From e63a9970f225bb433d818a8c75a09bfc807e84d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=9A=E4=BC=9F?= Date: Sat, 7 Feb 2026 23:13:24 +0800 Subject: [PATCH 01/52] fix: Add SessionInfoUpdate to SessionUpdate type in helpers (#61) * fix: Add SessionInfoUpdate to ToolCallContentVariant * fix: add miss import Signed-off-by: Chojan Shang --------- Signed-off-by: Chojan Shang Co-authored-by: Chojan Shang --- src/acp/helpers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/acp/helpers.py b/src/acp/helpers.py index 701cda7..8830c43 100644 --- a/src/acp/helpers.py +++ b/src/acp/helpers.py @@ -20,6 +20,7 @@ PlanEntryPriority, PlanEntryStatus, ResourceContentBlock, + SessionInfoUpdate, SessionNotification, TerminalToolCallContent, TextContentBlock, @@ -45,6 +46,7 @@ | UserMessageChunk | ToolCallStart | ToolCallProgress + | SessionInfoUpdate ) ToolCallContentVariant = ContentToolCallContent | FileEditToolCallContent | TerminalToolCallContent From b4f253c9506610798ed51f296d244cba8bc94c85 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sat, 7 Feb 2026 23:44:05 +0800 Subject: [PATCH 02/52] feat: bump agentclientprotocol to 0.10.8 (#63) * feat: bump agentclientprotocol to 0.10.8 Signed-off-by: Chojan Shang * fix: minor fix Signed-off-by: Chojan Shang --------- Signed-off-by: Chojan Shang --- schema/VERSION | 2 +- schema/schema.json | 523 ++++++++++++++++++++++++++++++----- scripts/gen_schema.py | 1 + src/acp/agent/connection.py | 5 +- src/acp/client/connection.py | 1 - src/acp/interfaces.py | 4 +- src/acp/meta.py | 2 +- src/acp/schema.py | 126 +++++++-- 8 files changed, 558 insertions(+), 106 deletions(-) diff --git a/schema/VERSION b/schema/VERSION index 801f529..3222b17 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.10.5 +refs/tags/v0.10.8 diff --git a/schema/schema.json b/schema/schema.json index 4f45ef0..ba61b43 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -67,7 +67,8 @@ "$ref": "#/$defs/SessionNotification" } ], - "description": "Handles session update notifications from the agent.\n\nThis is a notification endpoint (no response expected) that receives\nreal-time updates about session progress, including message chunks,\ntool calls, and execution plans.\n\nNote: Clients SHOULD continue accepting tool call updates even after\nsending a `session/cancel` notification, as the agent may send final\nupdates before responding with the cancelled stop reason.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)" + "description": "Handles session update notifications from the agent.\n\nThis is a notification endpoint (no response expected) that receives\nreal-time updates about session progress, including message chunks,\ntool calls, and execution plans.\n\nNote: Clients SHOULD continue accepting tool call updates even after\nsending a `session/cancel` notification, as the agent may send final\nupdates before responding with the cancelled stop reason.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "title": "SessionNotification" }, { "allOf": [ @@ -75,7 +76,8 @@ "$ref": "#/$defs/ExtNotification" } ], - "description": "Handles extension notifications from the agent.\n\nAllows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + "description": "Handles extension notifications from the agent.\n\nAllows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "title": "ExtNotification" } ], "description": "All possible notifications that an agent can send to a client.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly - use the notification methods on the [`Client`] trait instead.\n\nNotifications do not expect a response." @@ -110,7 +112,8 @@ "$ref": "#/$defs/WriteTextFileRequest" } ], - "description": "Writes content to a text file in the client's file system.\n\nOnly available if the client advertises the `fs.writeTextFile` capability.\nAllows the agent to create or modify files within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)" + "description": "Writes content to a text file in the client's file system.\n\nOnly available if the client advertises the `fs.writeTextFile` capability.\nAllows the agent to create or modify files within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", + "title": "WriteTextFileRequest" }, { "allOf": [ @@ -118,7 +121,8 @@ "$ref": "#/$defs/ReadTextFileRequest" } ], - "description": "Reads content from a text file in the client's file system.\n\nOnly available if the client advertises the `fs.readTextFile` capability.\nAllows the agent to access file contents within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)" + "description": "Reads content from a text file in the client's file system.\n\nOnly available if the client advertises the `fs.readTextFile` capability.\nAllows the agent to access file contents within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", + "title": "ReadTextFileRequest" }, { "allOf": [ @@ -126,7 +130,8 @@ "$ref": "#/$defs/RequestPermissionRequest" } ], - "description": "Requests permission from the user for a tool call operation.\n\nCalled by the agent when it needs user authorization before executing\na potentially sensitive operation. The client should present the options\nto the user and return their decision.\n\nIf the client cancels the prompt turn via `session/cancel`, it MUST\nrespond to this request with `RequestPermissionOutcome::Cancelled`.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)" + "description": "Requests permission from the user for a tool call operation.\n\nCalled by the agent when it needs user authorization before executing\na potentially sensitive operation. The client should present the options\nto the user and return their decision.\n\nIf the client cancels the prompt turn via `session/cancel`, it MUST\nrespond to this request with `RequestPermissionOutcome::Cancelled`.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", + "title": "RequestPermissionRequest" }, { "allOf": [ @@ -134,7 +139,8 @@ "$ref": "#/$defs/CreateTerminalRequest" } ], - "description": "Executes a command in a new terminal\n\nOnly available if the `terminal` Client capability is set to `true`.\n\nReturns a `TerminalId` that can be used with other terminal methods\nto get the current output, wait for exit, and kill the command.\n\nThe `TerminalId` can also be used to embed the terminal in a tool call\nby using the `ToolCallContent::Terminal` variant.\n\nThe Agent is responsible for releasing the terminal by using the `terminal/release`\nmethod.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)" + "description": "Executes a command in a new terminal\n\nOnly available if the `terminal` Client capability is set to `true`.\n\nReturns a `TerminalId` that can be used with other terminal methods\nto get the current output, wait for exit, and kill the command.\n\nThe `TerminalId` can also be used to embed the terminal in a tool call\nby using the `ToolCallContent::Terminal` variant.\n\nThe Agent is responsible for releasing the terminal by using the `terminal/release`\nmethod.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "CreateTerminalRequest" }, { "allOf": [ @@ -142,7 +148,8 @@ "$ref": "#/$defs/TerminalOutputRequest" } ], - "description": "Gets the terminal output and exit status\n\nReturns the current content in the terminal without waiting for the command to exit.\nIf the command has already exited, the exit status is included.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)" + "description": "Gets the terminal output and exit status\n\nReturns the current content in the terminal without waiting for the command to exit.\nIf the command has already exited, the exit status is included.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "TerminalOutputRequest" }, { "allOf": [ @@ -150,7 +157,8 @@ "$ref": "#/$defs/ReleaseTerminalRequest" } ], - "description": "Releases a terminal\n\nThe command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`\nto wait for the command to exit before releasing the terminal.\n\nAfter release, the `TerminalId` can no longer be used with other `terminal/*` methods,\nbut tool calls that already contain it, continue to display its output.\n\nThe `terminal/kill` method can be used to terminate the command without releasing\nthe terminal, allowing the Agent to call `terminal/output` and other methods.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)" + "description": "Releases a terminal\n\nThe command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`\nto wait for the command to exit before releasing the terminal.\n\nAfter release, the `TerminalId` can no longer be used with other `terminal/*` methods,\nbut tool calls that already contain it, continue to display its output.\n\nThe `terminal/kill` method can be used to terminate the command without releasing\nthe terminal, allowing the Agent to call `terminal/output` and other methods.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "ReleaseTerminalRequest" }, { "allOf": [ @@ -158,7 +166,8 @@ "$ref": "#/$defs/WaitForTerminalExitRequest" } ], - "description": "Waits for the terminal command to exit and return its exit status\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)" + "description": "Waits for the terminal command to exit and return its exit status\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "WaitForTerminalExitRequest" }, { "allOf": [ @@ -166,7 +175,8 @@ "$ref": "#/$defs/KillTerminalCommandRequest" } ], - "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)" + "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "KillTerminalCommandRequest" }, { "allOf": [ @@ -174,7 +184,8 @@ "$ref": "#/$defs/ExtRequest" } ], - "description": "Handles extension method requests from the agent.\n\nAllows the Agent to send an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + "description": "Handles extension method requests from the agent.\n\nAllows the Agent to send an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "title": "ExtMethodRequest" } ], "description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly - instead, use the methods on the [`Client`] trait.\n\nThis enum encompasses all method calls from agent to client." @@ -202,40 +213,100 @@ "result": { "anyOf": [ { - "$ref": "#/$defs/InitializeResponse" + "allOf": [ + { + "$ref": "#/$defs/InitializeResponse" + } + ], + "title": "InitializeResponse" }, { - "$ref": "#/$defs/AuthenticateResponse" + "allOf": [ + { + "$ref": "#/$defs/AuthenticateResponse" + } + ], + "title": "AuthenticateResponse" }, { - "$ref": "#/$defs/NewSessionResponse" + "allOf": [ + { + "$ref": "#/$defs/NewSessionResponse" + } + ], + "title": "NewSessionResponse" }, { - "$ref": "#/$defs/LoadSessionResponse" + "allOf": [ + { + "$ref": "#/$defs/LoadSessionResponse" + } + ], + "title": "LoadSessionResponse" }, { - "$ref": "#/$defs/ListSessionsResponse" + "allOf": [ + { + "$ref": "#/$defs/ListSessionsResponse" + } + ], + "title": "ListSessionsResponse" }, { - "$ref": "#/$defs/ForkSessionResponse" + "allOf": [ + { + "$ref": "#/$defs/ForkSessionResponse" + } + ], + "title": "ForkSessionResponse" }, { - "$ref": "#/$defs/ResumeSessionResponse" + "allOf": [ + { + "$ref": "#/$defs/ResumeSessionResponse" + } + ], + "title": "ResumeSessionResponse" }, { - "$ref": "#/$defs/SetSessionModeResponse" + "allOf": [ + { + "$ref": "#/$defs/SetSessionModeResponse" + } + ], + "title": "SetSessionModeResponse" }, { - "$ref": "#/$defs/SetSessionConfigOptionResponse" + "allOf": [ + { + "$ref": "#/$defs/SetSessionConfigOptionResponse" + } + ], + "title": "SetSessionConfigOptionResponse" }, { - "$ref": "#/$defs/PromptResponse" + "allOf": [ + { + "$ref": "#/$defs/PromptResponse" + } + ], + "title": "PromptResponse" }, { - "$ref": "#/$defs/SetSessionModelResponse" + "allOf": [ + { + "$ref": "#/$defs/SetSessionModelResponse" + } + ], + "title": "SetSessionModelResponse" }, { - "$ref": "#/$defs/ExtResponse" + "allOf": [ + { + "$ref": "#/$defs/ExtResponse" + } + ], + "title": "ExtMethodResponse" } ], "description": "All possible responses that an agent can send to a client.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `ClientRequest` variants." @@ -245,6 +316,7 @@ "id", "result" ], + "title": "Result", "type": "object" }, { @@ -260,6 +332,7 @@ "id", "error" ], + "title": "Error", "type": "object" } ], @@ -452,7 +525,8 @@ "$ref": "#/$defs/UnstructuredCommandInput" } ], - "description": "All text that was typed after the command name is provided as input." + "description": "All text that was typed after the command name is provided as input.", + "title": "unstructured" } ], "description": "The input specification for a command." @@ -611,7 +685,8 @@ "$ref": "#/$defs/CancelNotification" } ], - "description": "Cancels ongoing operations for a session.\n\nThis is a notification sent by the client to cancel an ongoing prompt turn.\n\nUpon receiving this notification, the Agent SHOULD:\n- Stop all language model requests as soon as possible\n- Abort all tool call invocations in progress\n- Send any pending `session/update` notifications\n- Respond to the original `session/prompt` request with `StopReason::Cancelled`\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)" + "description": "Cancels ongoing operations for a session.\n\nThis is a notification sent by the client to cancel an ongoing prompt turn.\n\nUpon receiving this notification, the Agent SHOULD:\n- Stop all language model requests as soon as possible\n- Abort all tool call invocations in progress\n- Send any pending `session/update` notifications\n- Respond to the original `session/prompt` request with `StopReason::Cancelled`\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "title": "CancelNotification" }, { "allOf": [ @@ -619,7 +694,8 @@ "$ref": "#/$defs/ExtNotification" } ], - "description": "Handles extension notifications from the client.\n\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + "description": "Handles extension notifications from the client.\n\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "title": "ExtNotification" } ], "description": "All possible notifications that a client can send to an agent.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly - use the notification methods on the [`Agent`] trait instead.\n\nNotifications do not expect a response." @@ -654,7 +730,8 @@ "$ref": "#/$defs/InitializeRequest" } ], - "description": "Establishes the connection with a client and negotiates protocol capabilities.\n\nThis method is called once at the beginning of the connection to:\n- Negotiate the protocol version to use\n- Exchange capability information between client and agent\n- Determine available authentication methods\n\nThe agent should respond with its supported protocol version and capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)" + "description": "Establishes the connection with a client and negotiates protocol capabilities.\n\nThis method is called once at the beginning of the connection to:\n- Negotiate the protocol version to use\n- Exchange capability information between client and agent\n- Determine available authentication methods\n\nThe agent should respond with its supported protocol version and capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "title": "InitializeRequest" }, { "allOf": [ @@ -662,7 +739,8 @@ "$ref": "#/$defs/AuthenticateRequest" } ], - "description": "Authenticates the client using the specified authentication method.\n\nCalled when the agent requires authentication before allowing session creation.\nThe client provides the authentication method ID that was advertised during initialization.\n\nAfter successful authentication, the client can proceed to create sessions with\n`new_session` without receiving an `auth_required` error.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)" + "description": "Authenticates the client using the specified authentication method.\n\nCalled when the agent requires authentication before allowing session creation.\nThe client provides the authentication method ID that was advertised during initialization.\n\nAfter successful authentication, the client can proceed to create sessions with\n`new_session` without receiving an `auth_required` error.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "title": "AuthenticateRequest" }, { "allOf": [ @@ -670,7 +748,8 @@ "$ref": "#/$defs/NewSessionRequest" } ], - "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)" + "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)", + "title": "NewSessionRequest" }, { "allOf": [ @@ -678,7 +757,8 @@ "$ref": "#/$defs/LoadSessionRequest" } ], - "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)" + "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "title": "LoadSessionRequest" }, { "allOf": [ @@ -686,7 +766,8 @@ "$ref": "#/$defs/ListSessionsRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `listSessions` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `listSessions` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", + "title": "ListSessionsRequest" }, { "allOf": [ @@ -694,7 +775,8 @@ "$ref": "#/$defs/ForkSessionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForks an existing session to create a new independent session.\n\nThis method is only available if the agent advertises the `session.fork` capability.\n\nThe agent should create a new session with the same conversation context as the\noriginal, allowing operations like generating summaries without affecting the\noriginal session's history." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForks an existing session to create a new independent session.\n\nThis method is only available if the agent advertises the `session.fork` capability.\n\nThe agent should create a new session with the same conversation context as the\noriginal, allowing operations like generating summaries without affecting the\noriginal session's history.", + "title": "ForkSessionRequest" }, { "allOf": [ @@ -702,7 +784,8 @@ "$ref": "#/$defs/ResumeSessionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `session.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`)." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `session.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", + "title": "ResumeSessionRequest" }, { "allOf": [ @@ -710,7 +793,8 @@ "$ref": "#/$defs/SetSessionModeRequest" } ], - "description": "Sets the current mode for a session.\n\nAllows switching between different agent modes (e.g., \"ask\", \"architect\", \"code\")\nthat affect system prompts, tool availability, and permission behaviors.\n\nThe mode must be one of the modes advertised in `availableModes` during session\ncreation or loading. Agents may also change modes autonomously and notify the\nclient via `current_mode_update` notifications.\n\nThis method can be called at any time during a session, whether the Agent is\nidle or actively generating a response.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Sets the current mode for a session.\n\nAllows switching between different agent modes (e.g., \"ask\", \"architect\", \"code\")\nthat affect system prompts, tool availability, and permission behaviors.\n\nThe mode must be one of the modes advertised in `availableModes` during session\ncreation or loading. Agents may also change modes autonomously and notify the\nclient via `current_mode_update` notifications.\n\nThis method can be called at any time during a session, whether the Agent is\nidle or actively generating a response.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "title": "SetSessionModeRequest" }, { "allOf": [ @@ -718,7 +802,8 @@ "$ref": "#/$defs/SetSessionConfigOptionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSets the current value for a session configuration option." + "description": "Sets the current value for a session configuration option.", + "title": "SetSessionConfigOptionRequest" }, { "allOf": [ @@ -726,7 +811,8 @@ "$ref": "#/$defs/PromptRequest" } ], - "description": "Processes a user prompt within a session.\n\nThis method handles the whole lifecycle of a prompt:\n- Receives user messages with optional context (files, images, etc.)\n- Processes the prompt using language models\n- Reports language model content and tool calls to the Clients\n- Requests permission to run tools\n- Executes any requested tool calls\n- Returns when the turn is complete with a stop reason\n\nSee protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)" + "description": "Processes a user prompt within a session.\n\nThis method handles the whole lifecycle of a prompt:\n- Receives user messages with optional context (files, images, etc.)\n- Processes the prompt using language models\n- Reports language model content and tool calls to the Clients\n- Requests permission to run tools\n- Executes any requested tool calls\n- Returns when the turn is complete with a stop reason\n\nSee protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)", + "title": "PromptRequest" }, { "allOf": [ @@ -734,7 +820,8 @@ "$ref": "#/$defs/SetSessionModelRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSelect a model for a given session." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSelect a model for a given session.", + "title": "SetSessionModelRequest" }, { "allOf": [ @@ -742,7 +829,8 @@ "$ref": "#/$defs/ExtRequest" } ], - "description": "Handles extension method requests from the client.\n\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + "description": "Handles extension method requests from the client.\n\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "title": "ExtMethodRequest" } ], "description": "All possible requests that a client can send to an agent.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly - instead, use the methods on the [`Agent`] trait.\n\nThis enum encompasses all method calls from client to agent." @@ -770,31 +858,76 @@ "result": { "anyOf": [ { - "$ref": "#/$defs/WriteTextFileResponse" + "allOf": [ + { + "$ref": "#/$defs/WriteTextFileResponse" + } + ], + "title": "WriteTextFileResponse" }, { - "$ref": "#/$defs/ReadTextFileResponse" + "allOf": [ + { + "$ref": "#/$defs/ReadTextFileResponse" + } + ], + "title": "ReadTextFileResponse" }, { - "$ref": "#/$defs/RequestPermissionResponse" + "allOf": [ + { + "$ref": "#/$defs/RequestPermissionResponse" + } + ], + "title": "RequestPermissionResponse" }, { - "$ref": "#/$defs/CreateTerminalResponse" + "allOf": [ + { + "$ref": "#/$defs/CreateTerminalResponse" + } + ], + "title": "CreateTerminalResponse" }, { - "$ref": "#/$defs/TerminalOutputResponse" + "allOf": [ + { + "$ref": "#/$defs/TerminalOutputResponse" + } + ], + "title": "TerminalOutputResponse" }, { - "$ref": "#/$defs/ReleaseTerminalResponse" + "allOf": [ + { + "$ref": "#/$defs/ReleaseTerminalResponse" + } + ], + "title": "ReleaseTerminalResponse" }, { - "$ref": "#/$defs/WaitForTerminalExitResponse" + "allOf": [ + { + "$ref": "#/$defs/WaitForTerminalExitResponse" + } + ], + "title": "WaitForTerminalExitResponse" }, { - "$ref": "#/$defs/KillTerminalCommandResponse" + "allOf": [ + { + "$ref": "#/$defs/KillTerminalCommandResponse" + } + ], + "title": "KillTerminalResponse" }, { - "$ref": "#/$defs/ExtResponse" + "allOf": [ + { + "$ref": "#/$defs/ExtResponse" + } + ], + "title": "ExtMethodResponse" } ], "description": "All possible responses that a client can send to an agent.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `AgentRequest` variants." @@ -804,6 +937,7 @@ "id", "result" ], + "title": "Result", "type": "object" }, { @@ -819,13 +953,14 @@ "id", "error" ], + "title": "Error", "type": "object" } ], "x-docs-ignore": true }, "ConfigOptionUpdate": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession configuration options have been updated.", + "description": "Session configuration options have been updated.", "properties": { "_meta": { "additionalProperties": true, @@ -996,6 +1131,25 @@ ], "type": "object" }, + "Cost": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCost information for a session.", + "properties": { + "amount": { + "description": "Total cumulative cost for session.", + "format": "double", + "type": "number" + }, + "currency": { + "description": "ISO 4217 currency code (e.g., \"USD\", \"EUR\").", + "type": "string" + } + }, + "required": [ + "amount", + "currency" + ], + "type": "object" + }, "CreateTerminalRequest": { "description": "Request to create a new terminal and execute a command.", "properties": { @@ -1172,10 +1326,20 @@ "EmbeddedResourceResource": { "anyOf": [ { - "$ref": "#/$defs/TextResourceContents" + "allOf": [ + { + "$ref": "#/$defs/TextResourceContents" + } + ], + "title": "TextResourceContents" }, { - "$ref": "#/$defs/BlobResourceContents" + "allOf": [ + { + "$ref": "#/$defs/BlobResourceContents" + } + ], + "title": "BlobResourceContents" } ], "description": "Resource content that can be embedded in a message." @@ -1237,53 +1401,62 @@ "const": -32700, "description": "**Parse error**: Invalid JSON was received by the server.\nAn error occurred on the server while parsing the JSON text.", "format": "int32", + "title": "Parse error", "type": "integer" }, { "const": -32600, "description": "**Invalid request**: The JSON sent is not a valid Request object.", "format": "int32", + "title": "Invalid request", "type": "integer" }, { "const": -32601, "description": "**Method not found**: The method does not exist or is not available.", "format": "int32", + "title": "Method not found", "type": "integer" }, { "const": -32602, "description": "**Invalid params**: Invalid method parameter(s).", "format": "int32", + "title": "Invalid params", "type": "integer" }, { "const": -32603, "description": "**Internal error**: Internal JSON-RPC error.\nReserved for implementation-defined server errors.", "format": "int32", + "title": "Internal error", "type": "integer" }, { "const": -32800, "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", "format": "int32", + "title": "Request cancelled", "type": "integer" }, { "const": -32000, "description": "**Authentication required**: Authentication is required before this operation can be performed.", "format": "int32", + "title": "Authentication required", "type": "integer" }, { "const": -32002, "description": "**Resource not found**: A given resource, such as a file, was not found.", "format": "int32", + "title": "Resource not found", "type": "integer" }, { "description": "Other undefined error code.", "format": "int32", + "title": "Other", "type": "integer" } ], @@ -1373,7 +1546,7 @@ ] }, "configOptions": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + "description": "Initial session configuration options if supported by the Agent.", "items": { "$ref": "#/$defs/SessionConfigOption" }, @@ -1802,7 +1975,7 @@ ] }, "configOptions": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + "description": "Initial session configuration options if supported by the Agent.", "items": { "$ref": "#/$defs/SessionConfigOption" }, @@ -1906,7 +2079,8 @@ "$ref": "#/$defs/McpServerStdio" } ], - "description": "Stdio transport configuration\n\nAll Agents MUST support this transport." + "description": "Stdio transport configuration\n\nAll Agents MUST support this transport.", + "title": "stdio" } ], "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)" @@ -2105,7 +2279,7 @@ ] }, "configOptions": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + "description": "Initial session configuration options if supported by the Agent.", "items": { "$ref": "#/$defs/SessionConfigOption" }, @@ -2405,6 +2579,17 @@ } ], "description": "Indicates why the agent stopped processing the turn." + }, + "usage": { + "anyOf": [ + { + "$ref": "#/$defs/Usage" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." } }, "required": [ @@ -2544,13 +2729,16 @@ "RequestId": { "anyOf": [ { + "title": "Null", "type": "null" }, { "format": "int64", + "title": "Number", "type": "integer" }, { + "title": "Str", "type": "string" } ], @@ -2776,7 +2964,7 @@ ] }, "configOptions": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + "description": "Initial session configuration options if supported by the Agent.", "items": { "$ref": "#/$defs/SessionConfigOption" }, @@ -2893,15 +3081,15 @@ "type": "object" }, "SessionConfigGroupId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a session configuration option value group.", + "description": "Unique identifier for a session configuration option value group.", "type": "string" }, "SessionConfigId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a session configuration option.", + "description": "Unique identifier for a session configuration option.", "type": "string" }, "SessionConfigOption": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA session configuration option selector and its current state.", + "description": "A session configuration option selector and its current state.", "discriminator": { "propertyName": "type" }, @@ -2934,6 +3122,17 @@ "null" ] }, + "category": { + "anyOf": [ + { + "$ref": "#/$defs/SessionConfigOptionCategory" + }, + { + "type": "null" + } + ], + "description": "Optional semantic category for this option (UX only)." + }, "description": { "description": "Optional description for the Client to display to the user.", "type": [ @@ -2960,8 +3159,33 @@ ], "type": "object" }, + "SessionConfigOptionCategory": { + "anyOf": [ + { + "const": "mode", + "description": "Session mode selector.", + "type": "string" + }, + { + "const": "model", + "description": "Model selector.", + "type": "string" + }, + { + "const": "thought_level", + "description": "Thought/reasoning level selector.", + "type": "string" + }, + { + "description": "Unknown / uncategorized selector.", + "title": "other", + "type": "string" + } + ], + "description": "Semantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec." + }, "SessionConfigSelect": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA single-value selector (dropdown) session configuration option payload.", + "description": "A single-value selector (dropdown) session configuration option payload.", "properties": { "currentValue": { "allOf": [ @@ -2987,7 +3211,7 @@ "type": "object" }, "SessionConfigSelectGroup": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA group of possible values for a session configuration option.", + "description": "A group of possible values for a session configuration option.", "properties": { "_meta": { "additionalProperties": true, @@ -3025,7 +3249,7 @@ "type": "object" }, "SessionConfigSelectOption": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA possible value for a session configuration option.", + "description": "A possible value for a session configuration option.", "properties": { "_meta": { "additionalProperties": true, @@ -3068,6 +3292,7 @@ "items": { "$ref": "#/$defs/SessionConfigSelectOption" }, + "title": "Ungrouped", "type": "array" }, { @@ -3075,13 +3300,14 @@ "items": { "$ref": "#/$defs/SessionConfigSelectGroup" }, + "title": "Grouped", "type": "array" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nPossible values for a session configuration option." + "description": "Possible values for a session configuration option." }, "SessionConfigValueId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a session configuration option value.", + "description": "Unique identifier for a session configuration option value.", "type": "string" }, "SessionForkCapabilities": { @@ -3494,7 +3720,7 @@ "$ref": "#/$defs/ConfigOptionUpdate" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession configuration options have been updated.", + "description": "Session configuration options have been updated.", "properties": { "sessionUpdate": { "const": "config_option_update", @@ -3523,11 +3749,29 @@ "sessionUpdate" ], "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/UsageUpdate" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.", + "properties": { + "sessionUpdate": { + "const": "usage_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" } ] }, "SetSessionConfigOptionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for setting a session configuration option.", + "description": "Request parameters for setting a session configuration option.", "properties": { "_meta": { "additionalProperties": true, @@ -3572,7 +3816,7 @@ "x-side": "agent" }, "SetSessionConfigOptionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `session/set_config_option` method.", + "description": "Response to `session/set_config_option` method.", "properties": { "_meta": { "additionalProperties": true, @@ -4254,6 +4498,103 @@ ], "type": "object" }, + "Usage": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage information for a prompt turn.", + "properties": { + "cachedReadTokens": { + "description": "Total cache read tokens.", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "cachedWriteTokens": { + "description": "Total cache write tokens.", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "inputTokens": { + "description": "Total input tokens across all turns.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "outputTokens": { + "description": "Total output tokens across all turns.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "thoughtTokens": { + "description": "Total thought/reasoning tokens", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "totalTokens": { + "description": "Sum of all token types across session.", + "format": "uint64", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "totalTokens", + "inputTokens", + "outputTokens" + ], + "type": "object" + }, + "UsageUpdate": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for a session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "cost": { + "anyOf": [ + { + "$ref": "#/$defs/Cost" + }, + { + "type": "null" + } + ], + "description": "Cumulative session cost (optional)." + }, + "size": { + "description": "Total context window size in tokens.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "used": { + "description": "Tokens currently in context.", + "format": "uint64", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "used", + "size" + ], + "type": "object" + }, "WaitForTerminalExitRequest": { "description": "Request to wait for a terminal command to exit.", "properties": { @@ -4377,13 +4718,28 @@ { "anyOf": [ { - "$ref": "#/$defs/AgentRequest" + "allOf": [ + { + "$ref": "#/$defs/AgentRequest" + } + ], + "title": "Request" }, { - "$ref": "#/$defs/AgentResponse" + "allOf": [ + { + "$ref": "#/$defs/AgentResponse" + } + ], + "title": "Response" }, { - "$ref": "#/$defs/AgentNotification" + "allOf": [ + { + "$ref": "#/$defs/AgentNotification" + } + ], + "title": "Notification" } ], "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", @@ -4398,18 +4754,34 @@ "required": [ "jsonrpc" ], + "title": "Agent", "type": "object" }, { "anyOf": [ { - "$ref": "#/$defs/ClientRequest" + "allOf": [ + { + "$ref": "#/$defs/ClientRequest" + } + ], + "title": "Request" }, { - "$ref": "#/$defs/ClientResponse" + "allOf": [ + { + "$ref": "#/$defs/ClientResponse" + } + ], + "title": "Response" }, { - "$ref": "#/$defs/ClientNotification" + "allOf": [ + { + "$ref": "#/$defs/ClientNotification" + } + ], + "title": "Notification" } ], "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", @@ -4424,6 +4796,7 @@ "required": [ "jsonrpc" ], + "title": "Client", "type": "object" }, { @@ -4434,10 +4807,12 @@ "$ref": "#/$defs/CancelRequestNotification" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)" + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "title": "CancelRequestNotification" } ], - "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response." + "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response.", + "title": "ProtocolLevel" } ], "title": "Agent Client Protocol" diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 36cbda7..74a8790 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -62,6 +62,7 @@ "SessionUpdate8": "CurrentModeUpdate", "SessionUpdate9": "ConfigOptionUpdate", "SessionUpdate10": "SessionInfoUpdate", + "SessionUpdate11": "UsageUpdate", "ToolCallContent1": "ContentToolCallContent", "ToolCallContent2": "FileEditToolCallContent", "ToolCallContent3": "TerminalToolCallContent", diff --git a/src/acp/agent/connection.py b/src/acp/agent/connection.py index 30b1092..b3b0351 100644 --- a/src/acp/agent/connection.py +++ b/src/acp/agent/connection.py @@ -33,6 +33,7 @@ ToolCallProgress, ToolCallStart, ToolCallUpdate, + UsageUpdate, UserMessageChunk, WaitForTerminalExitRequest, WaitForTerminalExitResponse, @@ -88,7 +89,8 @@ async def session_update( | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate - | SessionInfoUpdate, + | SessionInfoUpdate + | UsageUpdate, **kwargs: Any, ) -> None: await notify_model( @@ -216,5 +218,4 @@ async def __aexit__(self, exc_type, exc, tb) -> None: await self.close() def on_connect(self, conn: Agent) -> None: - # A dummy method to match the Client protocol pass diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index c71da96..ac0d34f 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -225,5 +225,4 @@ async def __aexit__(self, exc_type, exc, tb) -> None: await self.close() def on_connect(self, conn: Client) -> None: - # A dummy method to match the Agent protocol pass diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 5cc45ff..457dfe7 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -59,6 +59,7 @@ ToolCallProgress, ToolCallStart, ToolCallUpdate, + UsageUpdate, UserMessageChunk, WaitForTerminalExitRequest, WaitForTerminalExitResponse, @@ -89,7 +90,8 @@ async def session_update( | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate - | SessionInfoUpdate, + | SessionInfoUpdate + | UsageUpdate, **kwargs: Any, ) -> None: ... diff --git a/src/acp/meta.py b/src/acp/meta.py index 142f2f1..82aae7e 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,5 +1,5 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.10.5 +# Schema ref: refs/tags/v0.10.8 AGENT_METHODS = { "authenticate": "authenticate", "initialize": "initialize", diff --git a/src/acp/schema.py b/src/acp/schema.py index 314ccd9..e449e4a 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,5 +1,5 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.10.5 +# Schema ref: refs/tags/v0.10.8 from __future__ import annotations @@ -111,6 +111,13 @@ class BlobResourceContents(BaseModel): uri: str +class Cost(BaseModel): + # Total cumulative cost for session. + amount: Annotated[float, Field(description="Total cumulative cost for session.")] + # ISO 4217 currency code (e.g., "USD", "EUR"). + currency: Annotated[str, Field(description='ISO 4217 currency code (e.g., "USD", "EUR").')] + + class CreateTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -900,6 +907,72 @@ class UnstructuredCommandInput(BaseModel): ] +class Usage(BaseModel): + # Total cache read tokens. + cached_read_tokens: Annotated[ + Optional[int], + Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), + ] = None + # Total cache write tokens. + cached_write_tokens: Annotated[ + Optional[int], + Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), + ] = None + # Total input tokens across all turns. + input_tokens: Annotated[ + int, + Field( + alias="inputTokens", + description="Total input tokens across all turns.", + ge=0, + ), + ] + # Total output tokens across all turns. + output_tokens: Annotated[ + int, + Field( + alias="outputTokens", + description="Total output tokens across all turns.", + ge=0, + ), + ] + # Total thought/reasoning tokens + thought_tokens: Annotated[ + Optional[int], + Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), + ] = None + # Sum of all token types across session. + total_tokens: Annotated[ + int, + Field( + alias="totalTokens", + description="Sum of all token types across session.", + ge=0, + ), + ] + + +class _UsageUpdate(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Cumulative session cost (optional). + cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None + # Total context window size in tokens. + size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] + # Tokens currently in context. + used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] + + class WaitForTerminalExitRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1423,6 +1496,17 @@ class PromptResponse(BaseModel): description="Indicates why the agent stopped processing the turn.", ), ] + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Token usage for this turn (optional). + usage: Annotated[ + Optional[Usage], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." + ), + ] = None class ReadTextFileRequest(BaseModel): @@ -1666,6 +1750,10 @@ class CurrentModeUpdate(_CurrentModeUpdate): session_update: Annotated[Literal["current_mode_update"], Field(alias="sessionUpdate")] +class UsageUpdate(_UsageUpdate): + session_update: Annotated[Literal["usage_update"], Field(alias="sessionUpdate")] + + class TextContent(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2220,6 +2308,11 @@ class SessionConfigOptionSelect(SessionConfigSelect): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # Optional semantic category for this option (UX only). + category: Annotated[ + Optional[str], + Field(description="Optional semantic category for this option (UX only)."), + ] = None # Optional description for the Client to display to the user. description: Annotated[ Optional[str], @@ -2233,15 +2326,11 @@ class SessionConfigOptionSelect(SessionConfigSelect): class SessionConfigOption(RootModel[SessionConfigOptionSelect]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # A session configuration option selector and its current state. root: Annotated[ SessionConfigOptionSelect, Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA session configuration option selector and its current state.", + description="A session configuration option selector and its current state.", discriminator="type", ), ] @@ -2350,16 +2439,12 @@ class ForkSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Initial session configuration options if supported by the Agent. config_options: Annotated[ Optional[List[SessionConfigOption]], Field( alias="configOptions", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + description="Initial session configuration options if supported by the Agent.", ), ] = None # **UNSTABLE** @@ -2405,16 +2490,12 @@ class LoadSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Initial session configuration options if supported by the Agent. config_options: Annotated[ Optional[List[SessionConfigOption]], Field( alias="configOptions", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + description="Initial session configuration options if supported by the Agent.", ), ] = None # **UNSTABLE** @@ -2452,16 +2533,12 @@ class NewSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Initial session configuration options if supported by the Agent. config_options: Annotated[ Optional[List[SessionConfigOption]], Field( alias="configOptions", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + description="Initial session configuration options if supported by the Agent.", ), ] = None # **UNSTABLE** @@ -2539,16 +2616,12 @@ class ResumeSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Initial session configuration options if supported by the Agent. config_options: Annotated[ Optional[List[SessionConfigOption]], Field( alias="configOptions", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial session configuration options if supported by the Agent.", + description="Initial session configuration options if supported by the Agent.", ), ] = None # **UNSTABLE** @@ -2757,6 +2830,7 @@ class SessionNotification(BaseModel): CurrentModeUpdate, ConfigOptionUpdate, SessionInfoUpdate, + UsageUpdate, ], Field(description="The actual update content.", discriminator="session_update"), ] From e21d8d0acd16e31992361b1d79c3fdd06cbdd9f3 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sun, 8 Feb 2026 00:29:47 +0800 Subject: [PATCH 03/52] fix: allow omitting mcpServers in session requests (#58) * fix: allow omitting mcpServers in session requests * fix: warn on positional load_session session_id * Revert "fix: warn on positional load_session session_id" This reverts commit 1f21da8d68fa73bc49a0c2c4bc78d3cc60063907. * Revert "fix: allow omitting mcpServers in session requests" This reverts commit 73499a8f2ef7a0f32a0cf89e9aa6f973d66b976c. * fix: default mcpServers to empty list --- scripts/gen_signature.py | 30 +++++++-- src/acp/client/connection.py | 16 +++-- src/acp/interfaces.py | 8 ++- tests/real_user/test_mcp_servers_optional.py | 68 ++++++++++++++++++++ 4 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 tests/real_user/test_mcp_servers_optional.py diff --git a/scripts/gen_signature.py b/scripts/gen_signature.py index b3a7add..b435e2c 100644 --- a/scripts/gen_signature.py +++ b/scripts/gen_signature.py @@ -9,6 +9,11 @@ from acp import schema +SIGNATURE_OPTIONAL_FIELDS: set[tuple[str, str]] = { + ("LoadSessionRequest", "mcp_servers"), + ("NewSessionRequest", "mcp_servers"), +} + class NodeTransformer(ast.NodeTransformer): def __init__(self) -> None: @@ -16,6 +21,7 @@ def __init__(self) -> None: self._schema_import_node: ast.ImportFrom | None = None self._should_rewrite = False self._literals = {name: value for name, value in schema.__dict__.items() if t.get_origin(value) is t.Literal} + self._current_model_name: str | None = None def _add_typing_import(self, name: str) -> None: if not self._type_import_node: @@ -71,9 +77,13 @@ def visit_func(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> ast.AST: self._should_rewrite = True model_name = t.cast(ast.Name, decorator.args[0]).id model = t.cast(type[schema.BaseModel], getattr(schema, model_name)) - param_defaults = [ - self._to_param_def(name, field) for name, field in model.model_fields.items() if name != "field_meta" - ] + self._current_model_name = model_name + try: + param_defaults = [ + self._to_param_def(name, field) for name, field in model.model_fields.items() if name != "field_meta" + ] + finally: + self._current_model_name = None param_defaults.sort(key=lambda x: x[1] is not None) node.args.args[1:] = [param for param, _ in param_defaults] node.args.defaults = [default for _, default in param_defaults if default is not None] @@ -84,12 +94,18 @@ def visit_func(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> ast.AST: def _to_param_def(self, name: str, field: FieldInfo) -> tuple[ast.arg, ast.expr | None]: arg = ast.arg(arg=name) ann = field.annotation - if field.default is PydanticUndefined: - default = None - elif isinstance(field.default, dict | BaseModel): + override_optional = (self._current_model_name, name) in SIGNATURE_OPTIONAL_FIELDS + if override_optional: + if ann is not None: + ann = ann | None default = ast.Constant(None) else: - default = ast.Constant(value=field.default) + if field.default is PydanticUndefined: + default = None + elif isinstance(field.default, dict | BaseModel): + default = ast.Constant(None) + else: + default = ast.Constant(value=field.default) if ann is not None: arg.annotation = self._format_annotation(ann) return arg, default diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index ac0d34f..9831d7e 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -93,23 +93,31 @@ async def initialize( @param_model(NewSessionRequest) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any ) -> NewSessionResponse: + resolved_mcp_servers = mcp_servers or [] return await request_model( self._conn, AGENT_METHODS["session_new"], - NewSessionRequest(cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None), + NewSessionRequest(cwd=cwd, mcp_servers=resolved_mcp_servers, field_meta=kwargs or None), NewSessionResponse, ) @param_model(LoadSessionRequest) async def load_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], session_id: str, **kwargs: Any + self, + cwd: str, + session_id: str, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> LoadSessionResponse: + resolved_mcp_servers = mcp_servers or [] return await request_model_from_dict( self._conn, AGENT_METHODS["session_load"], - LoadSessionRequest(cwd=cwd, mcp_servers=mcp_servers, session_id=session_id, field_meta=kwargs or None), + LoadSessionRequest( + cwd=cwd, mcp_servers=resolved_mcp_servers, session_id=session_id, field_meta=kwargs or None + ), LoadSessionResponse, ) diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 457dfe7..55c00f3 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -154,12 +154,16 @@ async def initialize( @param_model(NewSessionRequest) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any ) -> NewSessionResponse: ... @param_model(LoadSessionRequest) async def load_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], session_id: str, **kwargs: Any + self, + cwd: str, + session_id: str, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> LoadSessionResponse | None: ... @param_model(ListSessionsRequest) diff --git a/tests/real_user/test_mcp_servers_optional.py b/tests/real_user/test_mcp_servers_optional.py new file mode 100644 index 0000000..96aae75 --- /dev/null +++ b/tests/real_user/test_mcp_servers_optional.py @@ -0,0 +1,68 @@ +import asyncio +from typing import Any + +import pytest + +from acp import InitializeResponse, LoadSessionResponse, NewSessionResponse +from acp.core import AgentSideConnection, ClientSideConnection +from acp.schema import HttpMcpServer, McpServerStdio, SseMcpServer +from tests.conftest import TestAgent, TestClient + + +class McpOptionalAgent(TestAgent): + def __init__(self) -> None: + super().__init__() + self.seen_new_session: tuple[str, Any] | None = None + self.seen_load_session: tuple[str, str, Any] | None = None + + async def new_session( + self, + cwd: str, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> NewSessionResponse: + resolved_mcp_servers = mcp_servers or [] + self.seen_new_session = (cwd, resolved_mcp_servers) + return await super().new_session(cwd=cwd, mcp_servers=resolved_mcp_servers, **kwargs) + + async def load_session( + self, + cwd: str, + session_id: str, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> LoadSessionResponse | None: + resolved_mcp_servers = mcp_servers or [] + self.seen_load_session = (cwd, session_id, resolved_mcp_servers) + return await super().load_session(cwd=cwd, session_id=session_id, mcp_servers=resolved_mcp_servers, **kwargs) + + +@pytest.mark.asyncio +async def test_session_requests_default_empty_mcp_servers(server) -> None: + client = TestClient() + captured_agent: list[McpOptionalAgent] = [] + + agent_conn = ClientSideConnection(client, server._client_writer, server._client_reader) # type: ignore[arg-type] + _agent_side = AgentSideConnection( + lambda _conn: captured_agent.append(McpOptionalAgent()) or captured_agent[-1], + server._server_writer, + server._server_reader, + listening=True, + ) + + init = await asyncio.wait_for(agent_conn.initialize(protocol_version=1), timeout=1.0) + assert isinstance(init, InitializeResponse) + + new_session = await asyncio.wait_for(agent_conn.new_session(cwd="/workspace"), timeout=1.0) + assert isinstance(new_session, NewSessionResponse) + + load_session = await asyncio.wait_for( + agent_conn.load_session(cwd="/workspace", session_id=new_session.session_id), + timeout=1.0, + ) + assert isinstance(load_session, LoadSessionResponse) + + assert captured_agent, "Agent was not constructed" + [agent] = captured_agent + assert agent.seen_new_session == ("/workspace", []) + assert agent.seen_load_session == ("/workspace", new_session.session_id, []) From a1d2ae8e9070763f575dc9a628ea76ecf49cef2e Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sun, 8 Feb 2026 01:07:01 +0800 Subject: [PATCH 04/52] chore: prepare 0.8.0 release (#64) * chore: prepare 0.8.0 release * chore: bump to 0.8.0 --- .github/workflows/on-release-main.yml | 40 +++++++++++++++++++-------- docs/migration-guide-0.8.md | 37 +++++++++++++++++++++++++ mkdocs.yml | 1 + pyproject.toml | 2 +- uv.lock | 2 +- 5 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 docs/migration-guide-0.8.md diff --git a/.github/workflows/on-release-main.yml b/.github/workflows/on-release-main.yml index 5e1bba1..620606a 100644 --- a/.github/workflows/on-release-main.yml +++ b/.github/workflows/on-release-main.yml @@ -4,6 +4,15 @@ on: release: types: [published] +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + jobs: set-version: runs-on: ubuntu-24.04 @@ -51,7 +60,7 @@ jobs: env: UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }} - deploy-docs: + build-docs: needs: publish runs-on: ubuntu-latest steps: @@ -61,14 +70,21 @@ jobs: - name: Set up the environment uses: ./.github/actions/setup-python-env - - name: Deploy documentation - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GIT_AUTHOR_NAME: acp-bot - GIT_AUTHOR_EMAIL: noreply@github.com - GIT_COMMITTER_NAME: acp-bot - GIT_COMMITTER_EMAIL: noreply@github.com - run: | - git config user.name "$GIT_AUTHOR_NAME" - git config user.email "$GIT_AUTHOR_EMAIL" - uv run mkdocs gh-deploy --force --remote-branch gh-pages --remote-name origin + - name: Build site + run: uv run mkdocs build -f mkdocs.yml --clean + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 + with: + path: site + + deploy-docs: + needs: build-docs + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 diff --git a/docs/migration-guide-0.8.md b/docs/migration-guide-0.8.md new file mode 100644 index 0000000..efb1d61 --- /dev/null +++ b/docs/migration-guide-0.8.md @@ -0,0 +1,37 @@ +# Migrating to ACP Python SDK 0.8 + +ACP 0.8 keeps the 0.7 public surface but aligns the SDK with the latest ACP schema and tightens a few runtime behaviors. Most teams only need to review the updated schema and terminal helpers. This guide calls out the changes that can affect downstream agents, clients, and tests. + +## 1. ACP schema bumped to 0.10.8 + +- Regenerate any internal copies of ACP schema-derived artifacts against 0.10.8. +- If you vendor schema types, run `make gen-all` or your equivalent pipeline. +- Helper types now include `SessionInfoUpdate` in the `SessionUpdate` union, so downstream code that exhaustively matches update variants should include it. + +## 2. `TerminalHandle` removal + +`TerminalHandle` is no longer part of the public API. If you referenced it directly, switch to the request/response models and terminal IDs returned by `CreateTerminalRequest`/`CreateTerminalResponse`. + +Typical adjustment: + +```python +# Before (0.7.x) +handle = await conn.create_terminal(...) +await conn.terminal_output(session_id=..., terminal_id=handle.id) + +# After (0.8.x) +resp = await conn.create_terminal(...) +await conn.terminal_output(session_id=..., terminal_id=resp.terminal_id) +``` + +## 3. Larger default stdio buffer limits + +The default stdio reader limit is now 50MB to support multimodal payloads. If you run in memory-constrained environments, explicitly set `stdio_buffer_limit_bytes` when calling `run_agent`. + +```python +await run_agent(agent, stdio_buffer_limit_bytes=2 * 1024 * 1024) +``` + +## 4. Documentation and quickstart updates + +Docs and settings examples have been refreshed for ACP 0.10.8. If you maintain internal onboarding material, sync it with the latest docs in `docs/`. diff --git a/mkdocs.yml b/mkdocs.yml index e74cd49..6a7a76e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -14,6 +14,7 @@ nav: - Experimental Contrib: contrib.md - Releasing: releasing.md - 0.7 Migration Guide: migration-guide-0.7.md + - 0.8 Migration Guide: migration-guide-0.8.md plugins: - search - mkdocstrings: diff --git a/pyproject.toml b/pyproject.toml index c31938f..fc62423 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.7.1" +version = "0.8.0" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 3bc3ea2..ad9247d 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.7.1" +version = "0.8.0" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 21573581afa74c9903afe68879f5c96c1320be69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Feb 2026 01:47:11 +0800 Subject: [PATCH 05/52] chore(deps): bump the uv group across 1 directory with 4 updates (#65) Bumps the uv group with 4 updates in the / directory: [filelock](https://github.com/tox-dev/py-filelock), [protobuf](https://github.com/protocolbuffers/protobuf), [urllib3](https://github.com/urllib3/urllib3) and [virtualenv](https://github.com/pypa/virtualenv). Updates `filelock` from 3.20.0 to 3.20.3 - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.20.0...3.20.3) Updates `protobuf` from 6.33.0 to 6.33.5 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Commits](https://github.com/protocolbuffers/protobuf/commits) Updates `urllib3` from 2.5.0 to 2.6.3 - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.3) Updates `virtualenv` from 20.35.4 to 20.36.1 - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.35.4...20.36.1) --- updated-dependencies: - dependency-name: filelock dependency-version: 3.20.3 dependency-type: indirect dependency-group: uv - dependency-name: protobuf dependency-version: 6.33.5 dependency-type: indirect dependency-group: uv - dependency-name: urllib3 dependency-version: 2.6.3 dependency-type: indirect dependency-group: uv - dependency-name: virtualenv dependency-version: 20.36.1 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/uv.lock b/uv.lock index ad9247d..dafcb0f 100644 --- a/uv.lock +++ b/uv.lock @@ -361,11 +361,11 @@ wheels = [ [[package]] name = "filelock" -version = "3.20.0" +version = "3.20.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/65/ce7f1b70157833bf3cb851b556a37d4547ceafc158aa9b34b36782f23696/filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1", size = 19485, upload-time = "2026-01-09T17:55:05.421Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, + { url = "https://files.pythonhosted.org/packages/b5/36/7fb70f04bf00bc646cd5bb45aa9eddb15e19437a28b8fb2b4a5249fac770/filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1", size = 16701, upload-time = "2026-01-09T17:55:04.334Z" }, ] [[package]] @@ -928,17 +928,17 @@ wheels = [ [[package]] name = "protobuf" -version = "6.33.0" +version = "6.33.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/19/ff/64a6c8f420818bb873713988ca5492cba3a7946be57e027ac63495157d97/protobuf-6.33.0.tar.gz", hash = "sha256:140303d5c8d2037730c548f8c7b93b20bb1dc301be280c378b82b8894589c954", size = 443463, upload-time = "2025-10-15T20:39:52.159Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/25/7c72c307aafc96fa87062aa6291d9f7c94836e43214d43722e86037aac02/protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c", size = 444465, upload-time = "2026-01-29T21:51:33.494Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/ee/52b3fa8feb6db4a833dfea4943e175ce645144532e8a90f72571ad85df4e/protobuf-6.33.0-cp310-abi3-win32.whl", hash = "sha256:d6101ded078042a8f17959eccd9236fb7a9ca20d3b0098bbcb91533a5680d035", size = 425593, upload-time = "2025-10-15T20:39:40.29Z" }, - { url = "https://files.pythonhosted.org/packages/7b/c6/7a465f1825872c55e0341ff4a80198743f73b69ce5d43ab18043699d1d81/protobuf-6.33.0-cp310-abi3-win_amd64.whl", hash = "sha256:9a031d10f703f03768f2743a1c403af050b6ae1f3480e9c140f39c45f81b13ee", size = 436882, upload-time = "2025-10-15T20:39:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/e1/a9/b6eee662a6951b9c3640e8e452ab3e09f117d99fc10baa32d1581a0d4099/protobuf-6.33.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:905b07a65f1a4b72412314082c7dbfae91a9e8b68a0cc1577515f8df58ecf455", size = 427521, upload-time = "2025-10-15T20:39:43.803Z" }, - { url = "https://files.pythonhosted.org/packages/10/35/16d31e0f92c6d2f0e77c2a3ba93185130ea13053dd16200a57434c882f2b/protobuf-6.33.0-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e0697ece353e6239b90ee43a9231318302ad8353c70e6e45499fa52396debf90", size = 324445, upload-time = "2025-10-15T20:39:44.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/eb/2a981a13e35cda8b75b5585aaffae2eb904f8f351bdd3870769692acbd8a/protobuf-6.33.0-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:e0a1715e4f27355afd9570f3ea369735afc853a6c3951a6afe1f80d8569ad298", size = 339159, upload-time = "2025-10-15T20:39:46.186Z" }, - { url = "https://files.pythonhosted.org/packages/21/51/0b1cbad62074439b867b4e04cc09b93f6699d78fd191bed2bbb44562e077/protobuf-6.33.0-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:35be49fd3f4fefa4e6e2aacc35e8b837d6703c37a2168a55ac21e9b1bc7559ef", size = 323172, upload-time = "2025-10-15T20:39:47.465Z" }, - { url = "https://files.pythonhosted.org/packages/07/d1/0a28c21707807c6aacd5dc9c3704b2aa1effbf37adebd8caeaf68b17a636/protobuf-6.33.0-py3-none-any.whl", hash = "sha256:25c9e1963c6734448ea2d308cfa610e692b801304ba0908d7bfa564ac5132995", size = 170477, upload-time = "2025-10-15T20:39:51.311Z" }, + { url = "https://files.pythonhosted.org/packages/b1/79/af92d0a8369732b027e6d6084251dd8e782c685c72da161bd4a2e00fbabb/protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b", size = 425769, upload-time = "2026-01-29T21:51:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/55/75/bb9bc917d10e9ee13dee8607eb9ab963b7cf8be607c46e7862c748aa2af7/protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c", size = 437118, upload-time = "2026-01-29T21:51:24.022Z" }, + { url = "https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5", size = 427766, upload-time = "2026-01-29T21:51:25.413Z" }, + { url = "https://files.pythonhosted.org/packages/4e/b1/c79468184310de09d75095ed1314b839eb2f72df71097db9d1404a1b2717/protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190", size = 324638, upload-time = "2026-01-29T21:51:26.423Z" }, + { url = "https://files.pythonhosted.org/packages/c5/f5/65d838092fd01c44d16037953fd4c2cc851e783de9b8f02b27ec4ffd906f/protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd", size = 339411, upload-time = "2026-01-29T21:51:27.446Z" }, + { url = "https://files.pythonhosted.org/packages/9b/53/a9443aa3ca9ba8724fdfa02dd1887c1bcd8e89556b715cfbacca6b63dbec/protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0", size = 323465, upload-time = "2026-01-29T21:51:28.925Z" }, + { url = "https://files.pythonhosted.org/packages/57/bf/2086963c69bdac3d7cff1cc7ff79b8ce5ea0bec6797a017e1be338a46248/protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02", size = 170687, upload-time = "2026-01-29T21:51:32.557Z" }, ] [[package]] @@ -1464,11 +1464,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.5.0" +version = "2.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, ] [[package]] @@ -1499,7 +1499,7 @@ wheels = [ [[package]] name = "virtualenv" -version = "20.35.4" +version = "20.36.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, @@ -1507,9 +1507,9 @@ dependencies = [ { name = "platformdirs" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/28/e6f1a6f655d620846bd9df527390ecc26b3805a0c5989048c210e22c5ca9/virtualenv-20.35.4.tar.gz", hash = "sha256:643d3914d73d3eeb0c552cbb12d7e82adf0e504dbf86a3182f8771a153a1971c", size = 6028799, upload-time = "2025-10-29T06:57:40.511Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba", size = 6032239, upload-time = "2026-01-09T18:21:01.296Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/79/0c/c05523fa3181fdf0c9c52a6ba91a23fbf3246cc095f26f6516f9c60e6771/virtualenv-20.35.4-py3-none-any.whl", hash = "sha256:c21c9cede36c9753eeade68ba7d523529f228a403463376cf821eaae2b650f1b", size = 6005095, upload-time = "2025-10-29T06:57:37.598Z" }, + { url = "https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f", size = 6008258, upload-time = "2026-01-09T18:20:59.425Z" }, ] [[package]] From e2f96ae277e666fc947859bcd03391231b5ab6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Drouin?= Date: Fri, 13 Feb 2026 12:11:51 +0100 Subject: [PATCH 06/52] feat: add protocol method for `session/set_config_option` (#69) --- src/acp/__init__.py | 4 ++++ src/acp/agent/router.py | 8 ++++++++ src/acp/client/connection.py | 15 +++++++++++++++ src/acp/interfaces.py | 7 +++++++ tests/conftest.py | 6 ++++++ tests/test_rpc.py | 10 ++++++++++ 6 files changed, 50 insertions(+) diff --git a/src/acp/__init__.py b/src/acp/__init__.py index 2d09a7d..7cbde3c 100644 --- a/src/acp/__init__.py +++ b/src/acp/__init__.py @@ -60,6 +60,8 @@ RequestPermissionRequest, RequestPermissionResponse, SessionNotification, + SetSessionConfigOptionRequest, + SetSessionConfigOptionResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -115,6 +117,8 @@ "SetSessionModeResponse", "SetSessionModelRequest", "SetSessionModelResponse", + "SetSessionConfigOptionRequest", + "SetSessionConfigOptionResponse", # terminal types "CreateTerminalRequest", "CreateTerminalResponse", diff --git a/src/acp/agent/router.py b/src/acp/agent/router.py index 8221ede..8477716 100644 --- a/src/acp/agent/router.py +++ b/src/acp/agent/router.py @@ -16,6 +16,7 @@ NewSessionRequest, PromptRequest, ResumeSessionRequest, + SetSessionConfigOptionRequest, SetSessionModelRequest, SetSessionModeRequest, ) @@ -53,6 +54,13 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes adapt_result=normalize_result, unstable=True, ) + router.route_request( + AGENT_METHODS["session_set_config_option"], + SetSessionConfigOptionRequest, + agent, + "set_config_option", + adapt_result=normalize_result, + ) router.route_request( AGENT_METHODS["authenticate"], AuthenticateRequest, diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 9831d7e..7d0396e 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -33,6 +33,8 @@ ResourceContentBlock, ResumeSessionRequest, ResumeSessionResponse, + SetSessionConfigOptionRequest, + SetSessionConfigOptionResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -150,6 +152,19 @@ async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) SetSessionModelResponse, ) + @param_model(SetSessionConfigOptionRequest) + async def set_config_option( + self, config_id: str, session_id: str, value: str, **kwargs: Any + ) -> SetSessionConfigOptionResponse: + return await request_model_from_dict( + self._conn, + AGENT_METHODS["session_set_config_option"], + SetSessionConfigOptionRequest( + config_id=config_id, session_id=session_id, value=value, field_meta=kwargs or None + ), + SetSessionConfigOptionResponse, + ) + @param_model(AuthenticateRequest) async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateResponse: return await request_model_from_dict( diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 55c00f3..1fd572f 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -48,6 +48,8 @@ ResumeSessionResponse, SessionInfoUpdate, SessionNotification, + SetSessionConfigOptionRequest, + SetSessionConfigOptionResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -179,6 +181,11 @@ async def set_session_model( self, model_id: str, session_id: str, **kwargs: Any ) -> SetSessionModelResponse | None: ... + @param_model(SetSessionConfigOptionRequest) + async def set_config_option( + self, config_id: str, session_id: str, value: str, **kwargs: Any + ) -> SetSessionConfigOptionResponse | None: ... + @param_model(AuthenticateRequest) async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateResponse | None: ... diff --git a/tests/conftest.py b/tests/conftest.py index 6cce0b1..a2a373d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,6 +20,7 @@ RequestError, RequestPermissionResponse, SessionNotification, + SetSessionConfigOptionResponse, SetSessionModeResponse, TerminalOutputResponse, WaitForTerminalExitResponse, @@ -276,6 +277,11 @@ async def cancel(self, session_id: str, **kwargs: Any) -> None: async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: return SetSessionModeResponse() + async def set_config_option( + self, config_id: str, session_id: str, value: str, **kwargs: Any + ) -> SetSessionConfigOptionResponse | None: + return SetSessionConfigOptionResponse(config_options=[]) + async def ext_method(self, method: str, params: dict) -> dict: self.ext_calls.append((method, params)) if method == "example.com/echo": diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 9b48a7c..7b4c37e 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -18,6 +18,7 @@ PromptResponse, RequestPermissionRequest, RequestPermissionResponse, + SetSessionConfigOptionResponse, SetSessionModeResponse, WriteTextFileResponse, spawn_agent_process, @@ -253,6 +254,15 @@ async def test_set_session_mode_and_extensions(connect, agent, client): assert client.ext_calls and client.ext_calls[-1] == ("example.com/ping", {"k": 3}) +@pytest.mark.asyncio +async def test_set_config_option(connect, agent, client): + _, agent_conn = connect() + + resp = await agent_conn.set_config_option(session_id="sess", config_id="theme", value="dark") + assert isinstance(resp, SetSessionConfigOptionResponse) + assert resp.config_options == [] + + @pytest.mark.asyncio async def test_ignore_invalid_messages(connect, server): connect(connect_agent=True, connect_client=False) From 0133bc49aaad9990e242b9b0f583ea9f492552a6 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Fri, 13 Feb 2026 15:16:22 +0000 Subject: [PATCH 07/52] chore: bump 0.8.1 Signed-off-by: Chojan Shang --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fc62423..63e17fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.8.0" +version = "0.8.1" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index dafcb0f..71fe2aa 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.8.0" +version = "0.8.1" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 0ede8352760efd4d5cafed404611001dbef8ac1c Mon Sep 17 00:00:00 2001 From: nikkie Date: Sat, 7 Mar 2026 18:49:15 +0900 Subject: [PATCH 08/52] fix(docs): correct nested agent server entry in Quickstart uv example (#77) --- docs/quickstart.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/quickstart.md b/docs/quickstart.md index 401b7d5..08a6602 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -65,6 +65,7 @@ Or, if using `uv`: ```json { "agent_servers": { + "Echo Agent (Python)": { "type": "custom", "command": "uv", "args": [ @@ -72,6 +73,7 @@ Or, if using `uv`: "/abs/path/to/agentclientprotocol/python-sdk/examples/echo_agent.py" ], } + } } ``` From 69c184c86a1ec7e77a718fcbbfdc7db7eb5351e6 Mon Sep 17 00:00:00 2001 From: nikkie Date: Sat, 7 Mar 2026 18:51:30 +0900 Subject: [PATCH 09/52] Add inline script metadata so users can run it directly via just `uv run` (#76) --- examples/echo_agent.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/echo_agent.py b/examples/echo_agent.py index 4823cc3..0f376fb 100644 --- a/examples/echo_agent.py +++ b/examples/echo_agent.py @@ -1,3 +1,9 @@ +# /// script +# requires-python = ">=3.10,<3.15" +# dependencies = [ +# "agent-client-protocol", +# ] +# /// import asyncio from typing import Any from uuid import uuid4 From 897182bec1a261f008d4015881d95eb0905a4862 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 10:31:00 +0800 Subject: [PATCH 10/52] chore(deps): bump black in the uv group across 1 directory (#79) Bumps the uv group with 1 update in the / directory: [black](https://github.com/psf/black). Updates `black` from 25.9.0 to 26.3.1 - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/25.9.0...26.3.1) --- updated-dependencies: - dependency-name: black dependency-version: 26.3.1 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 95 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 28 deletions(-) diff --git a/uv.lock b/uv.lock index 71fe2aa..938a030 100644 --- a/uv.lock +++ b/uv.lock @@ -108,7 +108,7 @@ wheels = [ [[package]] name = "black" -version = "25.9.0" +version = "26.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -120,25 +120,34 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4b/43/20b5c90612d7bdb2bdbcceeb53d588acca3bb8f0e4c5d5c751a2c8fdd55a/black-25.9.0.tar.gz", hash = "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", size = 648393, upload-time = "2025-09-19T00:27:37.758Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/40/dbe31fc56b218a858c8fc6f5d8d3ba61c1fa7e989d43d4a4574b8b992840/black-25.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce41ed2614b706fd55fd0b4a6909d06b5bab344ffbfadc6ef34ae50adba3d4f7", size = 1715605, upload-time = "2025-09-19T00:36:13.483Z" }, - { url = "https://files.pythonhosted.org/packages/92/b2/f46800621200eab6479b1f4c0e3ede5b4c06b768e79ee228bc80270bcc74/black-25.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ab0ce111ef026790e9b13bd216fa7bc48edd934ffc4cbf78808b235793cbc92", size = 1571829, upload-time = "2025-09-19T00:32:42.13Z" }, - { url = "https://files.pythonhosted.org/packages/4e/64/5c7f66bd65af5c19b4ea86062bb585adc28d51d37babf70969e804dbd5c2/black-25.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f96b6726d690c96c60ba682955199f8c39abc1ae0c3a494a9c62c0184049a713", size = 1631888, upload-time = "2025-09-19T00:30:54.212Z" }, - { url = "https://files.pythonhosted.org/packages/3b/64/0b9e5bfcf67db25a6eef6d9be6726499a8a72ebab3888c2de135190853d3/black-25.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:d119957b37cc641596063cd7db2656c5be3752ac17877017b2ffcdb9dfc4d2b1", size = 1327056, upload-time = "2025-09-19T00:31:08.877Z" }, - { url = "https://files.pythonhosted.org/packages/b7/f4/7531d4a336d2d4ac6cc101662184c8e7d068b548d35d874415ed9f4116ef/black-25.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", size = 1698727, upload-time = "2025-09-19T00:31:14.264Z" }, - { url = "https://files.pythonhosted.org/packages/28/f9/66f26bfbbf84b949cc77a41a43e138d83b109502cd9c52dfc94070ca51f2/black-25.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", size = 1555679, upload-time = "2025-09-19T00:31:29.265Z" }, - { url = "https://files.pythonhosted.org/packages/bf/59/61475115906052f415f518a648a9ac679d7afbc8da1c16f8fdf68a8cebed/black-25.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", size = 1617453, upload-time = "2025-09-19T00:30:42.24Z" }, - { url = "https://files.pythonhosted.org/packages/7f/5b/20fd5c884d14550c911e4fb1b0dae00d4abb60a4f3876b449c4d3a9141d5/black-25.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", size = 1333655, upload-time = "2025-09-19T00:30:56.715Z" }, - { url = "https://files.pythonhosted.org/packages/fb/8e/319cfe6c82f7e2d5bfb4d3353c6cc85b523d677ff59edc61fdb9ee275234/black-25.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", size = 1742012, upload-time = "2025-09-19T00:33:08.678Z" }, - { url = "https://files.pythonhosted.org/packages/94/cc/f562fe5d0a40cd2a4e6ae3f685e4c36e365b1f7e494af99c26ff7f28117f/black-25.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", size = 1581421, upload-time = "2025-09-19T00:35:25.937Z" }, - { url = "https://files.pythonhosted.org/packages/84/67/6db6dff1ebc8965fd7661498aea0da5d7301074b85bba8606a28f47ede4d/black-25.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", size = 1655619, upload-time = "2025-09-19T00:30:49.241Z" }, - { url = "https://files.pythonhosted.org/packages/10/10/3faef9aa2a730306cf469d76f7f155a8cc1f66e74781298df0ba31f8b4c8/black-25.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", size = 1342481, upload-time = "2025-09-19T00:31:29.625Z" }, - { url = "https://files.pythonhosted.org/packages/48/99/3acfea65f5e79f45472c45f87ec13037b506522719cd9d4ac86484ff51ac/black-25.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", size = 1742165, upload-time = "2025-09-19T00:34:10.402Z" }, - { url = "https://files.pythonhosted.org/packages/3a/18/799285282c8236a79f25d590f0222dbd6850e14b060dfaa3e720241fd772/black-25.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", size = 1581259, upload-time = "2025-09-19T00:32:49.685Z" }, - { url = "https://files.pythonhosted.org/packages/f1/ce/883ec4b6303acdeca93ee06b7622f1fa383c6b3765294824165d49b1a86b/black-25.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", size = 1655583, upload-time = "2025-09-19T00:30:44.505Z" }, - { url = "https://files.pythonhosted.org/packages/21/17/5c253aa80a0639ccc427a5c7144534b661505ae2b5a10b77ebe13fa25334/black-25.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", size = 1343428, upload-time = "2025-09-19T00:32:13.839Z" }, - { url = "https://files.pythonhosted.org/packages/1b/46/863c90dcd3f9d41b109b7f19032ae0db021f0b2a81482ba0a1e28c84de86/black-25.9.0-py3-none-any.whl", hash = "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", size = 203363, upload-time = "2025-09-19T00:27:35.724Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/a8/11170031095655d36ebc6664fe0897866f6023892396900eec0e8fdc4299/black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2", size = 1866562, upload-time = "2026-03-12T03:39:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/9e7548d719c3248c6c2abfd555d11169457cbd584d98d179111338423790/black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b", size = 1703623, upload-time = "2026-03-12T03:40:00.347Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0a/8d17d1a9c06f88d3d030d0b1d4373c1551146e252afe4547ed601c0e697f/black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac", size = 1768388, upload-time = "2026-03-12T03:40:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/79/c1ee726e221c863cde5164f925bacf183dfdf0397d4e3f94889439b947b4/black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a", size = 1412969, upload-time = "2026-03-12T03:40:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/73/a5/15c01d613f5756f68ed8f6d4ec0a1e24b82b18889fa71affd3d1f7fad058/black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a", size = 1220345, upload-time = "2026-03-12T03:40:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, + { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/86e462cdd311a3c2a8ece708d22aba17d0b2a0d5348ca34b40cdcbea512e/black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983", size = 1420867, upload-time = "2026-03-12T03:40:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e5/22515a19cb7eaee3440325a6b0d95d2c0e88dd180cb011b12ae488e031d1/black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb", size = 1230124, upload-time = "2026-03-12T03:40:20.425Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/5728052a3c0450c53d9bb3945c4c46b91baa62b2cafab6801411b6271e45/black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54", size = 1895034, upload-time = "2026-03-12T03:40:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/7cae55fdfdfbe9d19e9a8d25d145018965fe2079fa908101c3733b0c55a0/black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f", size = 1718503, upload-time = "2026-03-12T03:40:23.666Z" }, + { url = "https://files.pythonhosted.org/packages/e1/87/af89ad449e8254fdbc74654e6467e3c9381b61472cc532ee350d28cfdafb/black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56", size = 1793557, upload-time = "2026-03-12T03:40:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/43/10/d6c06a791d8124b843bf325ab4ac7d2f5b98731dff84d6064eafd687ded1/black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839", size = 1422766, upload-time = "2026-03-12T03:40:27.14Z" }, + { url = "https://files.pythonhosted.org/packages/59/4f/40a582c015f2d841ac24fed6390bd68f0fc896069ff3a886317959c9daf8/black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2", size = 1232140, upload-time = "2026-03-12T03:40:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/e36e27c9cebc1311b7579210df6f1c86e50f2d7143ae4fcf8a5017dc8809/black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78", size = 1889234, upload-time = "2026-03-12T03:40:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7b/9871acf393f64a5fa33668c19350ca87177b181f44bb3d0c33b2d534f22c/black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568", size = 1720522, upload-time = "2026-03-12T03:40:32.346Z" }, + { url = "https://files.pythonhosted.org/packages/03/87/e766c7f2e90c07fb7586cc787c9ae6462b1eedab390191f2b7fc7f6170a9/black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f", size = 1787824, upload-time = "2026-03-12T03:40:33.636Z" }, + { url = "https://files.pythonhosted.org/packages/ac/94/2424338fb2d1875e9e83eed4c8e9c67f6905ec25afd826a911aea2b02535/black-26.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c", size = 1445855, upload-time = "2026-03-12T03:40:35.442Z" }, + { url = "https://files.pythonhosted.org/packages/86/43/0c3338bd928afb8ee7471f1a4eec3bdbe2245ccb4a646092a222e8669840/black-26.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1", size = 1258109, upload-time = "2026-03-12T03:40:36.832Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/52d98722666d6fc6c3dd4c76df339501d6efd40e0ff95e6186a7b7f0befd/black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b", size = 207542, upload-time = "2026-03-12T03:36:01.668Z" }, ] [[package]] @@ -875,11 +884,11 @@ wheels = [ [[package]] name = "pathspec" -version = "0.12.1" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] [[package]] @@ -1160,11 +1169,41 @@ wheels = [ [[package]] name = "pytokens" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d4/c2/dbadcdddb412a267585459142bfd7cc241e6276db69339353ae6e241ab2b/pytokens-0.2.0.tar.gz", hash = "sha256:532d6421364e5869ea57a9523bf385f02586d4662acbcc0342afd69511b4dd43", size = 15368, upload-time = "2025-10-15T08:02:42.738Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/5a/c269ea6b348b6f2c32686635df89f32dbe05df1088dd4579302a6f8f99af/pytokens-0.2.0-py3-none-any.whl", hash = "sha256:74d4b318c67f4295c13782ddd9abcb7e297ec5630ad060eb90abf7ebbefe59f8", size = 12038, upload-time = "2025-10-15T08:02:41.694Z" }, +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/24/f206113e05cb8ef51b3850e7ef88f20da6f4bf932190ceb48bd3da103e10/pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5", size = 161522, upload-time = "2026-01-30T01:02:50.393Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e9/06a6bf1b90c2ed81a9c7d2544232fe5d2891d1cd480e8a1809ca354a8eb2/pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe", size = 246945, upload-time = "2026-01-30T01:02:52.399Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/f6fb1007a4c3d8b682d5d65b7c1fb33257587a5f782647091e3408abe0b8/pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c", size = 259525, upload-time = "2026-01-30T01:02:53.737Z" }, + { url = "https://files.pythonhosted.org/packages/04/92/086f89b4d622a18418bac74ab5db7f68cf0c21cf7cc92de6c7b919d76c88/pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7", size = 262693, upload-time = "2026-01-30T01:02:54.871Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7b/8b31c347cf94a3f900bdde750b2e9131575a61fdb620d3d3c75832262137/pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2", size = 103567, upload-time = "2026-01-30T01:02:56.414Z" }, + { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, + { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, + { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, + { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, + { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, + { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, + { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, + { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/b470f672e6fc5fee0a01d9e75005a0e617e162381974213a945fcd274843/pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321", size = 160821, upload-time = "2026-01-30T01:03:19.684Z" }, + { url = "https://files.pythonhosted.org/packages/80/98/e83a36fe8d170c911f864bfded690d2542bfcfacb9c649d11a9e6eb9dc41/pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa", size = 254263, upload-time = "2026-01-30T01:03:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/0f/95/70d7041273890f9f97a24234c00b746e8da86df462620194cef1d411ddeb/pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d", size = 268071, upload-time = "2026-01-30T01:03:21.888Z" }, + { url = "https://files.pythonhosted.org/packages/da/79/76e6d09ae19c99404656d7db9c35dfd20f2086f3eb6ecb496b5b31163bad/pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324", size = 271716, upload-time = "2026-01-30T01:03:23.633Z" }, + { url = "https://files.pythonhosted.org/packages/79/37/482e55fa1602e0a7ff012661d8c946bafdc05e480ea5a32f4f7e336d4aa9/pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9", size = 104539, upload-time = "2026-01-30T01:03:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/30/e8/20e7db907c23f3d63b0be3b8a4fd1927f6da2395f5bcc7f72242bb963dfe/pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb", size = 168474, upload-time = "2026-01-30T01:03:26.428Z" }, + { url = "https://files.pythonhosted.org/packages/d6/81/88a95ee9fafdd8f5f3452107748fd04c24930d500b9aba9738f3ade642cc/pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3", size = 290473, upload-time = "2026-01-30T01:03:27.415Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/3aa899645e29b6375b4aed9f8d21df219e7c958c4c186b465e42ee0a06bf/pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975", size = 303485, upload-time = "2026-01-30T01:03:28.558Z" }, + { url = "https://files.pythonhosted.org/packages/52/a0/07907b6ff512674d9b201859f7d212298c44933633c946703a20c25e9d81/pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a", size = 306698, upload-time = "2026-01-30T01:03:29.653Z" }, + { url = "https://files.pythonhosted.org/packages/39/2a/cbbf9250020a4a8dd53ba83a46c097b69e5eb49dd14e708f496f548c6612/pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918", size = 116287, upload-time = "2026-01-30T01:03:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, ] [[package]] From 7e0a587b1b7dd264329a25286866edaf1eb9d72d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Drouin?= Date: Wed, 18 Mar 2026 18:49:16 +0100 Subject: [PATCH 11/52] feat(schema): upgrade ACP schema from v0.10.8 to v0.11.2 (#80) - Regenerate schema bindings and Pydantic models - Add session/close endpoint and CloseSession request/response types - Add message_id parameter to PromptRequest - Add AuthCapabilities, AuthEnvVar, AuthMethodAgent, AuthMethodEnvVar types - Rename KillTerminalCommandRequest/Response to KillTerminalRequest/Response - Rename SetSessionConfigOptionRequest to SetSessionConfigOptionSelectRequest - Promote session/list from unstable to stable - Update agent/client routers, interfaces, examples, and tests accordingly Generated by Mistral Vibe. Co-authored-by: Mistral Vibe --- examples/client.py | 6 +- examples/gemini.py | 12 +- schema/VERSION | 2 +- schema/meta.json | 1 + schema/schema.json | 441 ++++++++++++++++++++++++++++++++--- scripts/gen_schema.py | 7 +- src/acp/__init__.py | 12 +- src/acp/agent/connection.py | 14 +- src/acp/agent/router.py | 15 +- src/acp/client/connection.py | 18 +- src/acp/client/router.py | 4 +- src/acp/interfaces.py | 20 +- src/acp/meta.py | 3 +- src/acp/schema.py | 404 ++++++++++++++++++++++++++++---- tests/conftest.py | 10 +- tests/test_golden.py | 4 +- tests/test_rpc.py | 10 + tests/test_unstable.py | 11 +- 18 files changed, 876 insertions(+), 118 deletions(-) diff --git a/examples/client.py b/examples/client.py index be38edb..2abcc1a 100644 --- a/examples/client.py +++ b/examples/client.py @@ -28,7 +28,7 @@ EnvVariable, ImageContentBlock, Implementation, - KillTerminalCommandResponse, + KillTerminalResponse, PermissionOption, ReadTextFileResponse, ReleaseTerminalResponse, @@ -86,9 +86,7 @@ async def wait_for_terminal_exit( ) -> WaitForTerminalExitResponse: raise RequestError.method_not_found("terminal/wait_for_exit") - async def kill_terminal( - self, session_id: str, terminal_id: str, **kwargs: Any - ) -> KillTerminalCommandResponse | None: + async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: raise RequestError.method_not_found("terminal/kill") async def session_update( diff --git a/examples/gemini.py b/examples/gemini.py index 937bbe7..60eed0a 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -33,8 +33,8 @@ EmbeddedResourceContentBlock, EnvVariable, FileEditToolCallContent, - FileSystemCapability, - KillTerminalCommandResponse, + FileSystemCapabilities, + KillTerminalResponse, PermissionOption, ReadTextFileResponse, ReleaseTerminalResponse, @@ -183,11 +183,9 @@ async def wait_for_terminal_exit( print(f"[Client] waitForTerminalExit: {session_id} {terminal_id}") return WaitForTerminalExitResponse() - async def kill_terminal( - self, session_id: str, terminal_id: str, **kwargs: Any - ) -> KillTerminalCommandResponse | None: + async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: print(f"[Client] killTerminal: {session_id} {terminal_id}") - return KillTerminalCommandResponse() + return KillTerminalResponse() def _pick_preferred_option(options: Iterable[PermissionOption]) -> PermissionOption | None: @@ -320,7 +318,7 @@ async def run(argv: list[str]) -> int: # noqa: C901 init_resp = await conn.initialize( protocol_version=PROTOCOL_VERSION, client_capabilities=ClientCapabilities( - fs=FileSystemCapability(read_text_file=True, write_text_file=True), + fs=FileSystemCapabilities(read_text_file=True, write_text_file=True), terminal=True, ), ) diff --git a/schema/VERSION b/schema/VERSION index 3222b17..62d2bd0 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.10.8 +refs/tags/v0.11.2 diff --git a/schema/meta.json b/schema/meta.json index 507c21d..bfa8448 100644 --- a/schema/meta.json +++ b/schema/meta.json @@ -3,6 +3,7 @@ "authenticate": "authenticate", "initialize": "initialize", "session_cancel": "session/cancel", + "session_close": "session/close", "session_fork": "session/fork", "session_list": "session/list", "session_load": "session/load", diff --git a/schema/schema.json b/schema/schema.json index ba61b43..f679c1a 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -172,11 +172,11 @@ { "allOf": [ { - "$ref": "#/$defs/KillTerminalCommandRequest" + "$ref": "#/$defs/KillTerminalRequest" } ], - "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "KillTerminalCommandRequest" + "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: Call `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", + "title": "KillTerminalRequest" }, { "allOf": [ @@ -268,6 +268,14 @@ ], "title": "ResumeSessionResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/CloseSessionResponse" + } + ], + "title": "CloseSessionResponse" + }, { "allOf": [ { @@ -408,8 +416,115 @@ ], "type": "object" }, + "AuthCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\n\nAdvertised during initialization to inform the agent which authentication\nmethod types the client can handle. This governs opt-in types that require\nadditional client-side support.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "terminal": { + "default": false, + "description": "Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods.", + "type": "boolean" + } + }, + "type": "object" + }, + "AuthEnvVar": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDescribes a single environment variable for an [`AuthMethodEnvVar`] authentication method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "label": { + "description": "Human-readable label for this variable, displayed in client UI.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "The environment variable name (e.g. `\"OPENAI_API_KEY\"`).", + "type": "string" + }, + "optional": { + "default": false, + "description": "Whether this variable is optional.\n\nDefaults to `false`.", + "type": "boolean" + }, + "secret": { + "default": true, + "description": "Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`.", + "type": "boolean" + } + }, + "required": [ + "name" + ], + "type": "object" + }, "AuthMethod": { - "description": "Describes an available authentication method.", + "anyOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/AuthMethodEnvVar" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUser provides a key that the client passes to the agent as an environment variable.", + "properties": { + "type": { + "const": "env_var", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/AuthMethodTerminal" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nClient runs an interactive terminal for the user to authenticate via a TUI.", + "properties": { + "type": { + "const": "terminal", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/AuthMethodAgent" + } + ], + "description": "Agent handles authentication itself.\n\nThis is the default when no `type` is specified.", + "title": "agent" + } + ], + "description": "Describes an available authentication method.\n\nThe `type` field acts as the discriminator in the serialized JSON form.\nWhen no `type` is present, the method is treated as `agent`." + }, + "AuthMethodAgent": { + "description": "Agent handles authentication itself.\n\nThis is the default authentication method type.", "properties": { "_meta": { "additionalProperties": true, @@ -441,6 +556,101 @@ ], "type": "object" }, + "AuthMethodEnvVar": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nEnvironment variable authentication method.\n\nThe user provides credentials that the client passes to the agent as environment variables.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "description": { + "description": "Optional description providing more details about this authentication method.", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Unique identifier for this authentication method.", + "type": "string" + }, + "link": { + "description": "Optional link to a page where the user can obtain their credentials.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "Human-readable name of the authentication method.", + "type": "string" + }, + "vars": { + "description": "The environment variables the client should set.", + "items": { + "$ref": "#/$defs/AuthEnvVar" + }, + "type": "array" + } + }, + "required": [ + "id", + "name", + "vars" + ], + "type": "object" + }, + "AuthMethodTerminal": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nTerminal-based authentication method.\n\nThe client runs an interactive terminal for the user to authenticate via a TUI.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "args": { + "description": "Additional arguments to pass when running the agent binary for terminal auth.", + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "description": "Optional description providing more details about this authentication method.", + "type": [ + "string", + "null" + ] + }, + "env": { + "additionalProperties": { + "type": "string" + }, + "description": "Additional environment variables to set when running the agent binary for terminal auth.", + "type": "object" + }, + "id": { + "description": "Unique identifier for this authentication method.", + "type": "string" + }, + "name": { + "description": "Human-readable name of the authentication method.", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, "AuthenticateRequest": { "description": "Request parameters for the authenticate method.\n\nSpecifies which authentication method to use.", "properties": { @@ -650,10 +860,21 @@ "null" ] }, + "auth": { + "allOf": [ + { + "$ref": "#/$defs/AuthCapabilities" + } + ], + "default": { + "terminal": false + }, + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." + }, "fs": { "allOf": [ { - "$ref": "#/$defs/FileSystemCapability" + "$ref": "#/$defs/FileSystemCapabilities" } ], "default": { @@ -766,7 +987,7 @@ "$ref": "#/$defs/ListSessionsRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `listSessions` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", + "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", "title": "ListSessionsRequest" }, { @@ -787,6 +1008,15 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `session.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", "title": "ResumeSessionRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/CloseSessionRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active session and frees up any resources associated with it.\n\nThis method is only available if the agent advertises the `session.close` capability.\n\nThe agent must cancel any ongoing work (as if `session/cancel` was called)\nand then free up any resources associated with the session.", + "title": "CloseSessionRequest" + }, { "allOf": [ { @@ -916,7 +1146,7 @@ { "allOf": [ { - "$ref": "#/$defs/KillTerminalCommandResponse" + "$ref": "#/$defs/KillTerminalResponse" } ], "title": "KillTerminalResponse" @@ -959,6 +1189,49 @@ ], "x-docs-ignore": true }, + "CloseSessionRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for closing an active session.\n\nIf supported, the agent **must** cancel any ongoing work related to the session\n(treat it as if `session/cancel` was called) and then free up any resources\nassociated with the session.\n\nOnly available if the Agent supports the `session.close` capability.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to close." + } + }, + "required": [ + "sessionId" + ], + "type": "object", + "x-method": "session/close", + "x-side": "agent" + }, + "CloseSessionResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from closing a session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "session/close", + "x-side": "agent" + }, "ConfigOptionUpdate": { "description": "Session configuration options have been updated.", "properties": { @@ -1124,6 +1397,13 @@ } ], "description": "A single item of content" + }, + "messageId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.\nBoth clients and agents MUST use UUID format for message IDs.", + "type": [ + "string", + "null" + ] } }, "required": [ @@ -1471,8 +1751,8 @@ "ExtResponse": { "description": "Allows for sending an arbitrary response to an [`ExtRequest`] that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" }, - "FileSystemCapability": { - "description": "Filesystem capabilities supported by the client.\nFile system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", + "FileSystemCapabilities": { + "description": "File system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", "properties": { "_meta": { "additionalProperties": true, @@ -1710,6 +1990,9 @@ } ], "default": { + "auth": { + "terminal": false + }, "fs": { "readTextFile": false, "writeTextFile": false @@ -1812,8 +2095,8 @@ "x-method": "initialize", "x-side": "agent" }, - "KillTerminalCommandRequest": { - "description": "Request to kill a terminal command without releasing the terminal.", + "KillTerminalRequest": { + "description": "Request to kill a terminal without releasing it.", "properties": { "_meta": { "additionalProperties": true, @@ -1844,8 +2127,8 @@ "x-method": "terminal/kill", "x-side": "client" }, - "KillTerminalCommandResponse": { - "description": "Response to terminal/kill command method", + "KillTerminalResponse": { + "description": "Response to `terminal/kill` method", "properties": { "_meta": { "additionalProperties": true, @@ -1861,7 +2144,7 @@ "x-side": "client" }, "ListSessionsRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for listing existing sessions.\n\nOnly available if the Agent supports the `listSessions` capability.", + "description": "Request parameters for listing existing sessions.\n\nOnly available if the Agent supports the `sessionCapabilities.list` capability.", "properties": { "_meta": { "additionalProperties": true, @@ -1891,7 +2174,7 @@ "x-side": "agent" }, "ListSessionsResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from listing sessions.", + "description": "Response from listing sessions.", "properties": { "_meta": { "additionalProperties": true, @@ -2537,6 +2820,13 @@ "null" ] }, + "messageId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", + "type": [ + "string", + "null" + ] + }, "prompt": { "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", "items": { @@ -2590,6 +2880,13 @@ } ], "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." + }, + "userMessageId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", + "type": [ + "string", + "null" + ] } }, "required": [ @@ -3044,6 +3341,17 @@ "null" ] }, + "close": { + "anyOf": [ + { + "$ref": "#/$defs/SessionCloseCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/close`." + }, "fork": { "anyOf": [ { @@ -3064,7 +3372,7 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/list`." + "description": "Whether the agent supports `session/list`." }, "resume": { "anyOf": [ @@ -3080,6 +3388,33 @@ }, "type": "object" }, + "SessionCloseCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionConfigBoolean": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", + "properties": { + "currentValue": { + "description": "The current value of the boolean option.", + "type": "boolean" + } + }, + "required": [ + "currentValue" + ], + "type": "object" + }, "SessionConfigGroupId": { "description": "Unique identifier for a session configuration option value group.", "type": "string" @@ -3111,6 +3446,24 @@ "type" ], "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigBoolean" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", + "properties": { + "type": { + "const": "boolean", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" } ], "properties": { @@ -3329,7 +3682,7 @@ "type": "string" }, "SessionInfo": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a session returned by session/list", + "description": "Information about a session returned by session/list", "properties": { "_meta": { "additionalProperties": true, @@ -3401,7 +3754,7 @@ "type": "object" }, "SessionListCapabilities": { - "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.\n\nFurther capabilities can be added in the future for other means of filtering or searching the list.", + "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", "properties": { "_meta": { "additionalProperties": true, @@ -3771,6 +4124,44 @@ ] }, "SetSessionConfigOptionRequest": { + "anyOf": [ + { + "description": "A boolean value (`type: \"boolean\"`).", + "properties": { + "type": { + "const": "boolean", + "type": "string" + }, + "value": { + "description": "The boolean value.", + "type": "boolean" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "description": "A [`SessionConfigValueId`] string value.\n\nThis is the default when `type` is absent on the wire. Unknown `type`\nvalues with string payloads also gracefully deserialize into this\nvariant.", + "properties": { + "value": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigValueId" + } + ], + "description": "The value ID." + } + }, + "required": [ + "value" + ], + "title": "value_id", + "type": "object" + } + ], "description": "Request parameters for setting a session configuration option.", "properties": { "_meta": { @@ -3796,20 +4187,11 @@ } ], "description": "The ID of the session to set the configuration option for." - }, - "value": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } - ], - "description": "The ID of the configuration option value to set." } }, "required": [ "sessionId", - "configId", - "value" + "configId" ], "type": "object", "x-method": "session/set_config_option", @@ -3882,6 +4264,7 @@ "properties": { "_meta": { "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" @@ -4807,7 +5190,7 @@ "$ref": "#/$defs/CancelRequestNotification" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", "title": "CancelRequestNotification" } ], diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 74a8790..ad9c6fb 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -51,7 +51,12 @@ "McpServer2": "SseMcpServer", "RequestPermissionOutcome1": "DeniedOutcome", "RequestPermissionOutcome2": "AllowedOutcome", + "AuthMethod1": "EnvVarAuthMethod", + "AuthMethod2": "TerminalAuthMethod", "SessionConfigOption1": "SessionConfigOptionSelect", + "SessionConfigOption2": "SessionConfigOptionBoolean", + "SetSessionConfigOptionRequest1": "SetSessionConfigOptionBooleanRequest", + "SetSessionConfigOptionRequest2": "SetSessionConfigOptionSelectRequest", "SessionUpdate1": "UserMessageChunk", "SessionUpdate2": "AgentMessageChunk", "SessionUpdate3": "AgentThoughtChunk", @@ -101,7 +106,7 @@ "prompt_capabilities", "PromptCapabilities()", ), - ("ClientCapabilities", "fs", "FileSystemCapability()"), + ("ClientCapabilities", "fs", "FileSystemCapabilities()"), ("ClientCapabilities", "terminal", "False"), ( "InitializeRequest", diff --git a/src/acp/__init__.py b/src/acp/__init__.py index 7cbde3c..c49b187 100644 --- a/src/acp/__init__.py +++ b/src/acp/__init__.py @@ -45,8 +45,8 @@ CreateTerminalResponse, InitializeRequest, InitializeResponse, - KillTerminalCommandRequest, - KillTerminalCommandResponse, + KillTerminalRequest, + KillTerminalResponse, LoadSessionRequest, LoadSessionResponse, NewSessionRequest, @@ -60,8 +60,8 @@ RequestPermissionRequest, RequestPermissionResponse, SessionNotification, - SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, + SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -117,7 +117,7 @@ "SetSessionModeResponse", "SetSessionModelRequest", "SetSessionModelResponse", - "SetSessionConfigOptionRequest", + "SetSessionConfigOptionSelectRequest", "SetSessionConfigOptionResponse", # terminal types "CreateTerminalRequest", @@ -126,8 +126,8 @@ "TerminalOutputResponse", "WaitForTerminalExitRequest", "WaitForTerminalExitResponse", - "KillTerminalCommandRequest", - "KillTerminalCommandResponse", + "KillTerminalRequest", + "KillTerminalResponse", "ReleaseTerminalRequest", "ReleaseTerminalResponse", # core diff --git a/src/acp/agent/connection.py b/src/acp/agent/connection.py index b3b0351..64c96d9 100644 --- a/src/acp/agent/connection.py +++ b/src/acp/agent/connection.py @@ -17,8 +17,8 @@ CreateTerminalResponse, CurrentModeUpdate, EnvVariable, - KillTerminalCommandRequest, - KillTerminalCommandResponse, + KillTerminalRequest, + KillTerminalResponse, PermissionOption, ReadTextFileRequest, ReadTextFileResponse, @@ -191,15 +191,13 @@ async def wait_for_terminal_exit( WaitForTerminalExitResponse, ) - @param_model(KillTerminalCommandRequest) - async def kill_terminal( - self, session_id: str, terminal_id: str, **kwargs: Any - ) -> KillTerminalCommandResponse | None: + @param_model(KillTerminalRequest) + async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: return await request_optional_model( self._conn, CLIENT_METHODS["terminal_kill"], - KillTerminalCommandRequest(session_id=session_id, terminal_id=terminal_id, field_meta=kwargs or None), - KillTerminalCommandResponse, + KillTerminalRequest(session_id=session_id, terminal_id=terminal_id, field_meta=kwargs or None), + KillTerminalResponse, ) async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]: diff --git a/src/acp/agent/router.py b/src/acp/agent/router.py index 8477716..26db13f 100644 --- a/src/acp/agent/router.py +++ b/src/acp/agent/router.py @@ -9,6 +9,7 @@ from ..schema import ( AuthenticateRequest, CancelNotification, + CloseSessionRequest, ForkSessionRequest, InitializeRequest, ListSessionsRequest, @@ -16,7 +17,7 @@ NewSessionRequest, PromptRequest, ResumeSessionRequest, - SetSessionConfigOptionRequest, + SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModeRequest, ) @@ -37,7 +38,15 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes "load_session", adapt_result=normalize_result, ) - router.route_request(AGENT_METHODS["session_list"], ListSessionsRequest, agent, "list_sessions", unstable=True) + router.route_request(AGENT_METHODS["session_list"], ListSessionsRequest, agent, "list_sessions") + router.route_request( + AGENT_METHODS["session_close"], + CloseSessionRequest, + agent, + "close_session", + adapt_result=normalize_result, + unstable=True, + ) router.route_request( AGENT_METHODS["session_set_mode"], SetSessionModeRequest, @@ -56,7 +65,7 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes ) router.route_request( AGENT_METHODS["session_set_config_option"], - SetSessionConfigOptionRequest, + SetSessionConfigOptionSelectRequest, agent, "set_config_option", adapt_result=normalize_result, diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 7d0396e..d3471b6 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -13,6 +13,8 @@ AuthenticateResponse, CancelNotification, ClientCapabilities, + CloseSessionRequest, + CloseSessionResponse, EmbeddedResourceContentBlock, ForkSessionRequest, ForkSessionResponse, @@ -33,8 +35,8 @@ ResourceContentBlock, ResumeSessionRequest, ResumeSessionResponse, - SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, + SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -152,14 +154,14 @@ async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) SetSessionModelResponse, ) - @param_model(SetSessionConfigOptionRequest) + @param_model(SetSessionConfigOptionSelectRequest) async def set_config_option( self, config_id: str, session_id: str, value: str, **kwargs: Any ) -> SetSessionConfigOptionResponse: return await request_model_from_dict( self._conn, AGENT_METHODS["session_set_config_option"], - SetSessionConfigOptionRequest( + SetSessionConfigOptionSelectRequest( config_id=config_id, session_id=session_id, value=value, field_meta=kwargs or None ), SetSessionConfigOptionResponse, @@ -185,6 +187,7 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, + message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: return await request_model( @@ -224,6 +227,15 @@ async def resume_session( ResumeSessionResponse, ) + @param_model(CloseSessionRequest) + async def close_session(self, session_id: str, **kwargs: Any) -> CloseSessionResponse | None: + return await request_model_from_dict( + self._conn, + AGENT_METHODS["session_close"], + CloseSessionRequest(session_id=session_id, field_meta=kwargs or None), + CloseSessionResponse, + ) + @param_model(CancelNotification) async def cancel(self, session_id: str, **kwargs: Any) -> None: await notify_model( diff --git a/src/acp/client/router.py b/src/acp/client/router.py index 4bab2d9..5b9049b 100644 --- a/src/acp/client/router.py +++ b/src/acp/client/router.py @@ -8,7 +8,7 @@ from ..router import MessageRouter from ..schema import ( CreateTerminalRequest, - KillTerminalCommandRequest, + KillTerminalRequest, ReadTextFileRequest, ReleaseTerminalRequest, RequestPermissionRequest, @@ -68,7 +68,7 @@ def build_client_router(client: Client, use_unstable_protocol: bool = False) -> ) router.route_request( CLIENT_METHODS["terminal_kill"], - KillTerminalCommandRequest, + KillTerminalRequest, client, "kill_terminal", optional=True, diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 1fd572f..f33f403 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -12,6 +12,8 @@ AvailableCommandsUpdate, CancelNotification, ClientCapabilities, + CloseSessionRequest, + CloseSessionResponse, ConfigOptionUpdate, CreateTerminalRequest, CreateTerminalResponse, @@ -25,8 +27,8 @@ Implementation, InitializeRequest, InitializeResponse, - KillTerminalCommandRequest, - KillTerminalCommandResponse, + KillTerminalRequest, + KillTerminalResponse, ListSessionsRequest, ListSessionsResponse, LoadSessionRequest, @@ -48,8 +50,8 @@ ResumeSessionResponse, SessionInfoUpdate, SessionNotification, - SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, + SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModelResponse, SetSessionModeRequest, @@ -132,10 +134,8 @@ async def wait_for_terminal_exit( self, session_id: str, terminal_id: str, **kwargs: Any ) -> WaitForTerminalExitResponse: ... - @param_model(KillTerminalCommandRequest) - async def kill_terminal( - self, session_id: str, terminal_id: str, **kwargs: Any - ) -> KillTerminalCommandResponse | None: ... + @param_model(KillTerminalRequest) + async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: ... async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]: ... @@ -181,7 +181,7 @@ async def set_session_model( self, model_id: str, session_id: str, **kwargs: Any ) -> SetSessionModelResponse | None: ... - @param_model(SetSessionConfigOptionRequest) + @param_model(SetSessionConfigOptionSelectRequest) async def set_config_option( self, config_id: str, session_id: str, value: str, **kwargs: Any ) -> SetSessionConfigOptionResponse | None: ... @@ -200,6 +200,7 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, + message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: ... @@ -221,6 +222,9 @@ async def resume_session( **kwargs: Any, ) -> ResumeSessionResponse: ... + @param_model(CloseSessionRequest) + async def close_session(self, session_id: str, **kwargs: Any) -> CloseSessionResponse | None: ... + @param_model(CancelNotification) async def cancel(self, session_id: str, **kwargs: Any) -> None: ... diff --git a/src/acp/meta.py b/src/acp/meta.py index 82aae7e..bc57869 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,9 +1,10 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.10.8 +# Schema ref: refs/tags/v0.11.2 AGENT_METHODS = { "authenticate": "authenticate", "initialize": "initialize", "session_cancel": "session/cancel", + "session_close": "session/close", "session_fork": "session/fork", "session_list": "session/list", "session_load": "session/load", diff --git a/src/acp/schema.py b/src/acp/schema.py index e449e4a..32031c4 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,5 +1,5 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.10.8 +# Schema ref: refs/tags/v0.11.2 from __future__ import annotations @@ -30,7 +30,7 @@ class Jsonrpc(Enum): field_2_0 = "2.0" -class AuthMethod(BaseModel): +class AuthCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -43,11 +43,145 @@ class AuthMethod(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # Whether the client supports `terminal` authentication methods. + # + # When `true`, the agent may include `terminal` entries in its authentication methods. + terminal: Annotated[ + Optional[bool], + Field( + description="Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods." + ), + ] = False + + +class AuthEnvVar(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Human-readable label for this variable, displayed in client UI. + label: Annotated[ + Optional[str], + Field(description="Human-readable label for this variable, displayed in client UI."), + ] = None + # The environment variable name (e.g. `"OPENAI_API_KEY"`). + name: Annotated[ + str, + Field(description='The environment variable name (e.g. `"OPENAI_API_KEY"`).'), + ] + # Whether this variable is optional. + # + # Defaults to `false`. + optional: Annotated[ + Optional[bool], + Field(description="Whether this variable is optional.\n\nDefaults to `false`."), + ] = False + # Whether this value is a secret (e.g. API key, token). + # Clients should use a password-style input for secret vars. + # + # Defaults to `true`. + secret: Annotated[ + Optional[bool], + Field( + description="Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`." + ), + ] = True + + +class AuthMethodAgent(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Optional description providing more details about this authentication method. + description: Annotated[ + Optional[str], + Field(description="Optional description providing more details about this authentication method."), + ] = None + # Unique identifier for this authentication method. + id: Annotated[str, Field(description="Unique identifier for this authentication method.")] + # Human-readable name of the authentication method. + name: Annotated[str, Field(description="Human-readable name of the authentication method.")] + + +class AuthMethodEnvVar(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Optional description providing more details about this authentication method. + description: Annotated[ + Optional[str], + Field(description="Optional description providing more details about this authentication method."), + ] = None + # Unique identifier for this authentication method. + id: Annotated[str, Field(description="Unique identifier for this authentication method.")] + # Optional link to a page where the user can obtain their credentials. + link: Annotated[ + Optional[str], + Field(description="Optional link to a page where the user can obtain their credentials."), + ] = None + # Human-readable name of the authentication method. + name: Annotated[str, Field(description="Human-readable name of the authentication method.")] + # The environment variables the client should set. + vars: Annotated[ + List[AuthEnvVar], + Field(description="The environment variables the client should set."), + ] + + +class AuthMethodTerminal(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Additional arguments to pass when running the agent binary for terminal auth. + args: Annotated[ + Optional[List[str]], + Field(description="Additional arguments to pass when running the agent binary for terminal auth."), + ] = None # Optional description providing more details about this authentication method. description: Annotated[ Optional[str], Field(description="Optional description providing more details about this authentication method."), ] = None + # Additional environment variables to set when running the agent binary for terminal auth. + env: Annotated[ + Optional[Dict[str, str]], + Field(description="Additional environment variables to set when running the agent binary for terminal auth."), + ] = None # Unique identifier for this authentication method. id: Annotated[str, Field(description="Unique identifier for this authentication method.")] # Human-readable name of the authentication method. @@ -111,6 +245,21 @@ class BlobResourceContents(BaseModel): uri: str +class CloseSessionResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class Cost(BaseModel): # Total cumulative cost for session. amount: Annotated[float, Field(description="Total cumulative cost for session.")] @@ -184,7 +333,7 @@ class EnvVariable(BaseModel): value: Annotated[str, Field(description="The value to set for the environment variable.")] -class FileSystemCapability(BaseModel): +class FileSystemCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -275,7 +424,7 @@ class Implementation(BaseModel): ] -class KillTerminalCommandResponse(BaseModel): +class KillTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -524,6 +673,29 @@ class SelectedPermissionOutcome(BaseModel): ] +class SessionCloseCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class SessionConfigBoolean(BaseModel): + # The current value of the boolean option. + current_value: Annotated[ + bool, + Field(alias="currentValue", description="The current value of the boolean option."), + ] + + class SessionForkCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -658,7 +830,38 @@ class SessionInfoUpdate(_SessionInfoUpdate): session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] -class SetSessionConfigOptionRequest(BaseModel): +class SetSessionConfigOptionBooleanRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the configuration option to set. + config_id: Annotated[ + str, + Field(alias="configId", description="The ID of the configuration option to set."), + ] + # The ID of the session to set the configuration option for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to set the configuration option for.", + ), + ] + type: Literal["boolean"] + # The boolean value. + value: Annotated[bool, Field(description="The boolean value.")] + + +class SetSessionConfigOptionSelectRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -684,8 +887,8 @@ class SetSessionConfigOptionRequest(BaseModel): description="The ID of the session to set the configuration option for.", ), ] - # The ID of the configuration option value to set. - value: Annotated[str, Field(description="The ID of the configuration option value to set.")] + # The value ID. + value: Annotated[str, Field(description="The value ID.")] class SetSessionModeRequest(BaseModel): @@ -711,7 +914,18 @@ class SetSessionModeRequest(BaseModel): class SetSessionModeResponse(BaseModel): - field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None class SetSessionModelRequest(BaseModel): @@ -1096,6 +1310,14 @@ class AudioContent(BaseModel): mime_type: Annotated[str, Field(alias="mimeType")] +class EnvVarAuthMethod(AuthMethodEnvVar): + type: Literal["env_var"] + + +class TerminalAuthMethod(AuthMethodTerminal): + type: Literal["terminal"] + + class AvailableCommandInput(RootModel[UnstructuredCommandInput]): # The input specification for a command. root: Annotated[ @@ -1160,14 +1382,27 @@ class ClientCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Authentication capabilities supported by the client. + # Determines which authentication method types the agent may include + # in its `InitializeResponse`. + auth: Annotated[ + Optional[AuthCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." + ), + ] = {"terminal": False} # File system capabilities supported by the client. # Determines which file operations the agent can request. fs: Annotated[ - Optional[FileSystemCapability], + Optional[FileSystemCapabilities], Field( description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." ), - ] = FileSystemCapability() + ] = FileSystemCapabilities() # Whether the Client support all `terminal/*` methods. terminal: Annotated[ Optional[bool], @@ -1180,6 +1415,23 @@ class ClientNotification(BaseModel): params: Optional[Union[CancelNotification, Any]] = None +class CloseSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the session to close. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] + + class AudioContentBlock(AudioContent): type: Literal["audio"] @@ -1337,7 +1589,7 @@ class InitializeRequest(BaseModel): ] -class KillTerminalCommandRequest(BaseModel): +class KillTerminalRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1507,6 +1759,22 @@ class PromptResponse(BaseModel): description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # The acknowledged user message ID. + # + # If the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here + # to confirm it was recorded. If the client did not provide one, the agent MAY assign one + # and return it here. Absence of this field indicates the agent did not record a message ID. + user_message_id: Annotated[ + Optional[str], + Field( + alias="userMessageId", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", + ), + ] = None class ReadTextFileRequest(BaseModel): @@ -1647,23 +1915,28 @@ class SessionCapabilities(BaseModel): # # This capability is not part of the spec yet, and may be removed or changed at any point. # - # Whether the agent supports `session/fork`. - fork: Annotated[ - Optional[SessionForkCapabilities], + # Whether the agent supports `session/close`. + close: Annotated[ + Optional[SessionCloseCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/close`." ), ] = None # **UNSTABLE** # # This capability is not part of the spec yet, and may be removed or changed at any point. # + # Whether the agent supports `session/fork`. + fork: Annotated[ + Optional[SessionForkCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + ), + ] = None # Whether the agent supports `session/list`. list: Annotated[ Optional[SessionListCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/list`." - ), + Field(description="Whether the agent supports `session/list`."), ] = None # **UNSTABLE** # @@ -1678,6 +1951,36 @@ class SessionCapabilities(BaseModel): ] = None +class SessionConfigOptionBoolean(SessionConfigBoolean): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Optional semantic category for this option (UX only). + category: Annotated[ + Optional[str], + Field(description="Optional semantic category for this option (UX only)."), + ] = None + # Optional description for the Client to display to the user. + description: Annotated[ + Optional[str], + Field(description="Optional description for the Client to display to the user."), + ] = None + # Unique identifier for the configuration option. + id: Annotated[str, Field(description="Unique identifier for the configuration option.")] + # Human-readable label for the option. + name: Annotated[str, Field(description="Human-readable label for the option.")] + type: Literal["boolean"] + + class SessionConfigSelectOption(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1910,7 +2213,7 @@ class ClientResponseMessage(BaseModel): TerminalOutputResponse, ReleaseTerminalResponse, WaitForTerminalExitResponse, - KillTerminalCommandResponse, + KillTerminalResponse, Any, ], Field( @@ -2035,7 +2338,7 @@ class InitializeResponse(BaseModel): ] = None # Authentication methods supported by the agent. auth_methods: Annotated[ - Optional[List[AuthMethod]], + Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], Field( alias="authMethods", description="Authentication methods supported by the agent.", @@ -2164,6 +2467,22 @@ class ContentChunk(BaseModel): ], Field(description="A single item of content", discriminator="type"), ] + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # A unique identifier for the message this chunk belongs to. + # + # All chunks belonging to the same message share the same `messageId`. + # A change in `messageId` indicates a new message has started. + # Both clients and agents MUST use UUID format for message IDs. + message_id: Annotated[ + Optional[str], + Field( + alias="messageId", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.\nBoth clients and agents MUST use UUID format for message IDs.", + ), + ] = None class PromptRequest(BaseModel): @@ -2179,6 +2498,22 @@ class PromptRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # A client-generated unique identifier for this user message. + # + # If provided, the Agent SHOULD echo this value as `userMessageId` in the + # [`PromptResponse`] to confirm it was recorded. + # Both clients and agents MUST use UUID format for message IDs. + message_id: Annotated[ + Optional[str], + Field( + alias="messageId", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", + ), + ] = None # The blocks of content that compose the user's message. # # As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], @@ -2264,10 +2599,11 @@ class ClientRequest(BaseModel): ListSessionsRequest, ForkSessionRequest, ResumeSessionRequest, + CloseSessionRequest, SetSessionModeRequest, - SetSessionConfigOptionRequest, PromptRequest, SetSessionModelRequest, + Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], Any, ] ] = None @@ -2325,17 +2661,6 @@ class SessionConfigOptionSelect(SessionConfigSelect): type: Literal["select"] -class SessionConfigOption(RootModel[SessionConfigOptionSelect]): - # A session configuration option selector and its current state. - root: Annotated[ - SessionConfigOptionSelect, - Field( - description="A session configuration option selector and its current state.", - discriminator="type", - ), - ] - - class SetSessionConfigOptionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2351,7 +2676,7 @@ class SetSessionConfigOptionResponse(BaseModel): ] = None # The full set of configuration options and their current values. config_options: Annotated[ - List[SessionConfigOption], + List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], Field( alias="configOptions", description="The full set of configuration options and their current values.", @@ -2418,7 +2743,7 @@ class _ConfigOptionUpdate(BaseModel): ] = None # The full set of configuration options and their current values. config_options: Annotated[ - List[SessionConfigOption], + List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], Field( alias="configOptions", description="The full set of configuration options and their current values.", @@ -2441,7 +2766,7 @@ class ForkSessionResponse(BaseModel): ] = None # Initial session configuration options if supported by the Agent. config_options: Annotated[ - Optional[List[SessionConfigOption]], + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], Field( alias="configOptions", description="Initial session configuration options if supported by the Agent.", @@ -2492,7 +2817,7 @@ class LoadSessionResponse(BaseModel): ] = None # Initial session configuration options if supported by the Agent. config_options: Annotated[ - Optional[List[SessionConfigOption]], + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], Field( alias="configOptions", description="Initial session configuration options if supported by the Agent.", @@ -2535,7 +2860,7 @@ class NewSessionResponse(BaseModel): ] = None # Initial session configuration options if supported by the Agent. config_options: Annotated[ - Optional[List[SessionConfigOption]], + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], Field( alias="configOptions", description="Initial session configuration options if supported by the Agent.", @@ -2618,7 +2943,7 @@ class ResumeSessionResponse(BaseModel): ] = None # Initial session configuration options if supported by the Agent. config_options: Annotated[ - Optional[List[SessionConfigOption]], + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], Field( alias="configOptions", description="Initial session configuration options if supported by the Agent.", @@ -2739,7 +3064,7 @@ class AgentRequest(BaseModel): TerminalOutputRequest, ReleaseTerminalRequest, WaitForTerminalExitRequest, - KillTerminalCommandRequest, + KillTerminalRequest, Any, ] ] = None @@ -2776,6 +3101,7 @@ class AgentResponseMessage(BaseModel): ListSessionsResponse, ForkSessionResponse, ResumeSessionResponse, + CloseSessionResponse, SetSessionModeResponse, SetSessionConfigOptionResponse, PromptResponse, diff --git a/tests/conftest.py b/tests/conftest.py index a2a373d..825610a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ AuthenticateResponse, CreateTerminalResponse, InitializeResponse, - KillTerminalCommandResponse, + KillTerminalResponse, LoadSessionResponse, NewSessionResponse, PromptRequest, @@ -43,6 +43,7 @@ HttpMcpServer, ImageContentBlock, Implementation, + ListSessionsResponse, McpServerStdio, PermissionOption, ResourceContentBlock, @@ -211,7 +212,7 @@ async def wait_for_terminal_exit( async def kill_terminal( self, session_id: str, terminal_id: str | None = None, **kwargs: Any - ) -> KillTerminalCommandResponse | None: + ) -> KillTerminalResponse | None: raise NotImplementedError async def ext_method(self, method: str, params: dict) -> dict: @@ -274,6 +275,11 @@ async def prompt( async def cancel(self, session_id: str, **kwargs: Any) -> None: self.cancellations.append(session_id) + async def list_sessions( + self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any + ) -> ListSessionsResponse: + return ListSessionsResponse(sessions=[]) + async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: return SetSessionModeResponse() diff --git a/tests/test_golden.py b/tests/test_golden.py index 181945f..2420ed2 100644 --- a/tests/test_golden.py +++ b/tests/test_golden.py @@ -51,8 +51,8 @@ RequestPermissionRequest, RequestPermissionResponse, ResourceContentBlock, - SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, + SetSessionConfigOptionSelectRequest, TerminalToolCallContent, TextContentBlock, ToolCallLocation, @@ -96,7 +96,7 @@ "session_update_tool_call_update_content": ToolCallProgress, "session_update_tool_call_update_more_fields": ToolCallProgress, "session_update_user_message_chunk": UserMessageChunk, - "set_session_config_option_request": SetSessionConfigOptionRequest, + "set_session_config_option_request": SetSessionConfigOptionSelectRequest, "set_session_config_option_response": SetSessionConfigOptionResponse, "tool_content_content_text": ContentToolCallContent, "tool_content_diff": FileEditToolCallContent, diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 7b4c37e..bcf068e 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -38,6 +38,7 @@ HttpMcpServer, ImageContentBlock, Implementation, + ListSessionsResponse, McpServerStdio, PermissionOption, ResourceContentBlock, @@ -263,6 +264,15 @@ async def test_set_config_option(connect, agent, client): assert resp.config_options == [] +@pytest.mark.asyncio +async def test_list_sessions_stable(connect, agent, client): + _, agent_conn = connect() + + resp = await agent_conn.list_sessions() + assert isinstance(resp, ListSessionsResponse) + assert resp.sessions == [] + + @pytest.mark.asyncio async def test_ignore_invalid_messages(connect, server): connect(connect_agent=True, connect_client=False) diff --git a/tests/test_unstable.py b/tests/test_unstable.py index afdbb28..0a25e47 100644 --- a/tests/test_unstable.py +++ b/tests/test_unstable.py @@ -4,6 +4,7 @@ from acp.exceptions import RequestError from acp.schema import ( + CloseSessionResponse, ForkSessionResponse, HttpMcpServer, ListSessionsResponse, @@ -19,6 +20,9 @@ class UnstableAgent(TestAgent): async def list_sessions(self, cursor: str | None = None, cwd: str | None = None, **kwargs) -> ListSessionsResponse: return ListSessionsResponse(sessions=[]) + async def close_session(self, session_id: str, **kwargs) -> CloseSessionResponse | None: + return CloseSessionResponse() + async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) -> SetSessionModelResponse | None: return SetSessionModelResponse() @@ -58,6 +62,9 @@ async def test_call_unstable_protocol(connect): resp = await agent_conn.resume_session(cwd="/workspace", session_id="sess") assert isinstance(resp, ResumeSessionResponse) + resp = await agent_conn.close_session(session_id="sess") + assert isinstance(resp, CloseSessionResponse) + @pytest.mark.parametrize("agent", [UnstableAgent()]) @pytest.mark.asyncio @@ -66,10 +73,10 @@ async def test_call_unstable_protocol_warning(connect): with pytest.warns(UserWarning) as record: with pytest.raises(RequestError): - await agent_conn.list_sessions() + await agent_conn.set_session_model(session_id="sess", model_id="gpt-4o-mini") assert len(record) == 1 with pytest.warns(UserWarning) as record: with pytest.raises(RequestError): - await agent_conn.set_session_model(session_id="sess", model_id="gpt-4o-mini") + await agent_conn.close_session(session_id="sess") assert len(record) == 1 From 65ed78180bb2eb38854e72d15465aa01e0b316a8 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Fri, 20 Mar 2026 02:42:19 +0800 Subject: [PATCH 12/52] chore: bump to 0.9.0a1 --- docs/releasing.md | 5 +++-- pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/releasing.md b/docs/releasing.md index 6b3ff65..0e3c42a 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -9,7 +9,7 @@ Every package release tracks an upstream ACP schema tag from [`agentclientprotoc ACP_SCHEMA_VERSION=v0.4.5 make gen-all ``` This refreshes `schema/` and the generated `src/acp/schema.py`. -2. **Bump the SDK version** in `pyproject.toml` (and regenerate `uv.lock` if deps moved). +2. **Bump the SDK version** in `pyproject.toml` using a PEP 440 version string (for example `0.9.0a1` for an alpha release), and sync `uv.lock` if the lockfile is tracked. 3. **Run the standard gates:** ```bash make check # Ruff format/lint, type analysis, dep hygiene @@ -20,7 +20,7 @@ Every package release tracks an upstream ACP schema tag from [`agentclientprotoc ## Commit & review - Keep the diff tight: regenerated schema files, version bumps, doc updates, and any required fixture refresh (goldens, RPC tests, etc.). -- Use a Conventional Commit such as `release: v0.4.5`. +- Use a Conventional Commit such as `release: 0.9.0a1`. - In the PR description, capture: - The ACP schema tag you targeted. - Output from `make check` / `make test` (and optional Gemini tests if you ran them). @@ -31,6 +31,7 @@ Every package release tracks an upstream ACP schema tag from [`agentclientprotoc Releases are automated by `on-release-main.yml` once the PR lands on `main`. 1. Draft a GitHub Release for the new tag (the UI creates the tag if missing). + Use the exact package version as the tag, for example `0.9.0a1` or `0.9.0`. 2. Publishing the release triggers the workflow, which: - Syncs the tag back into `pyproject.toml`. - Builds and uploads to PyPI via `uv publish` using `PYPI_TOKEN`. diff --git a/pyproject.toml b/pyproject.toml index 63e17fc..96f452c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.8.1" +version = "0.9.0a1" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 938a030..8109330 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.8.1" +version = "0.9.0a1" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 2af0e7c715f6fa67c28d98af8114debe172155af Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Thu, 26 Mar 2026 01:12:07 +0800 Subject: [PATCH 13/52] fix: sync initialize response golden fixture --- tests/golden/initialize_response.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/golden/initialize_response.json b/tests/golden/initialize_response.json index 66abb81..e4db91d 100644 --- a/tests/golden/initialize_response.json +++ b/tests/golden/initialize_response.json @@ -7,7 +7,8 @@ "image": true, "audio": true, "embeddedContext": true - } + }, + "sessionCapabilities": {} }, "authMethods": [] } From a57c672ca581bbd66f16769e08198008f7d5fb65 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Thu, 26 Mar 2026 01:08:01 +0000 Subject: [PATCH 14/52] fix: complete schema v0.11.2 follow-ups (#81) --- src/acp/agent/router.py | 45 ++++++++++++--- src/acp/client/connection.py | 34 +++++++++--- src/acp/interfaces.py | 7 ++- src/acp/router.py | 52 +++++++++++------- src/acp/utils.py | 104 +++++++++++++++++++++++++++++++++-- tests/conftest.py | 14 ++++- tests/test_compatibility.py | 43 +++++++++++++++ tests/test_rpc.py | 24 ++++++++ tests/test_utils.py | 41 +++++++++++++- 9 files changed, 317 insertions(+), 47 deletions(-) diff --git a/src/acp/agent/router.py b/src/acp/agent/router.py index 26db13f..2a27bcd 100644 --- a/src/acp/agent/router.py +++ b/src/acp/agent/router.py @@ -2,10 +2,12 @@ from typing import Any +from pydantic import BaseModel + from ..exceptions import RequestError from ..interfaces import Agent from ..meta import AGENT_METHODS -from ..router import MessageRouter +from ..router import MessageRouter, Route, _resolve_handler, _warn_legacy_handler from ..schema import ( AuthenticateRequest, CancelNotification, @@ -17,15 +19,41 @@ NewSessionRequest, PromptRequest, ResumeSessionRequest, + SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModeRequest, ) -from ..utils import normalize_result +from ..utils import model_to_kwargs, normalize_result __all__ = ["build_agent_router"] +_SET_CONFIG_OPTION_MODELS = (SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) + + +def _validate_set_config_option_request(params: Any) -> BaseModel: + if isinstance(params, dict) and params.get("type") == "boolean": + return SetSessionConfigOptionBooleanRequest.model_validate(params) + return SetSessionConfigOptionSelectRequest.model_validate(params) + + +def _make_set_config_option_handler(agent: Agent) -> Any: + func, attr, legacy_api = _resolve_handler(agent, "set_config_option") + if func is None: + return None + + async def wrapper(params: Any) -> Any: + if legacy_api: + _warn_legacy_handler(agent, attr) + request = _validate_set_config_option_request(params) + if legacy_api: + return await func(request) + return await func(**model_to_kwargs(request, _SET_CONFIG_OPTION_MODELS)) + + return wrapper + + def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> MessageRouter: router = MessageRouter(use_unstable_protocol=use_unstable_protocol) @@ -63,12 +91,13 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes adapt_result=normalize_result, unstable=True, ) - router.route_request( - AGENT_METHODS["session_set_config_option"], - SetSessionConfigOptionSelectRequest, - agent, - "set_config_option", - adapt_result=normalize_result, + router.add_route( + Route( + method=AGENT_METHODS["session_set_config_option"], + func=_make_set_config_option_handler(agent), + kind="request", + adapt_result=normalize_result, + ) ) router.route_request( AGENT_METHODS["authenticate"], diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index d3471b6..bb8fdc2 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -35,6 +35,7 @@ ResourceContentBlock, ResumeSessionRequest, ResumeSessionResponse, + SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, SetSessionModelRequest, @@ -44,7 +45,7 @@ SseMcpServer, TextContentBlock, ) -from ..utils import compatible_class, notify_model, param_model, request_model, request_model_from_dict +from ..utils import compatible_class, notify_model, param_model, param_models, request_model, request_model_from_dict from .router import build_client_router __all__ = ["ClientSideConnection"] @@ -154,16 +155,30 @@ async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) SetSessionModelResponse, ) - @param_model(SetSessionConfigOptionSelectRequest) + @param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) async def set_config_option( - self, config_id: str, session_id: str, value: str, **kwargs: Any + self, config_id: str, session_id: str, value: str | bool, **kwargs: Any ) -> SetSessionConfigOptionResponse: + request = ( + SetSessionConfigOptionBooleanRequest( + config_id=config_id, + session_id=session_id, + type="boolean", + value=value, + field_meta=kwargs or None, + ) + if isinstance(value, bool) + else SetSessionConfigOptionSelectRequest( + config_id=config_id, + session_id=session_id, + value=value, + field_meta=kwargs or None, + ) + ) return await request_model_from_dict( self._conn, AGENT_METHODS["session_set_config_option"], - SetSessionConfigOptionSelectRequest( - config_id=config_id, session_id=session_id, value=value, field_meta=kwargs or None - ), + request, SetSessionConfigOptionResponse, ) @@ -193,7 +208,12 @@ async def prompt( return await request_model( self._conn, AGENT_METHODS["session_prompt"], - PromptRequest(prompt=prompt, session_id=session_id, field_meta=kwargs or None), + PromptRequest( + prompt=prompt, + session_id=session_id, + message_id=message_id, + field_meta=kwargs or None, + ), PromptResponse, ) diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index f33f403..2decdb2 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -50,6 +50,7 @@ ResumeSessionResponse, SessionInfoUpdate, SessionNotification, + SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, SetSessionModelRequest, @@ -70,7 +71,7 @@ WriteTextFileRequest, WriteTextFileResponse, ) -from .utils import param_model +from .utils import param_model, param_models __all__ = ["Agent", "Client"] @@ -181,9 +182,9 @@ async def set_session_model( self, model_id: str, session_id: str, **kwargs: Any ) -> SetSessionModelResponse | None: ... - @param_model(SetSessionConfigOptionSelectRequest) + @param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) async def set_config_option( - self, config_id: str, session_id: str, value: str, **kwargs: Any + self, config_id: str, session_id: str, value: str | bool, **kwargs: Any ) -> SetSessionConfigOptionResponse | None: ... @param_model(AuthenticateRequest) diff --git a/src/acp/router.py b/src/acp/router.py index 2aa3c24..3069deb 100644 --- a/src/acp/router.py +++ b/src/acp/router.py @@ -20,6 +20,34 @@ HandlerT = TypeVar("HandlerT", bound=RequestHandler) +def _warn_legacy_handler(obj: Any, attr: str) -> None: + warnings.warn( + f"The old style method {type(obj).__name__}.{attr} is deprecated, please update to the snake-cased form.", + DeprecationWarning, + stacklevel=3, + ) + + +def _resolve_handler(obj: Any, attr: str) -> tuple[AsyncHandler | None, str, bool]: + legacy_api = False + func = getattr(obj, attr, None) + if func is None and "_" in attr: + attr = to_camel_case(attr) + func = getattr(obj, attr, None) + legacy_api = True + elif callable(func) and "_" not in attr: + original_func = func + if hasattr(func, "__func__"): + original_func = func.__func__ + parameters = inspect.signature(original_func).parameters + if len(parameters) == 2 and "params" in parameters: + legacy_api = True + + if func is None or not callable(func): + return None, attr, legacy_api + return func, attr, legacy_api + + @dataclass(slots=True) class Route: method: str @@ -63,31 +91,13 @@ def add_route(self, route: Route) -> None: self._notifications[route.method] = route def _make_func(self, model: type[BaseModel], obj: Any, attr: str) -> AsyncHandler | None: - legacy_api = False - func = getattr(obj, attr, None) - if func is None and "_" in attr: - attr = to_camel_case(attr) - func = getattr(obj, attr, None) - legacy_api = True - elif callable(func) and "_" not in attr: - original_func = func - if hasattr(func, "__func__"): - original_func = func.__func__ - parameters = inspect.signature(original_func).parameters - if len(parameters) == 2 and "params" in parameters: - legacy_api = True - - if func is None or not callable(func): + func, attr, legacy_api = _resolve_handler(obj, attr) + if func is None: return None async def wrapper(params: Any) -> Any: if legacy_api: - warnings.warn( - f"The old style method {type(obj).__name__}.{attr} is deprecated, " - "please update to the snake-cased form.", - DeprecationWarning, - stacklevel=3, - ) + _warn_legacy_handler(obj, attr) model_obj = model.model_validate(params) if legacy_api: return await func(model_obj) # type: ignore[arg-type] diff --git a/src/acp/utils.py b/src/acp/utils.py index 1be9c19..3d62496 100644 --- a/src/acp/utils.py +++ b/src/acp/utils.py @@ -26,6 +26,29 @@ MethodT = TypeVar("MethodT", bound=Callable) ClassT = TypeVar("ClassT", bound=type) T = TypeVar("T") +MultiParamModelSpec = tuple[type[BaseModel], ...] + + +def _param_models_name(models: MultiParamModelSpec) -> str: + return " | ".join(model_type.__name__ for model_type in models) + + +def _param_models_field_names(models: MultiParamModelSpec) -> tuple[str, ...]: + shared_fields = set(models[0].model_fields) + for model_type in models[1:]: + shared_fields &= set(model_type.model_fields) + return tuple(field_name for field_name in models[0].model_fields if field_name in shared_fields) + + +def model_to_kwargs(model_obj: BaseModel, models: MultiParamModelSpec) -> dict[str, Any]: + kwargs = { + field_name: getattr(model_obj, field_name) + for field_name in _param_models_field_names(models) + if field_name != "field_meta" + } + if meta := getattr(model_obj, "field_meta", None): + kwargs.update(meta) + return kwargs def serialize_params(params: BaseModel) -> dict[str, Any]: @@ -114,6 +137,18 @@ def decorator(func: MethodT) -> MethodT: return decorator +def param_models(*param_cls: type[BaseModel]) -> Callable[[MethodT], MethodT]: + """Decorator to mark a method as accepting multiple legacy parameter models.""" + if not param_cls: + raise ValueError("param_models() requires at least one model class") + + def decorator(func: MethodT) -> MethodT: + func.__param_models__ = param_cls # type: ignore[attr-defined] + return func + + return decorator + + def to_camel_case(snake_str: str) -> str: """Convert snake_case strings to camelCase.""" components = snake_str.split("_") @@ -129,7 +164,9 @@ def wrapped(self, params: BaseModel) -> T: DeprecationWarning, stacklevel=3, ) - kwargs = {k: getattr(params, k) for k in model.model_fields if k != "field_meta"} + kwargs = { + field_name: getattr(params, field_name) for field_name in model.model_fields if field_name != "field_meta" + } if meta := getattr(params, "field_meta", None): kwargs.update(meta) return func(self, **kwargs) # type: ignore[arg-type] @@ -152,7 +189,11 @@ def wrapped(self, *args: Any, **kwargs: Any) -> T: DeprecationWarning, stacklevel=3, ) - kwargs = {k: getattr(param, k) for k in model.model_fields if k != "field_meta"} + kwargs = { + field_name: getattr(param, field_name) + for field_name in model.model_fields + if field_name != "field_meta" + } if meta := getattr(param, "field_meta", None): kwargs.update(meta) return func(self, **kwargs) # type: ignore[arg-type] @@ -161,14 +202,67 @@ def wrapped(self, *args: Any, **kwargs: Any) -> T: return wrapped +def _make_multi_legacy_func(func: Callable[..., T], models: MultiParamModelSpec) -> Callable[[Any, BaseModel], T]: + model_name = _param_models_name(models) + + @functools.wraps(func) + def wrapped(self, params: BaseModel) -> T: + warnings.warn( + f"Calling {func.__name__} with {model_name} parameter is " # type: ignore[attr-defined] + "deprecated, please update to the new API style.", + DeprecationWarning, + stacklevel=3, + ) + return func(self, **model_to_kwargs(params, models)) # type: ignore[arg-type] + + return wrapped + + +def _make_multi_compatible_func(func: Callable[..., T], models: MultiParamModelSpec) -> Callable[..., T]: + model_name = _param_models_name(models) + + @functools.wraps(func) + def wrapped(self, *args: Any, **kwargs: Any) -> T: + param = None + if not kwargs and len(args) == 1: + param = args[0] + elif not args and len(kwargs) == 1: + param = kwargs.get("params") + if isinstance(param, models): + warnings.warn( + f"Calling {func.__name__} with {model_name} parameter " # type: ignore[attr-defined] + "is deprecated, please update to the new API style.", + DeprecationWarning, + stacklevel=3, + ) + return func(self, **model_to_kwargs(param, models)) # type: ignore[arg-type] + return func(self, *args, **kwargs) + + return wrapped + + def compatible_class(cls: ClassT) -> ClassT: """Mark a class as backward compatible with old API style.""" for attr in dir(cls): func = getattr(cls, attr) - if not callable(func) or (model := getattr(func, "__param_model__", None)) is None: + if not callable(func): + continue + model = getattr(func, "__param_model__", None) + models = getattr(func, "__param_models__", None) + if model is None and models is None: continue if "_" in attr: - setattr(cls, to_camel_case(attr), _make_legacy_func(func, model)) + if models is not None: + setattr(cls, to_camel_case(attr), _make_multi_legacy_func(func, models)) + else: + if model is None: + continue + setattr(cls, to_camel_case(attr), _make_legacy_func(func, model)) else: - setattr(cls, attr, _make_compatible_func(func, model)) + if models is not None: + setattr(cls, attr, _make_multi_compatible_func(func, models)) + else: + if model is None: + continue + setattr(cls, attr, _make_compatible_func(func, model)) return cls diff --git a/tests/conftest.py b/tests/conftest.py index 825610a..f154167 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -231,6 +231,7 @@ class TestAgent: def __init__(self) -> None: self.prompts: list[PromptRequest] = [] self.cancellations: list[str] = [] + self.config_option_calls: list[tuple[str, str, str | bool]] = [] self.ext_calls: list[tuple[str, dict]] = [] self.ext_notes: list[tuple[str, dict]] = [] @@ -267,9 +268,17 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, + message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: - self.prompts.append(PromptRequest(prompt=prompt, session_id=session_id, field_meta=kwargs or None)) + self.prompts.append( + PromptRequest( + prompt=prompt, + session_id=session_id, + message_id=message_id, + field_meta=kwargs or None, + ) + ) return PromptResponse(stop_reason="end_turn") async def cancel(self, session_id: str, **kwargs: Any) -> None: @@ -284,8 +293,9 @@ async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) - return SetSessionModeResponse() async def set_config_option( - self, config_id: str, session_id: str, value: str, **kwargs: Any + self, config_id: str, session_id: str, value: str | bool, **kwargs: Any ) -> SetSessionConfigOptionResponse | None: + self.config_option_calls.append((config_id, session_id, value)) return SetSessionConfigOptionResponse(config_options=[]) async def ext_method(self, method: str, params: dict) -> dict: diff --git a/tests/test_compatibility.py b/tests/test_compatibility.py index 013427e..cdca9ad 100644 --- a/tests/test_compatibility.py +++ b/tests/test_compatibility.py @@ -11,6 +11,7 @@ RequestError, RequestPermissionResponse, SessionNotification, + SetSessionConfigOptionResponse, SetSessionModelResponse, SetSessionModeResponse, WriteTextFileResponse, @@ -25,6 +26,8 @@ NewSessionRequest, ReadTextFileRequest, RequestPermissionRequest, + SetSessionConfigOptionBooleanRequest, + SetSessionConfigOptionSelectRequest, SetSessionModelRequest, SetSessionModeRequest, WriteTextFileRequest, @@ -34,6 +37,9 @@ class LegacyAgent: def __init__(self) -> None: self.prompts: list[PromptRequest] = [] + self.config_option_requests: list[ + SetSessionConfigOptionBooleanRequest | SetSessionConfigOptionSelectRequest + ] = [] self.cancellations: list[str] = [] self.ext_calls: list[tuple[str, dict]] = [] self.ext_notes: list[tuple[str, dict]] = [] @@ -64,6 +70,12 @@ async def setSessionMode(self, params: SetSessionModeRequest) -> SetSessionModeR async def setSessionModel(self, params: SetSessionModelRequest) -> SetSessionModelResponse | None: return SetSessionModelResponse() + async def setConfigOption( + self, params: SetSessionConfigOptionBooleanRequest | SetSessionConfigOptionSelectRequest + ) -> SetSessionConfigOptionResponse | None: + self.config_option_requests.append(params) + return SetSessionConfigOptionResponse(config_options=[]) + async def extMethod(self, method: str, params: dict) -> dict: self.ext_calls.append((method, params)) if method == "example.com/echo": @@ -167,3 +179,34 @@ async def test_initialize_and_new_session_compat(connect, client): assert len(record) == 1 assert resp.content == "Hello, World!" + + +@pytest.mark.asyncio +@pytest.mark.parametrize("agent,client", [(LegacyAgent(), LegacyClient())]) +async def test_set_config_option_boolean_compat(connect, agent): + _, agent_conn = connect() + + with pytest.warns(DeprecationWarning) as record: + resp = await agent_conn.setConfigOption( + SetSessionConfigOptionBooleanRequest( + config_id="brave_mode", + session_id="test-session-123", + type="boolean", + value=True, + ) + ) + + assert len(record) == 2 + assert "SetSessionConfigOptionBooleanRequest | SetSessionConfigOptionSelectRequest parameter is deprecated" in str( + record[0].message + ) + assert "The old style method LegacyAgent.setConfigOption is deprecated" in str(record[1].message) + assert isinstance(resp, SetSessionConfigOptionResponse) + assert agent.config_option_requests == [ + SetSessionConfigOptionBooleanRequest( + config_id="brave_mode", + session_id="test-session-123", + type="boolean", + value=True, + ) + ] diff --git a/tests/test_rpc.py b/tests/test_rpc.py index bcf068e..0d3bb75 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -262,6 +262,30 @@ async def test_set_config_option(connect, agent, client): resp = await agent_conn.set_config_option(session_id="sess", config_id="theme", value="dark") assert isinstance(resp, SetSessionConfigOptionResponse) assert resp.config_options == [] + assert agent.config_option_calls == [("theme", "sess", "dark")] + + +@pytest.mark.asyncio +async def test_set_config_option_boolean(connect, agent, client): + _, agent_conn = connect() + + resp = await agent_conn.set_config_option(session_id="sess", config_id="brave_mode", value=True) + assert isinstance(resp, SetSessionConfigOptionResponse) + assert resp.config_options == [] + assert agent.config_option_calls == [("brave_mode", "sess", True)] + + +@pytest.mark.asyncio +async def test_prompt_message_id_roundtrip(connect, agent, client): + _, agent_conn = connect() + + resp = await agent_conn.prompt( + session_id="sess", + prompt=[TextContentBlock(type="text", text="hello")], + message_id="123e4567-e89b-12d3-a456-426614174000", + ) + assert isinstance(resp, PromptResponse) + assert agent.prompts[-1].message_id == "123e4567-e89b-12d3-a456-426614174000" @pytest.mark.asyncio diff --git a/tests/test_utils.py b/tests/test_utils.py index 47706d9..bf00257 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,11 @@ import pytest -from acp.schema import AgentMessageChunk, TextContentBlock +from acp.schema import ( + AgentMessageChunk, + SetSessionConfigOptionBooleanRequest, + SetSessionConfigOptionSelectRequest, + TextContentBlock, +) from acp.utils import serialize_params @@ -40,6 +45,40 @@ def test_field_meta_can_be_set_by_name_on_models() -> None: assert chunk.content.field_meta == {"inner": "value"} +def test_serialize_params_uses_boolean_config_variant() -> None: + request = SetSessionConfigOptionBooleanRequest( + config_id="brave_mode", + session_id="sess", + type="boolean", + value=True, + ) + + payload = serialize_params(request) + + assert payload == { + "configId": "brave_mode", + "sessionId": "sess", + "type": "boolean", + "value": True, + } + + +def test_serialize_params_uses_select_config_variant() -> None: + request = SetSessionConfigOptionSelectRequest( + config_id="theme", + session_id="sess", + value="dark", + ) + + payload = serialize_params(request) + + assert payload == { + "configId": "theme", + "sessionId": "sess", + "value": "dark", + } + + @pytest.mark.parametrize( "original, expected", [ From 2aba01b7eaf065f5c7db19bb02e5908acfda4945 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Thu, 26 Mar 2026 09:16:03 +0800 Subject: [PATCH 15/52] chore: bump to 0.9.0 --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 96f452c..036b8fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.9.0a1" +version = "0.9.0" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 8109330..696aa84 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.9.0a1" +version = "0.9.0" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 093a562a59bdec3c8bb62ff826cf86e67c427a7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 09:19:34 +0800 Subject: [PATCH 16/52] chore(deps): bump requests in the uv group across 1 directory (#82) Bumps the uv group with 1 update in the / directory: [requests](https://github.com/psf/requests). Updates `requests` from 2.32.5 to 2.33.0 - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.32.5...v2.33.0) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.0 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 696aa84..b739e0d 100644 --- a/uv.lock +++ b/uv.lock @@ -1284,7 +1284,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.5" +version = "2.33.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1292,9 +1292,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/64/8860370b167a9721e8956ae116825caff829224fbca0ca6e7bf8ddef8430/requests-2.33.0.tar.gz", hash = "sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652", size = 134232, upload-time = "2026-03-25T15:10:41.586Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, + { url = "https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl", hash = "sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b", size = 65017, upload-time = "2026-03-25T15:10:40.382Z" }, ] [[package]] From e06ae46c9c1d4eb80e7126facee557327ce2bbeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 00:45:48 +0800 Subject: [PATCH 17/52] chore(deps): bump uv in the uv group across 1 directory (#88) Bumps the uv group with 1 update in the / directory: [uv](https://github.com/astral-sh/uv). Updates `uv` from 0.9.7 to 0.11.6 - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.9.7...0.11.6) --- updated-dependencies: - dependency-name: uv dependency-version: 0.11.6 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/uv.lock b/uv.lock index b739e0d..32be215 100644 --- a/uv.lock +++ b/uv.lock @@ -1512,28 +1512,28 @@ wheels = [ [[package]] name = "uv" -version = "0.9.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cc/f6/9914f57d152cfcb85f3a26f8fbac3c88e4eb9cbe88639076241e16819334/uv-0.9.7.tar.gz", hash = "sha256:555ee72146b8782c73d755e4a21c9885c6bfc81db0ffca2220d52dddae007eb7", size = 3705596, upload-time = "2025-10-30T22:17:18.652Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/58/38/cee64a9dcefd46f83a922c4e31d9cd9d91ce0d27a594192f7df677151eb4/uv-0.9.7-py3-none-linux_armv6l.whl", hash = "sha256:134e0daac56f9e399ccdfc9e4635bc0a13c234cad9224994c67bae462e07399a", size = 20614967, upload-time = "2025-10-30T22:16:31.274Z" }, - { url = "https://files.pythonhosted.org/packages/6f/b7/1b1ff8dfde05e9d27abf29ebf22da48428fe1e16f0b4d65a839bd2211303/uv-0.9.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1aaf79b4234400e9e2fbf5b50b091726ccbb0b6d4d032edd3dfd4c9673d89dca", size = 19692886, upload-time = "2025-10-30T22:16:35.893Z" }, - { url = "https://files.pythonhosted.org/packages/f5/7d/b618174d8a8216af350398ace03805b2b2df6267b1745abf45556c2fda58/uv-0.9.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0fdbfad5b367e7a3968264af6da5bbfffd4944a90319042f166e8df1a2d9de09", size = 18345022, upload-time = "2025-10-30T22:16:38.45Z" }, - { url = "https://files.pythonhosted.org/packages/13/4c/03fafb7d28289d54ac7a34507f1e97e527971f8b0ee2c5e957045966a1a6/uv-0.9.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:635e82c2d0d8b001618af82e4f2724350f15814f6462a71b3ebd44adec21f03c", size = 20170427, upload-time = "2025-10-30T22:16:41.099Z" }, - { url = "https://files.pythonhosted.org/packages/35/0e/f1316da150453755bb88cf4232e8934de71a0091eb274a8b69d948535453/uv-0.9.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56a440ccde7624a7bc070e1c2492b358c67aea9b8f17bc243ea27c5871c8d02c", size = 20234277, upload-time = "2025-10-30T22:16:43.521Z" }, - { url = "https://files.pythonhosted.org/packages/37/b8/cb62cd78151b235c5da9290f0e3fb032b36706f2922208a691678aa0f2df/uv-0.9.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5f1fb8203a77853db176000e8f30d5815ab175dc46199db059f97a72fc51110", size = 21180078, upload-time = "2025-10-30T22:16:45.857Z" }, - { url = "https://files.pythonhosted.org/packages/be/e5/6107249d23f06fa1739496e89699e76169037b4643144b28b324efc3075d/uv-0.9.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bb8bfcc2897f7653522abc2cae80233af756ad857bfbbbbe176f79460cbba417", size = 22743896, upload-time = "2025-10-30T22:16:48.487Z" }, - { url = "https://files.pythonhosted.org/packages/df/94/69d8e0bb29c140305e7677bc8c98c765468a55cb10966e77bb8c69bf815d/uv-0.9.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89697fa0d7384ba047daf75df844ee7800235105e41d08e0c876861a2b4aa90e", size = 22361126, upload-time = "2025-10-30T22:16:51.366Z" }, - { url = "https://files.pythonhosted.org/packages/c0/0d/d186456cd0d7972ed026e5977b8a12e1f94c923fc3d6e86c7826c6f0d1fe/uv-0.9.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9810ee8173dce129c49b338d5e97f3d7c7e9435f73e0b9b26c2f37743d3bb9e", size = 21477489, upload-time = "2025-10-30T22:16:53.757Z" }, - { url = "https://files.pythonhosted.org/packages/c7/59/61d8e9f1734069049abe9e593961de602397c7194712346906c075fec65f/uv-0.9.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cf6bc2482d1293cc630f66b862b494c09acda9b7faff7307ef52667a2b3ad49", size = 21382006, upload-time = "2025-10-30T22:16:56.117Z" }, - { url = "https://files.pythonhosted.org/packages/74/ac/090dbde63abb56001190392d29ca2aa654eebc146a693b5dda68da0df2fb/uv-0.9.7-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7019f4416925f4091b9d28c1cf3e8444cf910c4ede76bdf1f6b9a56ca5f97985", size = 20255103, upload-time = "2025-10-30T22:16:58.434Z" }, - { url = "https://files.pythonhosted.org/packages/56/e7/ca2d99a4ce86366731547a84b5a2c946528b8d6d28c74ac659c925955a0c/uv-0.9.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:edd768f6730bba06aa10fdbd80ee064569f7236806f636bf65b68136a430aad0", size = 21311768, upload-time = "2025-10-30T22:17:01.259Z" }, - { url = "https://files.pythonhosted.org/packages/d8/1a/c5d9e57f52aa30bfee703e6b9e5b5072102cfc706f3444377bb0de79eac7/uv-0.9.7-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:d6e5fe28ca05a4b576c0e8da5f69251dc187a67054829cfc4afb2bfa1767114b", size = 20239129, upload-time = "2025-10-30T22:17:03.815Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ab/16110ca6b1c4aaad79b4f2c6bc102c416a906e5d29947d0dc774f6ef4365/uv-0.9.7-py3-none-musllinux_1_1_i686.whl", hash = "sha256:34fe0af83fcafb9e2b786f4bd633a06c878d548a7c479594ffb5607db8778471", size = 20647326, upload-time = "2025-10-30T22:17:06.33Z" }, - { url = "https://files.pythonhosted.org/packages/89/a9/2a8129c796831279cc0c53ffdd19dd6133d514805e52b1ef8a2aa0ff8912/uv-0.9.7-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:777bb1de174319245a35e4f805d3b4484d006ebedae71d3546f95e7c28a5f436", size = 21604958, upload-time = "2025-10-30T22:17:09.046Z" }, - { url = "https://files.pythonhosted.org/packages/73/97/616650cb4dd5fbaabf8237469e1bc84710ae878095d359999982e1bc8ecf/uv-0.9.7-py3-none-win32.whl", hash = "sha256:bcf878528bd079fe8ae15928b5dfa232fac8b0e1854a2102da6ae1a833c31276", size = 19418913, upload-time = "2025-10-30T22:17:11.384Z" }, - { url = "https://files.pythonhosted.org/packages/de/7f/e3cdaffac70852f5ff933b04c7b8a06c0f91f41e563f04b689caa65b71bd/uv-0.9.7-py3-none-win_amd64.whl", hash = "sha256:62b315f62669899076a1953fba6baf50bd2b57f66f656280491331dcedd7e6c6", size = 21443513, upload-time = "2025-10-30T22:17:13.785Z" }, - { url = "https://files.pythonhosted.org/packages/89/79/8278452acae2fe96829485d32e1a2363829c9e42674704562ffcfc06b140/uv-0.9.7-py3-none-win_arm64.whl", hash = "sha256:d13da6521d4e841b1e0a9fda82e793dcf8458a323a9e8955f50903479d0bfa97", size = 19946729, upload-time = "2025-10-30T22:17:16.669Z" }, +version = "0.11.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/f3/8aceeab67ea69805293ab290e7ca8cc1b61a064d28b8a35c76d8eba063dd/uv-0.11.6.tar.gz", hash = "sha256:e3b21b7e80024c95ff339fcd147ac6fc3dd98d3613c9d45d3a1f4fd1057f127b", size = 4073298, upload-time = "2026-04-09T12:09:01.738Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/fe/4b61a3d5ad9d02e8a4405026ccd43593d7044598e0fa47d892d4dafe44c9/uv-0.11.6-py3-none-linux_armv6l.whl", hash = "sha256:ada04dcf89ddea5b69d27ac9cdc5ef575a82f90a209a1392e930de504b2321d6", size = 23780079, upload-time = "2026-04-09T12:08:56.609Z" }, + { url = "https://files.pythonhosted.org/packages/52/db/d27519a9e1a5ffee9d71af1a811ad0e19ce7ab9ae815453bef39dd479389/uv-0.11.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5be013888420f96879c6e0d3081e7bcf51b539b034a01777041934457dfbedf3", size = 23214721, upload-time = "2026-04-09T12:09:32.228Z" }, + { url = "https://files.pythonhosted.org/packages/a6/8f/4399fa8b882bd7e0efffc829f73ab24d117d490a93e6bc7104a50282b854/uv-0.11.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ffa5dc1cbb52bdce3b8447e83d1601a57ad4da6b523d77d4b47366db8b1ceb18", size = 21750109, upload-time = "2026-04-09T12:09:24.357Z" }, + { url = "https://files.pythonhosted.org/packages/32/07/5a12944c31c3dda253632da7a363edddb869ed47839d4d92a2dc5f546c93/uv-0.11.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bfb107b4dade1d2c9e572992b06992d51dd5f2136eb8ceee9e62dd124289e825", size = 23551146, upload-time = "2026-04-09T12:09:10.439Z" }, + { url = "https://files.pythonhosted.org/packages/79/5b/2ec8b0af80acd1016ed596baf205ddc77b19ece288473b01926c4a9cf6db/uv-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:9e2fe7ce12161d8016b7deb1eaad7905a76ff7afec13383333ca75e0c4b5425d", size = 23331192, upload-time = "2026-04-09T12:09:34.792Z" }, + { url = "https://files.pythonhosted.org/packages/62/7d/eea35935f2112b21c296a3e42645f3e4b1aa8bcd34dcf13345fbd55134b7/uv-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ed9c6f70c25e8dfeedddf4eddaf14d353f5e6b0eb43da9a14d3a1033d51d915", size = 23337686, upload-time = "2026-04-09T12:09:18.522Z" }, + { url = "https://files.pythonhosted.org/packages/21/47/2584f5ab618f6ebe9bdefb2f765f2ca8540e9d739667606a916b35449eec/uv-0.11.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d68a013e609cebf82077cbeeb0809ed5e205257814273bfd31e02fc0353bbfc2", size = 25008139, upload-time = "2026-04-09T12:09:03.983Z" }, + { url = "https://files.pythonhosted.org/packages/95/81/497ae5c1d36355b56b97dc59f550c7e89d0291c163a3f203c6f341dff195/uv-0.11.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93f736dddca03dae732c6fdea177328d3bc4bf137c75248f3d433c57416a4311", size = 25712458, upload-time = "2026-04-09T12:09:07.598Z" }, + { url = "https://files.pythonhosted.org/packages/3c/1c/74083238e4fab2672b63575b9008f1ea418b02a714bcfcf017f4f6a309b6/uv-0.11.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e96a66abe53fced0e3389008b8d2eff8278cfa8bb545d75631ae8ceb9c929aba", size = 24915507, upload-time = "2026-04-09T12:08:50.892Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ee/e14fe10ba455a823ed18233f12de6699a601890905420b5c504abf115116/uv-0.11.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b096311b2743b228df911a19532b3f18fa420bf9530547aecd6a8e04bbfaccd", size = 24971011, upload-time = "2026-04-09T12:08:54.016Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/7b9c83eaadf98e343317ff6384a7227a4855afd02cdaf9696bcc71ee6155/uv-0.11.6-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:904d537b4a6e798015b4a64ff5622023bd4601b43b6cd1e5f423d63471f5e948", size = 23640234, upload-time = "2026-04-09T12:09:15.735Z" }, + { url = "https://files.pythonhosted.org/packages/d6/51/75ccdd23e76ff1703b70eb82881cd5b4d2a954c9679f8ef7e0136ef2cfab/uv-0.11.6-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:4ed8150c26b5e319381d75ae2ce6aba1e9c65888f4850f4e3b3fa839953c90a5", size = 24452664, upload-time = "2026-04-09T12:09:26.875Z" }, + { url = "https://files.pythonhosted.org/packages/4d/86/ace80fe47d8d48b5e3b5aee0b6eb1a49deaacc2313782870250b3faa36f5/uv-0.11.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:1c9218c8d4ac35ca6e617fb0951cc0ab2d907c91a6aea2617de0a5494cf162c0", size = 24494599, upload-time = "2026-04-09T12:09:37.368Z" }, + { url = "https://files.pythonhosted.org/packages/05/2d/4b642669b56648194f026de79bc992cbfc3ac2318b0a8d435f3c284934e8/uv-0.11.6-py3-none-musllinux_1_1_i686.whl", hash = "sha256:9e211c83cc890c569b86a4183fcf5f8b6f0c7adc33a839b699a98d30f1310d3a", size = 24159150, upload-time = "2026-04-09T12:09:13.17Z" }, + { url = "https://files.pythonhosted.org/packages/ae/24/7eecd76fe983a74fed1fc700a14882e70c4e857f1d562a9f2303d4286c12/uv-0.11.6-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:d2a1d2089afdf117ad19a4c1dd36b8189c00ae1ad4135d3bfbfced82342595cf", size = 25164324, upload-time = "2026-04-09T12:08:59.56Z" }, + { url = "https://files.pythonhosted.org/packages/27/e0/bbd4ba7c2e5067bbba617d87d306ec146889edaeeaa2081d3e122178ca08/uv-0.11.6-py3-none-win32.whl", hash = "sha256:6e8344f38fa29f85dcfd3e62dc35a700d2448f8e90381077ef393438dcd5012e", size = 22865693, upload-time = "2026-04-09T12:09:21.415Z" }, + { url = "https://files.pythonhosted.org/packages/a5/33/1983ce113c538a856f2d620d16e39691962ecceef091a84086c5785e32e5/uv-0.11.6-py3-none-win_amd64.whl", hash = "sha256:a28bea69c1186303d1200f155c7a28c449f8a4431e458fcf89360cc7ef546e40", size = 25371258, upload-time = "2026-04-09T12:09:40.52Z" }, + { url = "https://files.pythonhosted.org/packages/35/01/be0873f44b9c9bc250fcbf263367fcfc1f59feab996355bcb6b52fff080d/uv-0.11.6-py3-none-win_arm64.whl", hash = "sha256:a78f6d64b9950e24061bc7ec7f15ff8089ad7f5a976e7b65fcadce58fe02f613", size = 23869585, upload-time = "2026-04-09T12:09:29.425Z" }, ] [[package]] From d53722c68ff1f43a66d03e8fe188cb9913579f84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 10:38:46 +0800 Subject: [PATCH 18/52] chore(deps-dev): bump pytest in the uv group across 1 directory (#89) Bumps the uv group with 1 update in the / directory: [pytest](https://github.com/pytest-dev/pytest). Updates `pytest` from 8.4.2 to 9.0.3 - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.4.2...9.0.3) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.0.3 dependency-type: direct:development dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/uv.lock b/uv.lock index 32be215..8e718f8 100644 --- a/uv.lock +++ b/uv.lock @@ -1116,7 +1116,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.2" +version = "9.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1127,23 +1127,23 @@ dependencies = [ { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] [[package]] name = "pytest-asyncio" -version = "1.2.0" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] [[package]] From 88621c5a24abded0e4dee52f1d4e39b0d5ba600f Mon Sep 17 00:00:00 2001 From: simonrosenberg <157206163+simonrosenberg@users.noreply.github.com> Date: Sun, 19 Apr 2026 09:07:29 -0300 Subject: [PATCH 19/52] fix: reject pending requests on EOF to prevent infinite hang (#86) * fix: reject pending requests on EOF to prevent infinite hang When the remote end closes the connection (e.g., subprocess crashes), _receive_loop exits cleanly on EOF without raising an exception. This means _on_receive_error is never called and pending outgoing request futures hang forever. Add reject_all_outgoing() after the receive loop breaks on EOF so callers get a ConnectionError instead of an infinite hang. Fixes #85 Co-Authored-By: Claude Opus 4.6 * fix: fail fast after connection EOF --------- Co-authored-by: Debug Agent Co-authored-by: Claude Opus 4.6 Co-authored-by: Chojan Shang --- src/acp/connection.py | 16 +++++++++++++++- tests/test_rpc.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/acp/connection.py b/src/acp/connection.py index aca1c19..ccf2fc3 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -83,6 +83,7 @@ def __init__( self._tasks.add_error_handler(self._on_task_error) self._queue = queue or InMemoryMessageQueue() self._closed = False + self._disconnected = False self._sender = (sender_factory or self._default_sender_factory)(self._writer, self._tasks) if listening: self._recv_task = self._tasks.create( @@ -132,6 +133,7 @@ def add_observer(self, observer: StreamObserver) -> None: self._observers.append(observer) async def send_request(self, method: str, params: JsonValue | None = None) -> Any: + self._raise_if_unavailable() request_id = self._next_request_id self._next_request_id += 1 future = self._state.register_outgoing(request_id, method) @@ -141,6 +143,7 @@ async def send_request(self, method: str, params: JsonValue | None = None) -> An return await future async def send_notification(self, method: str, params: JsonValue | None = None) -> None: + self._raise_if_unavailable() payload = {"jsonrpc": "2.0", "method": method, "params": params} await self._sender.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) @@ -160,6 +163,7 @@ async def _receive_loop(self) -> None: await self._process_message(message) except asyncio.CancelledError: return + self._disconnect() async def _process_message(self, message: dict[str, Any]) -> None: method = message.get("method") @@ -262,7 +266,7 @@ async def _handle_response(self, message: dict[str, Any]) -> None: def _on_receive_error(self, task: asyncio.Task[Any], exc: BaseException) -> None: logging.exception("Receive loop failed", exc_info=exc) - self._state.reject_all_outgoing(exc) + self._disconnect() def _on_task_error(self, task: asyncio.Task[Any], exc: BaseException) -> None: logging.exception("Background task failed", exc_info=exc) @@ -285,3 +289,13 @@ def _default_dispatcher_factory( def _default_sender_factory(self, writer: asyncio.StreamWriter, supervisor: TaskSupervisor) -> MessageSender: return MessageSender(writer, supervisor) + + def _disconnect(self) -> None: + if self._disconnected: + return + self._disconnected = True + self._state.reject_all_outgoing(ConnectionError("Connection closed")) + + def _raise_if_unavailable(self) -> None: + if self._disconnected or self._closed: + raise ConnectionError("Connection closed") diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 0d3bb75..b30e358 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -26,6 +26,7 @@ update_agent_message_text, update_tool_call, ) +from acp.connection import Connection from acp.core import AgentSideConnection, ClientSideConnection from acp.schema import ( AgentMessageChunk, @@ -199,6 +200,35 @@ async def read_one(i: int): assert res.content == f"Content {i}" +@pytest.mark.asyncio +async def test_pending_request_fails_when_remote_sends_eof(server): + conn = Connection(lambda method, params, is_notification: None, server.client_writer, server.client_reader) + request = asyncio.create_task(conn.send_request("ping", {"value": 1})) + + await asyncio.sleep(0.05) + server.server_writer.close() + await server.server_writer.wait_closed() + + with pytest.raises(ConnectionError, match="Connection closed"): + await asyncio.wait_for(request, timeout=1.0) + + await conn.close() + + +@pytest.mark.asyncio +async def test_new_requests_fail_fast_after_remote_eof(server): + conn = Connection(lambda method, params, is_notification: None, server.client_writer, server.client_reader) + + server.server_writer.close() + await server.server_writer.wait_closed() + await asyncio.sleep(0.05) + + with pytest.raises(ConnectionError, match="Connection closed"): + await asyncio.wait_for(conn.send_request("ping", {"value": 1}), timeout=1.0) + + await conn.close() + + @pytest.mark.asyncio async def test_invalid_params_results_in_error_response(connect, server): # Only start agent-side (server) so we can inject raw request from client socket From df721735e2cbdfd226ec26469acca9c85362579c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:35:11 +0800 Subject: [PATCH 20/52] chore(deps-dev): bump python-dotenv in the uv group across 1 directory (#90) Bumps the uv group with 1 update in the / directory: [python-dotenv](https://github.com/theskumar/python-dotenv). Updates `python-dotenv` from 1.2.1 to 1.2.2 - [Release notes](https://github.com/theskumar/python-dotenv/releases) - [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md) - [Commits](https://github.com/theskumar/python-dotenv/compare/v1.2.1...v1.2.2) --- updated-dependencies: - dependency-name: python-dotenv dependency-version: 1.2.2 dependency-type: direct:development dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 8e718f8..eda1e22 100644 --- a/uv.lock +++ b/uv.lock @@ -1160,11 +1160,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.2.1" +version = "1.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, ] [[package]] From 03739f4d06c5f65675a45f0ee91ed717a450bb3e Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Wed, 6 May 2026 17:48:01 +0100 Subject: [PATCH 21/52] feat: bump acp protocol to 0.12.2 (#93) * feat: bump acp protocol to 0.12.2 Signed-off-by: Chojan Shang * *: refine Signed-off-by: Chojan Shang --------- Signed-off-by: Chojan Shang --- docs/quickstart.md | 16 +- examples/agent.py | 16 +- examples/client.py | 14 +- examples/echo_agent.py | 9 +- examples/gemini.py | 63 +- pyproject.toml | 2 +- schema/VERSION | 2 +- schema/meta.json | 16 + schema/schema.json | 6709 +++++++++++++++++++++++++--------- scripts/gen_schema.py | 18 + src/acp/client/connection.py | 71 +- src/acp/interfaces.py | 15 +- src/acp/meta.py | 18 +- src/acp/schema.py | 2877 ++++++++++++--- tests/test_rpc.py | 102 +- uv.lock | 2 +- 16 files changed, 7734 insertions(+), 2216 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 08a6602..5e79205 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -92,8 +92,9 @@ import asyncio import sys from pathlib import Path from typing import Any +from uuid import uuid4 -from acp import spawn_agent_process, text_block +from acp import PROTOCOL_VERSION, spawn_agent_process, text_block from acp.interfaces import Client @@ -110,11 +111,12 @@ class SimpleClient(Client): async def main() -> None: script = Path("examples/echo_agent.py") async with spawn_agent_process(SimpleClient(), sys.executable, str(script)) as (conn, _proc): - await conn.initialize(protocol_version=1) + await conn.initialize(protocol_version=PROTOCOL_VERSION) session = await conn.new_session(cwd=str(script.parent), mcp_servers=[]) await conn.prompt( session_id=session.session_id, prompt=[text_block("Hello from spawn!")], + message_id=str(uuid4()), ) asyncio.run(main()) @@ -133,9 +135,9 @@ from acp import Agent, PromptResponse class MyAgent(Agent): - async def prompt(self, prompt, session_id, **kwargs) -> PromptResponse: + async def prompt(self, prompt, session_id, message_id=None, **kwargs) -> PromptResponse: # inspect prompt, stream updates, then finish the turn - return PromptResponse(stop_reason="end_turn") + return PromptResponse(stop_reason="end_turn", user_message_id=message_id) ``` Run it with `run_agent()` inside an async entrypoint and wire it to your client. Refer to: @@ -143,7 +145,7 @@ Run it with `run_agent()` inside an async entrypoint and wire it to your client. - [`examples/echo_agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/echo_agent.py) for the smallest streaming agent - [`examples/agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/agent.py) for an implementation that negotiates capabilities and streams richer updates - [`examples/duet.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/duet.py) to see `spawn_agent_process` in action alongside the interactive client -- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--experimental-acp`) directly from Python +- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--acp`) directly from Python Need builders for common payloads? `acp.helpers` mirrors the Go/TS helper APIs: @@ -167,8 +169,8 @@ _Have the Gemini CLI installed? Run the bridge to exercise permission flows._ If you have the Gemini CLI installed and authenticated: ```bash -python examples/gemini.py --yolo # auto-approve permission prompts -python examples/gemini.py --sandbox --model gemini-1.5-pro +python examples/gemini.py --skip-trust --yolo # auto-approve permission prompts +python examples/gemini.py --skip-trust --sandbox --model gemini-1.5-pro ``` Environment helpers: diff --git a/examples/agent.py b/examples/agent.py index af9979e..6182580 100644 --- a/examples/agent.py +++ b/examples/agent.py @@ -65,7 +65,11 @@ async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateRespo return AuthenticateResponse() async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: logging.info("Received new session request") session_id = str(self._next_session_id) @@ -74,7 +78,12 @@ async def new_session( return NewSessionResponse(session_id=session_id, modes=None) async def load_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], session_id: str, **kwargs: Any + self, + cwd: str, + session_id: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> LoadSessionResponse | None: logging.info("Received load session request %s", session_id) self._sessions.add(session_id) @@ -94,6 +103,7 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, + message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: logging.info("Received prompt request for session %s", session_id) @@ -103,7 +113,7 @@ async def prompt( await self._send_agent_message(session_id, text_block("Client sent:")) for block in prompt: await self._send_agent_message(session_id, block) - return PromptResponse(stop_reason="end_turn") + return PromptResponse(stop_reason="end_turn", user_message_id=message_id) async def cancel(self, session_id: str, **kwargs: Any) -> None: logging.info("Received cancel notification for session %s", session_id) diff --git a/examples/client.py b/examples/client.py index 2abcc1a..138ab7f 100644 --- a/examples/client.py +++ b/examples/client.py @@ -6,6 +6,7 @@ import sys from pathlib import Path from typing import Any +from uuid import uuid4 from acp import ( PROTOCOL_VERSION, @@ -22,6 +23,7 @@ AudioContentBlock, AvailableCommandsUpdate, ClientCapabilities, + ConfigOptionUpdate, CreateTerminalResponse, CurrentModeUpdate, EmbeddedResourceContentBlock, @@ -34,11 +36,13 @@ ReleaseTerminalResponse, RequestPermissionResponse, ResourceContentBlock, + SessionInfoUpdate, TerminalOutputResponse, TextContentBlock, - ToolCall, ToolCallProgress, ToolCallStart, + ToolCallUpdate, + UsageUpdate, UserMessageChunk, WaitForTerminalExitResponse, WriteTextFileResponse, @@ -47,7 +51,7 @@ class ExampleClient(Client): async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCall, **kwargs: Any + self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any ) -> RequestPermissionResponse: raise RequestError.method_not_found("session/request_permission") @@ -99,7 +103,10 @@ async def session_update( | ToolCallProgress | AgentPlanUpdate | AvailableCommandsUpdate - | CurrentModeUpdate, + | CurrentModeUpdate + | ConfigOptionUpdate + | SessionInfoUpdate + | UsageUpdate, **kwargs: Any, ) -> None: if not isinstance(update, AgentMessageChunk): @@ -151,6 +158,7 @@ async def interactive_loop(conn: ClientSideConnection, session_id: str) -> None: await conn.prompt( session_id=session_id, prompt=[text_block(line)], + message_id=str(uuid4()), ) except Exception as exc: logging.error("Prompt failed: %s", exc) # noqa: TRY400 diff --git a/examples/echo_agent.py b/examples/echo_agent.py index 0f376fb..3eec09c 100644 --- a/examples/echo_agent.py +++ b/examples/echo_agent.py @@ -48,7 +48,11 @@ async def initialize( return InitializeResponse(protocol_version=protocol_version) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: return NewSessionResponse(session_id=uuid4().hex) @@ -62,6 +66,7 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, + message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: for block in prompt: @@ -71,7 +76,7 @@ async def prompt( chunk.content.field_meta = {"echo": True} await self._conn.session_update(session_id=session_id, update=chunk, source="echo_agent") - return PromptResponse(stop_reason="end_turn") + return PromptResponse(stop_reason="end_turn", user_message_id=message_id) async def main() -> None: diff --git a/examples/gemini.py b/examples/gemini.py index 60eed0a..bc824af 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -27,6 +27,7 @@ AllowedOutcome, AvailableCommandsUpdate, ClientCapabilities, + ConfigOptionUpdate, CreateTerminalResponse, CurrentModeUpdate, DeniedOutcome, @@ -40,12 +41,14 @@ ReleaseTerminalResponse, RequestPermissionResponse, ResourceContentBlock, + SessionInfoUpdate, TerminalOutputResponse, TerminalToolCallContent, TextContentBlock, - ToolCall, ToolCallProgress, ToolCallStart, + ToolCallUpdate, + UsageUpdate, UserMessageChunk, WaitForTerminalExitResponse, WriteTextFileResponse, @@ -59,7 +62,7 @@ def __init__(self, auto_approve: bool) -> None: self._auto_approve = auto_approve async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCall, **kwargs: Any + self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any ) -> RequestPermissionResponse: if self._auto_approve: option = _pick_preferred_option(options) @@ -122,7 +125,10 @@ async def session_update( # noqa: C901 | ToolCallProgress | AgentPlanUpdate | AvailableCommandsUpdate - | CurrentModeUpdate, + | CurrentModeUpdate + | ConfigOptionUpdate + | SessionInfoUpdate + | UsageUpdate, **kwargs: Any, ) -> None: if isinstance(update, AgentMessageChunk): @@ -227,7 +233,18 @@ def _print_text_content(content: object) -> None: print(text) -async def interactive_loop(conn: ClientSideConnection, session_id: str) -> None: +async def _send_prompt(conn: ClientSideConnection, session_id: str, prompt: str, timeout: float | None) -> None: + request = conn.prompt( + session_id=session_id, + prompt=[text_block(prompt)], + ) + if timeout is None: + await request + return + await asyncio.wait_for(request, timeout=timeout) + + +async def interactive_loop(conn: ClientSideConnection, session_id: str, prompt_timeout: float | None) -> None: print("Type a message and press Enter to send.") print("Commands: :cancel, :exit") @@ -248,10 +265,11 @@ async def interactive_loop(conn: ClientSideConnection, session_id: str) -> None: continue try: - await conn.prompt( - session_id=session_id, - prompt=[text_block(line)], - ) + await _send_prompt(conn, session_id, line, prompt_timeout) + except asyncio.TimeoutError: + print("prompt timed out waiting for final ACP response", file=sys.stderr) + with contextlib.suppress(Exception): + await asyncio.wait_for(conn.cancel(session_id=session_id), timeout=2) except RequestError as err: _print_request_error("prompt", err) except Exception as exc: @@ -274,10 +292,20 @@ async def run(argv: list[str]) -> int: # noqa: C901 parser = argparse.ArgumentParser(description="Interact with the Gemini CLI over ACP.") parser.add_argument("--gemini", help="Path to the Gemini CLI binary") parser.add_argument("--model", help="Model identifier to pass to Gemini") + parser.add_argument("--prompt", help="Send one prompt and exit") + parser.add_argument( + "--prompt-timeout", + type=float, + default=120.0, + help="Seconds to wait for session/prompt to finish; use 0 to disable", + ) parser.add_argument("--sandbox", action="store_true", help="Enable Gemini sandbox mode") parser.add_argument("--debug", action="store_true", help="Pass --debug to Gemini") + parser.add_argument("--experimental-acp", action="store_true", help="Use Gemini's deprecated ACP flag") + parser.add_argument("--skip-trust", action="store_true", help="Trust the current workspace for this session") parser.add_argument("--yolo", action="store_true", help="Auto-approve permission prompts") args = parser.parse_args(argv[1:]) + prompt_timeout = None if args.prompt_timeout == 0 else args.prompt_timeout try: gemini_path = _resolve_gemini_cli(args.gemini) @@ -285,13 +313,15 @@ async def run(argv: list[str]) -> int: # noqa: C901 print(exc, file=sys.stderr) return 1 - cmd = [gemini_path, "--experimental-acp"] + cmd = [gemini_path, "--experimental-acp" if args.experimental_acp else "--acp"] if args.model: cmd += ["--model", args.model] if args.sandbox: cmd.append("--sandbox") if args.debug: cmd.append("--debug") + if args.skip_trust: + cmd.append("--skip-trust") try: proc = await asyncio.create_subprocess_exec( @@ -350,7 +380,15 @@ async def run(argv: list[str]) -> int: # noqa: C901 print(f"📝 Created session: {session.session_id}") try: - await interactive_loop(conn, session.session_id) + if args.prompt is None: + await interactive_loop(conn, session.session_id, prompt_timeout) + else: + await _send_prompt(conn, session.session_id, args.prompt, prompt_timeout) + except asyncio.TimeoutError: + print("prompt timed out waiting for final ACP response", file=sys.stderr) + with contextlib.suppress(Exception): + await asyncio.wait_for(conn.cancel(session_id=session.session_id), timeout=2) + return 1 finally: await _shutdown(proc, conn) @@ -373,14 +411,15 @@ def _print_request_error(stage: str, err: RequestError) -> None: async def _shutdown(proc: asyncio.subprocess.Process, conn: ClientSideConnection) -> None: with contextlib.suppress(Exception): - await conn.close() + await asyncio.wait_for(conn.close(), timeout=2) if proc.returncode is None: proc.terminate() try: await asyncio.wait_for(proc.wait(), timeout=5) except asyncio.TimeoutError: proc.kill() - await proc.wait() + with contextlib.suppress(Exception): + await asyncio.wait_for(proc.wait(), timeout=5) def main(argv: list[str] | None = None) -> int: diff --git a/pyproject.toml b/pyproject.toml index 036b8fb..e8eb93d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.9.0" +version = "0.10.0" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/schema/VERSION b/schema/VERSION index 62d2bd0..f1d3366 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.11.2 +refs/tags/v0.12.2 diff --git a/schema/meta.json b/schema/meta.json index bfa8448..6d1dd24 100644 --- a/schema/meta.json +++ b/schema/meta.json @@ -1,7 +1,21 @@ { "agentMethods": { "authenticate": "authenticate", + "document_did_change": "document/didChange", + "document_did_close": "document/didClose", + "document_did_focus": "document/didFocus", + "document_did_open": "document/didOpen", + "document_did_save": "document/didSave", "initialize": "initialize", + "logout": "logout", + "nes_accept": "nes/accept", + "nes_close": "nes/close", + "nes_reject": "nes/reject", + "nes_start": "nes/start", + "nes_suggest": "nes/suggest", + "providers_disable": "providers/disable", + "providers_list": "providers/list", + "providers_set": "providers/set", "session_cancel": "session/cancel", "session_close": "session/close", "session_fork": "session/fork", @@ -15,6 +29,8 @@ "session_set_model": "session/set_model" }, "clientMethods": { + "elicitation_complete": "elicitation/complete", + "elicitation_create": "elicitation/create", "fs_read_text_file": "fs/read_text_file", "fs_write_text_file": "fs/write_text_file", "session_request_permission": "session/request_permission", diff --git a/schema/schema.json b/schema/schema.json index f679c1a..709a0d9 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -1,5 +1,62 @@ { "$defs": { + "AcceptNesNotification": { + "description": "Notification sent when a suggestion is accepted.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "The ID of the accepted suggestion.", + "type": "string" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this notification." + } + }, + "required": [ + "sessionId", + "id" + ], + "type": "object", + "x-method": "nes/accept", + "x-side": "agent" + }, + "AgentAuthCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "logout": { + "anyOf": [ + { + "$ref": "#/$defs/LogoutCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." + } + }, + "type": "object" + }, "AgentCapabilities": { "description": "Capabilities supported by the agent.\n\nAdvertised during initialization to inform the client about\navailable features and content types.\n\nSee protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)", "properties": { @@ -11,6 +68,15 @@ "null" ] }, + "auth": { + "allOf": [ + { + "$ref": "#/$defs/AgentAuthCapabilities" + } + ], + "default": {}, + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent." + }, "loadSession": { "default": false, "description": "Whether the agent supports `session/load`.", @@ -28,6 +94,28 @@ }, "description": "MCP capabilities supported by the agent." }, + "nes": { + "anyOf": [ + { + "$ref": "#/$defs/NesCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." + }, + "positionEncoding": { + "anyOf": [ + { + "$ref": "#/$defs/PositionEncodingKind" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings." + }, "promptCapabilities": { "allOf": [ { @@ -41,6 +129,17 @@ }, "description": "Prompt capabilities supported by the agent." }, + "providers": { + "anyOf": [ + { + "$ref": "#/$defs/ProvidersCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." + }, "sessionCapabilities": { "allOf": [ { @@ -70,6 +169,15 @@ "description": "Handles session update notifications from the agent.\n\nThis is a notification endpoint (no response expected) that receives\nreal-time updates about session progress, including message chunks,\ntool calls, and execution plans.\n\nNote: Clients SHOULD continue accepting tool call updates even after\nsending a `session/cancel` notification, as the agent may send final\nupdates before responding with the cancelled stop reason.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", "title": "SessionNotification" }, + { + "allOf": [ + { + "$ref": "#/$defs/CompleteElicitationNotification" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification that a URL-based elicitation has completed.", + "title": "CompleteElicitationNotification" + }, { "allOf": [ { @@ -178,6 +286,15 @@ "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: Call `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "title": "KillTerminalRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/CreateElicitationRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests structured user input via a form or URL.", + "title": "CreateElicitationRequest" + }, { "allOf": [ { @@ -228,6 +345,38 @@ ], "title": "AuthenticateResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/ListProvidersResponse" + } + ], + "title": "ListProvidersResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SetProvidersResponse" + } + ], + "title": "SetProvidersResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DisableProvidersResponse" + } + ], + "title": "DisableProvidersResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/LogoutResponse" + } + ], + "title": "LogoutResponse" + }, { "allOf": [ { @@ -308,6 +457,30 @@ ], "title": "SetSessionModelResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/StartNesResponse" + } + ], + "title": "StartNesResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SuggestNesResponse" + } + ], + "title": "SuggestNesResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/CloseNesResponse" + } + ], + "title": "CloseNesResponse" + }, { "allOf": [ { @@ -795,6 +968,33 @@ ], "type": "object" }, + "BooleanPropertySchema": { + "description": "Schema for boolean properties in an elicitation form.", + "properties": { + "default": { + "description": "Default value.", + "type": [ + "boolean", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, "CancelNotification": { "description": "Notification to cancel ongoing operations for a session.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", "properties": { @@ -871,6 +1071,17 @@ }, "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." }, + "elicitation": { + "anyOf": [ + { + "$ref": "#/$defs/ElicitationCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + }, "fs": { "allOf": [ { @@ -883,6 +1094,24 @@ }, "description": "File system capabilities supported by the client.\nDetermines which file operations the agent can request." }, + "nes": { + "anyOf": [ + { + "$ref": "#/$defs/ClientNesCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + }, + "positionEncodings": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", + "items": { + "$ref": "#/$defs/PositionEncodingKind" + }, + "type": "array" + }, "terminal": { "default": false, "description": "Whether the Client support all `terminal/*` methods.", @@ -891,6 +1120,53 @@ }, "type": "object" }, + "ClientNesCapabilities": { + "description": "NES capabilities advertised by the client during initialization.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "jump": { + "anyOf": [ + { + "$ref": "#/$defs/NesJumpCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the client supports the `jump` suggestion kind." + }, + "rename": { + "anyOf": [ + { + "$ref": "#/$defs/NesRenameCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the client supports the `rename` suggestion kind." + }, + "searchAndReplace": { + "anyOf": [ + { + "$ref": "#/$defs/NesSearchAndReplaceCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the client supports the `searchAndReplace` suggestion kind." + } + }, + "type": "object" + }, "ClientNotification": { "properties": { "method": { @@ -909,6 +1185,69 @@ "description": "Cancels ongoing operations for a session.\n\nThis is a notification sent by the client to cancel an ongoing prompt turn.\n\nUpon receiving this notification, the Agent SHOULD:\n- Stop all language model requests as soon as possible\n- Abort all tool call invocations in progress\n- Send any pending `session/update` notifications\n- Respond to the original `session/prompt` request with `StopReason::Cancelled`\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", "title": "CancelNotification" }, + { + "allOf": [ + { + "$ref": "#/$defs/DidOpenDocumentNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a file is opened in the editor.", + "title": "DidOpenDocumentNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DidChangeDocumentNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a file is edited.", + "title": "DidChangeDocumentNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DidCloseDocumentNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a file is closed.", + "title": "DidCloseDocumentNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DidSaveDocumentNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a file is saved.", + "title": "DidSaveDocumentNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DidFocusDocumentNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a file becomes the active editor tab.", + "title": "DidFocusDocumentNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/AcceptNesNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a suggestion is accepted.", + "title": "AcceptNesNotification" + }, + { + "allOf": [ + { + "$ref": "#/$defs/RejectNesNotification" + } + ], + "description": "**UNSTABLE**\n\nNotification sent when a suggestion is rejected.", + "title": "RejectNesNotification" + }, { "allOf": [ { @@ -966,28 +1305,64 @@ { "allOf": [ { - "$ref": "#/$defs/NewSessionRequest" + "$ref": "#/$defs/ListProvidersRequest" } ], - "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)", - "title": "NewSessionRequest" + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists providers that can be configured by the client.", + "title": "ListProvidersRequest" }, { "allOf": [ { - "$ref": "#/$defs/LoadSessionRequest" + "$ref": "#/$defs/SetProvidersRequest" } ], - "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", - "title": "LoadSessionRequest" + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReplaces the configuration for a provider.", + "title": "SetProvidersRequest" }, { "allOf": [ { - "$ref": "#/$defs/ListSessionsRequest" + "$ref": "#/$defs/DisableProvidersRequest" } ], - "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDisables a provider.", + "title": "DisableProvidersRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/LogoutRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLogs out of the current authenticated state.\n\nAfter a successful logout, all new sessions will require authentication.\nThere is no guarantee about the behavior of already running sessions.", + "title": "LogoutRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/NewSessionRequest" + } + ], + "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)", + "title": "NewSessionRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/LoadSessionRequest" + } + ], + "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "title": "LoadSessionRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ListSessionsRequest" + } + ], + "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", "title": "ListSessionsRequest" }, { @@ -1005,7 +1380,7 @@ "$ref": "#/$defs/ResumeSessionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `session.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", + "description": "Resumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `sessionCapabilities.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", "title": "ResumeSessionRequest" }, { @@ -1014,7 +1389,7 @@ "$ref": "#/$defs/CloseSessionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active session and frees up any resources associated with it.\n\nThis method is only available if the agent advertises the `session.close` capability.\n\nThe agent must cancel any ongoing work (as if `session/cancel` was called)\nand then free up any resources associated with the session.", + "description": "Closes an active session and frees up any resources associated with it.\n\nThis method is only available if the agent advertises the `sessionCapabilities.close` capability.\n\nThe agent must cancel any ongoing work (as if `session/cancel` was called)\nand then free up any resources associated with the session.", "title": "CloseSessionRequest" }, { @@ -1053,6 +1428,33 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSelect a model for a given session.", "title": "SetSessionModelRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/StartNesRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nStarts an NES session.", + "title": "StartNesRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SuggestNesRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests a code suggestion.", + "title": "SuggestNesRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/CloseNesRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active NES session and frees up any resources associated with it.\n\nThe agent must cancel any ongoing work and then free up any resources\nassociated with the NES session.", + "title": "CloseNesRequest" + }, { "allOf": [ { @@ -1151,6 +1553,14 @@ ], "title": "KillTerminalResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/CreateElicitationResponse" + } + ], + "title": "CreateElicitationResponse" + }, { "allOf": [ { @@ -1189,8 +1599,51 @@ ], "x-docs-ignore": true }, + "CloseNesRequest": { + "description": "Request to close an NES session.\n\nThe agent **must** cancel any ongoing work related to the NES session\nand then free up any resources associated with the session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the NES session to close." + } + }, + "required": [ + "sessionId" + ], + "type": "object", + "x-method": "nes/close", + "x-side": "agent" + }, + "CloseNesResponse": { + "description": "Response from closing an NES session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "nes/close", + "x-side": "agent" + }, "CloseSessionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for closing an active session.\n\nIf supported, the agent **must** cancel any ongoing work related to the session\n(treat it as if `session/cancel` was called) and then free up any resources\nassociated with the session.\n\nOnly available if the Agent supports the `session.close` capability.", + "description": "Request parameters for closing an active session.\n\nIf supported, the agent **must** cancel any ongoing work related to the session\n(treat it as if `session/cancel` was called) and then free up any resources\nassociated with the session.\n\nOnly available if the Agent supports the `sessionCapabilities.close` capability.", "properties": { "_meta": { "additionalProperties": true, @@ -1217,7 +1670,7 @@ "x-side": "agent" }, "CloseSessionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from closing a session.", + "description": "Response from closing a session.", "properties": { "_meta": { "additionalProperties": true, @@ -1232,6 +1685,33 @@ "x-method": "session/close", "x-side": "agent" }, + "CompleteElicitationNotification": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification sent by the agent when a URL-based elicitation is complete.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "elicitationId": { + "allOf": [ + { + "$ref": "#/$defs/ElicitationId" + } + ], + "description": "The ID of the elicitation that completed." + } + }, + "required": [ + "elicitationId" + ], + "type": "object", + "x-method": "elicitation/complete", + "x-side": "client" + }, "ConfigOptionUpdate": { "description": "Session configuration options have been updated.", "properties": { @@ -1430,6 +1910,135 @@ ], "type": "object" }, + "CreateElicitationRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest from the agent to elicit structured user input.\n\nThe agent sends this to the client to request information from the user,\neither via a form or by directing them to a URL.\nElicitations are tied to a session (optionally a tool call) or a request.", + "discriminator": { + "propertyName": "mode" + }, + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/ElicitationFormMode" + } + ], + "description": "Form-based elicitation where the client renders a form from the provided schema.", + "properties": { + "mode": { + "const": "form", + "type": "string" + } + }, + "required": [ + "mode" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ElicitationUrlMode" + } + ], + "description": "URL-based elicitation where the client directs the user to a URL.", + "properties": { + "mode": { + "const": "url", + "type": "string" + } + }, + "required": [ + "mode" + ], + "type": "object" + } + ], + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "message": { + "description": "A human-readable message describing what input is needed.", + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object", + "x-method": "elicitation/create", + "x-side": "client" + }, + "CreateElicitationResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from the client to an elicitation request.", + "discriminator": { + "propertyName": "action" + }, + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/ElicitationAcceptAction" + } + ], + "description": "The user accepted and provided content.", + "properties": { + "action": { + "const": "accept", + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "description": "The user declined the elicitation.", + "properties": { + "action": { + "const": "decline", + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + { + "description": "The elicitation was cancelled.", + "properties": { + "action": { + "const": "cancel", + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + } + ], + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "elicitation/create", + "x-side": "client" + }, "CreateTerminalRequest": { "description": "Request to create a new terminal and execute a command.", "properties": { @@ -1540,8 +2149,8 @@ ], "type": "object" }, - "Diff": { - "description": "A diff representing file modifications.\n\nShows changes to files in a format suitable for display in the client UI.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", + "DidChangeDocumentNotification": { + "description": "Notification sent when a file is edited.", "properties": { "_meta": { "additionalProperties": true, @@ -1551,30 +2160,43 @@ "null" ] }, - "newText": { - "description": "The new content after modification.", - "type": "string" + "contentChanges": { + "description": "The content changes.", + "items": { + "$ref": "#/$defs/TextDocumentContentChangeEvent" + }, + "type": "array" }, - "oldText": { - "description": "The original content (None for new files).", - "type": [ - "string", - "null" - ] + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this notification." }, - "path": { - "description": "The file path being modified.", + "uri": { + "description": "The URI of the changed document.", "type": "string" + }, + "version": { + "description": "The new version number of the document.", + "format": "int64", + "type": "integer" } }, "required": [ - "path", - "newText" + "sessionId", + "uri", + "version", + "contentChanges" ], - "type": "object" + "type": "object", + "x-method": "document/didChange", + "x-side": "agent" }, - "EmbeddedResource": { - "description": "The contents of a resource, embedded into a prompt or tool call result.", + "DidCloseDocumentNotification": { + "description": "Notification sent when a file is closed.", "properties": { "_meta": { "additionalProperties": true, @@ -1584,48 +2206,85 @@ "null" ] }, - "annotations": { - "anyOf": [ - { - "$ref": "#/$defs/Annotations" - }, + "sessionId": { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionId" } - ] + ], + "description": "The session ID for this notification." }, - "resource": { - "$ref": "#/$defs/EmbeddedResourceResource" + "uri": { + "description": "The URI of the closed document.", + "type": "string" } }, "required": [ - "resource" + "sessionId", + "uri" ], - "type": "object" + "type": "object", + "x-method": "document/didClose", + "x-side": "agent" }, - "EmbeddedResourceResource": { - "anyOf": [ - { + "DidFocusDocumentNotification": { + "description": "Notification sent when a file becomes the active editor tab.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "position": { "allOf": [ { - "$ref": "#/$defs/TextResourceContents" + "$ref": "#/$defs/Position" } ], - "title": "TextResourceContents" + "description": "The current cursor position." }, - { + "sessionId": { "allOf": [ { - "$ref": "#/$defs/BlobResourceContents" + "$ref": "#/$defs/SessionId" } ], - "title": "BlobResourceContents" + "description": "The session ID for this notification." + }, + "uri": { + "description": "The URI of the focused document.", + "type": "string" + }, + "version": { + "description": "The version number of the document.", + "format": "int64", + "type": "integer" + }, + "visibleRange": { + "allOf": [ + { + "$ref": "#/$defs/Range" + } + ], + "description": "The portion of the file currently visible in the editor viewport." } + }, + "required": [ + "sessionId", + "uri", + "version", + "position", + "visibleRange" ], - "description": "Resource content that can be embedded in a message." + "type": "object", + "x-method": "document/didFocus", + "x-side": "agent" }, - "EnvVariable": { - "description": "An environment variable to set when launching an MCP server.", + "DidOpenDocumentNotification": { + "description": "Notification sent when a file is opened in the editor.", "properties": { "_meta": { "additionalProperties": true, @@ -1635,124 +2294,77 @@ "null" ] }, - "name": { - "description": "The name of the environment variable.", + "languageId": { + "description": "The language identifier of the document (e.g., \"rust\", \"python\").", "type": "string" }, - "value": { - "description": "The value to set for the environment variable.", + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this notification." + }, + "text": { + "description": "The full text content of the document.", "type": "string" + }, + "uri": { + "description": "The URI of the opened document.", + "type": "string" + }, + "version": { + "description": "The version number of the document.", + "format": "int64", + "type": "integer" } }, "required": [ - "name", - "value" + "sessionId", + "uri", + "languageId", + "version", + "text" ], - "type": "object" + "type": "object", + "x-method": "document/didOpen", + "x-side": "agent" }, - "Error": { - "description": "JSON-RPC error object.\n\nRepresents an error that occurred during method execution, following the\nJSON-RPC 2.0 error object specification with optional additional data.\n\nSee protocol docs: [JSON-RPC Error Object](https://www.jsonrpc.org/specification#error_object)", + "DidSaveDocumentNotification": { + "description": "Notification sent when a file is saved.", "properties": { - "code": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { "allOf": [ { - "$ref": "#/$defs/ErrorCode" + "$ref": "#/$defs/SessionId" } ], - "description": "A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." - }, - "data": { - "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." + "description": "The session ID for this notification." }, - "message": { - "description": "A string providing a short description of the error.\nThe message should be limited to a concise single sentence.", + "uri": { + "description": "The URI of the saved document.", "type": "string" } }, "required": [ - "code", - "message" - ], - "type": "object" - }, - "ErrorCode": { - "anyOf": [ - { - "const": -32700, - "description": "**Parse error**: Invalid JSON was received by the server.\nAn error occurred on the server while parsing the JSON text.", - "format": "int32", - "title": "Parse error", - "type": "integer" - }, - { - "const": -32600, - "description": "**Invalid request**: The JSON sent is not a valid Request object.", - "format": "int32", - "title": "Invalid request", - "type": "integer" - }, - { - "const": -32601, - "description": "**Method not found**: The method does not exist or is not available.", - "format": "int32", - "title": "Method not found", - "type": "integer" - }, - { - "const": -32602, - "description": "**Invalid params**: Invalid method parameter(s).", - "format": "int32", - "title": "Invalid params", - "type": "integer" - }, - { - "const": -32603, - "description": "**Internal error**: Internal JSON-RPC error.\nReserved for implementation-defined server errors.", - "format": "int32", - "title": "Internal error", - "type": "integer" - }, - { - "const": -32800, - "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", - "format": "int32", - "title": "Request cancelled", - "type": "integer" - }, - { - "const": -32000, - "description": "**Authentication required**: Authentication is required before this operation can be performed.", - "format": "int32", - "title": "Authentication required", - "type": "integer" - }, - { - "const": -32002, - "description": "**Resource not found**: A given resource, such as a file, was not found.", - "format": "int32", - "title": "Resource not found", - "type": "integer" - }, - { - "description": "Other undefined error code.", - "format": "int32", - "title": "Other", - "type": "integer" - } + "sessionId", + "uri" ], - "description": "Predefined error codes for common JSON-RPC and ACP-specific errors.\n\nThese codes follow the JSON-RPC 2.0 specification for standard errors\nand use the reserved range (-32000 to -32099) for protocol-specific errors." - }, - "ExtNotification": { - "description": "Allows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" - }, - "ExtRequest": { - "description": "Allows for sending an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" - }, - "ExtResponse": { - "description": "Allows for sending an arbitrary response to an [`ExtRequest`] that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + "type": "object", + "x-method": "document/didSave", + "x-side": "agent" }, - "FileSystemCapabilities": { - "description": "File system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", + "Diff": { + "description": "A diff representing file modifications.\n\nShows changes to files in a format suitable for display in the client UI.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", "properties": { "_meta": { "additionalProperties": true, @@ -1762,21 +2374,30 @@ "null" ] }, - "readTextFile": { - "default": false, - "description": "Whether the Client supports `fs/read_text_file` requests.", - "type": "boolean" + "newText": { + "description": "The new content after modification.", + "type": "string" }, - "writeTextFile": { - "default": false, - "description": "Whether the Client supports `fs/write_text_file` requests.", - "type": "boolean" + "oldText": { + "description": "The original content (None for new files).", + "type": [ + "string", + "null" + ] + }, + "path": { + "description": "The file path being modified.", + "type": "string" } }, + "required": [ + "path", + "newText" + ], "type": "object" }, - "ForkSessionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for forking an existing session.\n\nCreates a new session based on the context of an existing one, allowing\noperations like generating summaries without affecting the original session's history.\n\nOnly available if the Agent supports the `session.fork` capability.", + "DisableProvidersRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/disable`.", "properties": { "_meta": { "additionalProperties": true, @@ -1786,36 +2407,20 @@ "null" ] }, - "cwd": { - "description": "The working directory for this session.", + "id": { + "description": "Provider id to disable.", "type": "string" - }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", - "items": { - "$ref": "#/$defs/McpServer" - }, - "type": "array" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session to fork." } }, "required": [ - "sessionId", - "cwd" + "id" ], "type": "object", - "x-method": "session/fork", + "x-method": "providers/disable", "x-side": "agent" }, - "ForkSessionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from forking an existing session.", + "DisableProvidersResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/disable`.", "properties": { "_meta": { "additionalProperties": true, @@ -1824,83 +2429,30 @@ "object", "null" ] - }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" + } + }, + "type": "object", + "x-method": "providers/disable", + "x-side": "agent" + }, + "ElicitationAcceptAction": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe user accepted the elicitation and provided content.", + "properties": { + "content": { + "additionalProperties": { + "$ref": "#/$defs/ElicitationContentValue" }, + "description": "The user-provided content, if any, as an object matching the requested schema.", "type": [ - "array", + "object", "null" ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, - { - "type": "null" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" - }, - "modes": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModeState" - }, - { - "type": "null" - } - ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "Unique identifier for the newly created forked session." - } - }, - "required": [ - "sessionId" - ], - "type": "object", - "x-method": "session/fork", - "x-side": "agent" - }, - "HttpHeader": { - "description": "An HTTP header to set when making requests to the MCP server.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "name": { - "description": "The name of the HTTP header.", - "type": "string" - }, - "value": { - "description": "The value to set for the HTTP header.", - "type": "string" } }, - "required": [ - "name", - "value" - ], "type": "object" }, - "ImageContent": { - "description": "An image provided to or from an LLM.", + "ElicitationCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.", "properties": { "_meta": { "additionalProperties": true, @@ -1910,70 +2462,62 @@ "null" ] }, - "annotations": { + "form": { "anyOf": [ { - "$ref": "#/$defs/Annotations" + "$ref": "#/$defs/ElicitationFormCapabilities" }, { "type": "null" } - ] - }, - "data": { - "type": "string" - }, - "mimeType": { - "type": "string" + ], + "description": "Whether the client supports form-based elicitation." }, - "uri": { - "type": [ - "string", - "null" - ] + "url": { + "anyOf": [ + { + "$ref": "#/$defs/ElicitationUrlCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the client supports URL-based elicitation." } }, - "required": [ - "data", - "mimeType" - ], "type": "object" }, - "Implementation": { - "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an MCP implementation, with an optional\ntitle for UI representation.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "name": { - "description": "Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn\u2019t present.", + "ElicitationContentValue": { + "anyOf": [ + { + "title": "String", "type": "string" }, - "title": { - "description": "Intended for UI and end-user contexts \u2014 optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display.", - "type": [ - "string", - "null" - ] + { + "format": "int64", + "title": "Integer", + "type": "integer" }, - "version": { - "description": "Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. \"1.0.0\").", - "type": "string" + { + "format": "double", + "title": "Number", + "type": "number" + }, + { + "title": "Boolean", + "type": "boolean" + }, + { + "items": { + "type": "string" + }, + "title": "StringArray", + "type": "array" } - }, - "required": [ - "name", - "version" - ], - "type": "object" + ] }, - "InitializeRequest": { - "description": "Request parameters for the initialize method.\n\nSent by the client to establish connection and negotiate capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "ElicitationFormCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation capabilities.", "properties": { "_meta": { "additionalProperties": true, @@ -1982,232 +2526,263 @@ "object", "null" ] - }, - "clientCapabilities": { + } + }, + "type": "object" + }, + "ElicitationFormMode": { + "anyOf": [ + { "allOf": [ { - "$ref": "#/$defs/ClientCapabilities" + "$ref": "#/$defs/ElicitationSessionScope" } ], - "default": { - "auth": { - "terminal": false - }, - "fs": { - "readTextFile": false, - "writeTextFile": false - }, - "terminal": false - }, - "description": "Capabilities supported by the client." + "description": "Tied to a session, optionally to a specific tool call within that session.", + "title": "Session" }, - "clientInfo": { - "anyOf": [ - { - "$ref": "#/$defs/Implementation" - }, + { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/ElicitationRequestScope" } ], - "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required." - }, - "protocolVersion": { + "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", + "title": "Request" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema.", + "properties": { + "requestedSchema": { "allOf": [ { - "$ref": "#/$defs/ProtocolVersion" + "$ref": "#/$defs/ElicitationSchema" } ], - "description": "The latest protocol version supported by the client." + "description": "A JSON Schema describing the form fields to present to the user." } }, "required": [ - "protocolVersion" + "requestedSchema" ], - "type": "object", - "x-method": "initialize", - "x-side": "agent" + "type": "object" }, - "InitializeResponse": { - "description": "Response to the `initialize` method.\n\nContains the negotiated protocol version and agent capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "agentCapabilities": { + "ElicitationId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an elicitation.", + "type": "string" + }, + "ElicitationPropertySchema": { + "description": "Property schema for elicitation form fields.\n\nEach variant corresponds to a JSON Schema `\"type\"` value.\nSingle-select enums use the `String` variant with `enum` or `oneOf` set.\nMulti-select enums use the `Array` variant.", + "discriminator": { + "propertyName": "type" + }, + "oneOf": [ + { "allOf": [ { - "$ref": "#/$defs/AgentCapabilities" + "$ref": "#/$defs/StringPropertySchema" } ], - "default": { - "loadSession": false, - "mcpCapabilities": { - "http": false, - "sse": false - }, - "promptCapabilities": { - "audio": false, - "embeddedContext": false, - "image": false - }, - "sessionCapabilities": {} + "description": "String property (or single-select enum when `enum`/`oneOf` is set).", + "properties": { + "type": { + "const": "string", + "type": "string" + } }, - "description": "Capabilities supported by the agent." + "required": [ + "type" + ], + "type": "object" }, - "agentInfo": { - "anyOf": [ - { - "$ref": "#/$defs/Implementation" - }, + { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/NumberPropertySchema" } ], - "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required." + "description": "Number (floating-point) property.", + "properties": { + "type": { + "const": "number", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" }, - "authMethods": { - "default": [], - "description": "Authentication methods supported by the agent.", - "items": { - "$ref": "#/$defs/AuthMethod" + { + "allOf": [ + { + "$ref": "#/$defs/IntegerPropertySchema" + } + ], + "description": "Integer property.", + "properties": { + "type": { + "const": "integer", + "type": "string" + } }, - "type": "array" + "required": [ + "type" + ], + "type": "object" }, - "protocolVersion": { + { "allOf": [ { - "$ref": "#/$defs/ProtocolVersion" + "$ref": "#/$defs/BooleanPropertySchema" } ], - "description": "The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version." - } - }, - "required": [ - "protocolVersion" - ], - "type": "object", - "x-method": "initialize", - "x-side": "agent" - }, - "KillTerminalRequest": { - "description": "Request to kill a terminal without releasing it.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "description": "Boolean property.", + "properties": { + "type": { + "const": "boolean", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" }, - "sessionId": { + { "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/MultiSelectPropertySchema" } ], - "description": "The session ID for this request." - }, - "terminalId": { - "description": "The ID of the terminal to kill.", - "type": "string" + "description": "Multi-select array property.", + "properties": { + "type": { + "const": "array", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" } - }, - "required": [ - "sessionId", - "terminalId" - ], - "type": "object", - "x-method": "terminal/kill", - "x-side": "client" + ] }, - "KillTerminalResponse": { - "description": "Response to `terminal/kill` method", + "ElicitationRequestScope": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest-scoped elicitation, tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "requestId": { + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ], + "description": "The request this elicitation is tied to." } }, - "type": "object", - "x-method": "terminal/kill", - "x-side": "client" + "required": [ + "requestId" + ], + "type": "object" }, - "ListSessionsRequest": { - "description": "Request parameters for listing existing sessions.\n\nOnly available if the Agent supports the `sessionCapabilities.list` capability.", + "ElicitationSchema": { + "description": "Type-safe elicitation schema for requesting structured user input.\n\nThis represents a JSON Schema object with primitive-typed properties,\nas required by the elicitation specification.", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "description": { + "description": "Optional description of what this schema represents.", "type": [ - "object", + "string", "null" ] }, - "cursor": { - "description": "Opaque cursor token from a previous response's nextCursor field for cursor-based pagination", + "properties": { + "additionalProperties": { + "$ref": "#/$defs/ElicitationPropertySchema" + }, + "default": {}, + "description": "Property definitions (must be primitive types).", + "type": "object" + }, + "required": { + "description": "List of required property names.", + "items": { + "type": "string" + }, "type": [ - "string", + "array", "null" ] }, - "cwd": { - "description": "Filter sessions by working directory. Must be an absolute path.", + "title": { + "description": "Optional title for the schema.", "type": [ "string", "null" ] + }, + "type": { + "allOf": [ + { + "$ref": "#/$defs/ElicitationSchemaType" + } + ], + "default": "object", + "description": "Type discriminator. Always `\"object\"`." } }, - "type": "object", - "x-method": "session/list", - "x-side": "agent" + "type": "object" }, - "ListSessionsResponse": { - "description": "Response from listing sessions.", + "ElicitationSchemaType": { + "description": "Type discriminator for elicitation schemas.", + "oneOf": [ + { + "const": "object", + "description": "Object schema type.", + "type": "string" + } + ] + }, + "ElicitationSessionScope": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-scoped elicitation, optionally tied to a specific tool call.\n\nWhen `tool_call_id` is set, the elicitation is tied to a specific tool call.\nThis is useful when an agent receives an elicitation from an MCP server\nduring a tool call and needs to redirect it to the user.", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "nextCursor": { - "description": "Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", - "type": [ - "string", - "null" - ] + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session this elicitation is tied to." }, - "sessions": { - "description": "Array of session information objects", - "items": { - "$ref": "#/$defs/SessionInfo" - }, - "type": "array" + "toolCallId": { + "anyOf": [ + { + "$ref": "#/$defs/ToolCallId" + }, + { + "type": "null" + } + ], + "description": "Optional tool call within the session." } }, "required": [ - "sessions" + "sessionId" ], - "type": "object", - "x-method": "session/list", - "x-side": "agent" + "type": "object" }, - "LoadSessionRequest": { - "description": "Request parameters for loading an existing session.\n\nOnly available if the Agent supports the `loadSession` capability.\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "ElicitationStringType": { + "description": "Items definition for untitled multi-select enum properties.", + "oneOf": [ + { + "const": "string", + "description": "String schema type.", + "type": "string" + } + ] + }, + "ElicitationUrlCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation capabilities.", "properties": { "_meta": { "additionalProperties": true, @@ -2216,38 +2791,55 @@ "object", "null" ] + } + }, + "type": "object" + }, + "ElicitationUrlMode": { + "anyOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/ElicitationSessionScope" + } + ], + "description": "Tied to a session, optionally to a specific tool call within that session.", + "title": "Session" }, - "cwd": { - "description": "The working directory for this session.", - "type": "string" - }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", - "items": { - "$ref": "#/$defs/McpServer" - }, - "type": "array" - }, - "sessionId": { + { "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/ElicitationRequestScope" } ], - "description": "The ID of the session to load." + "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", + "title": "Request" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL.", + "properties": { + "elicitationId": { + "allOf": [ + { + "$ref": "#/$defs/ElicitationId" + } + ], + "description": "The unique identifier for this elicitation." + }, + "url": { + "description": "The URL to direct the user to.", + "format": "uri", + "type": "string" } }, "required": [ - "mcpServers", - "cwd", - "sessionId" + "elicitationId", + "url" ], - "type": "object", - "x-method": "session/load", - "x-side": "agent" + "type": "object" }, - "LoadSessionResponse": { - "description": "Response from loading an existing session.", + "EmbeddedResource": { + "description": "The contents of a resource, embedded into a prompt or tool call result.", "properties": { "_meta": { "additionalProperties": true, @@ -2257,45 +2849,66 @@ "null" ] }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, - "type": [ - "array", - "null" - ] - }, - "models": { + "annotations": { "anyOf": [ { - "$ref": "#/$defs/SessionModelState" + "$ref": "#/$defs/Annotations" }, { "type": "null" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + ] }, - "modes": { - "anyOf": [ + "resource": { + "$ref": "#/$defs/EmbeddedResourceResource" + } + }, + "required": [ + "resource" + ], + "type": "object" + }, + "EmbeddedResourceResource": { + "anyOf": [ + { + "allOf": [ { - "$ref": "#/$defs/SessionModeState" - }, + "$ref": "#/$defs/TextResourceContents" + } + ], + "title": "TextResourceContents" + }, + { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/BlobResourceContents" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "title": "BlobResourceContents" } - }, - "type": "object", - "x-method": "session/load", - "x-side": "agent" + ], + "description": "Resource content that can be embedded in a message." }, - "McpCapabilities": { - "description": "MCP capabilities supported by the agent", + "EnumOption": { + "description": "A titled enum option with a const value and human-readable title.", + "properties": { + "const": { + "description": "The constant value for this option.", + "type": "string" + }, + "title": { + "description": "Human-readable title for this option.", + "type": "string" + } + }, + "required": [ + "const", + "title" + ], + "type": "object" + }, + "EnvVariable": { + "description": "An environment variable to set when launching an MCP server.", "properties": { "_meta": { "additionalProperties": true, @@ -2305,71 +2918,131 @@ "null" ] }, - "http": { - "default": false, - "description": "Agent supports [`McpServer::Http`].", - "type": "boolean" + "name": { + "description": "The name of the environment variable.", + "type": "string" }, - "sse": { - "default": false, - "description": "Agent supports [`McpServer::Sse`].", - "type": "boolean" + "value": { + "description": "The value to set for the environment variable.", + "type": "string" } }, + "required": [ + "name", + "value" + ], "type": "object" }, - "McpServer": { - "anyOf": [ - { + "Error": { + "description": "JSON-RPC error object.\n\nRepresents an error that occurred during method execution, following the\nJSON-RPC 2.0 error object specification with optional additional data.\n\nSee protocol docs: [JSON-RPC Error Object](https://www.jsonrpc.org/specification#error_object)", + "properties": { + "code": { "allOf": [ { - "$ref": "#/$defs/McpServerHttp" - } - ], - "description": "HTTP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.", - "properties": { - "type": { - "const": "http", - "type": "string" + "$ref": "#/$defs/ErrorCode" } - }, - "required": [ - "type" ], - "type": "object" + "description": "A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." + }, + "data": { + "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." + }, + "message": { + "description": "A string providing a short description of the error.\nThe message should be limited to a concise single sentence.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" + }, + "ErrorCode": { + "anyOf": [ + { + "const": -32700, + "description": "**Parse error**: Invalid JSON was received by the server.\nAn error occurred on the server while parsing the JSON text.", + "format": "int32", + "title": "Parse error", + "type": "integer" }, { - "allOf": [ - { - "$ref": "#/$defs/McpServerSse" - } - ], - "description": "SSE transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.", - "properties": { - "type": { - "const": "sse", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" + "const": -32600, + "description": "**Invalid request**: The JSON sent is not a valid Request object.", + "format": "int32", + "title": "Invalid request", + "type": "integer" }, { - "allOf": [ - { - "$ref": "#/$defs/McpServerStdio" - } - ], - "description": "Stdio transport configuration\n\nAll Agents MUST support this transport.", - "title": "stdio" + "const": -32601, + "description": "**Method not found**: The method does not exist or is not available.", + "format": "int32", + "title": "Method not found", + "type": "integer" + }, + { + "const": -32602, + "description": "**Invalid params**: Invalid method parameter(s).", + "format": "int32", + "title": "Invalid params", + "type": "integer" + }, + { + "const": -32603, + "description": "**Internal error**: Internal JSON-RPC error.\nReserved for implementation-defined server errors.", + "format": "int32", + "title": "Internal error", + "type": "integer" + }, + { + "const": -32800, + "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", + "format": "int32", + "title": "Request cancelled", + "type": "integer" + }, + { + "const": -32000, + "description": "**Authentication required**: Authentication is required before this operation can be performed.", + "format": "int32", + "title": "Authentication required", + "type": "integer" + }, + { + "const": -32002, + "description": "**Resource not found**: A given resource, such as a file, was not found.", + "format": "int32", + "title": "Resource not found", + "type": "integer" + }, + { + "const": -32042, + "description": "**URL elicitation required**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe agent requires user input via a URL-based elicitation before it can proceed.", + "format": "int32", + "title": "URL elicitation required", + "type": "integer" + }, + { + "description": "Other undefined error code.", + "format": "int32", + "title": "Other", + "type": "integer" } ], - "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)" + "description": "Predefined error codes for common JSON-RPC and ACP-specific errors.\n\nThese codes follow the JSON-RPC 2.0 specification for standard errors\nand use the reserved range (-32000 to -32099) for protocol-specific errors." }, - "McpServerHttp": { - "description": "HTTP transport configuration for MCP.", + "ExtNotification": { + "description": "Allows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "ExtRequest": { + "description": "Allows for sending an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "ExtResponse": { + "description": "Allows for sending an arbitrary response to an [`ExtRequest`] that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "FileSystemCapabilities": { + "description": "File system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", "properties": { "_meta": { "additionalProperties": true, @@ -2379,31 +3052,21 @@ "null" ] }, - "headers": { - "description": "HTTP headers to set when making requests to the MCP server.", - "items": { - "$ref": "#/$defs/HttpHeader" - }, - "type": "array" - }, - "name": { - "description": "Human-readable name identifying this MCP server.", - "type": "string" + "readTextFile": { + "default": false, + "description": "Whether the Client supports `fs/read_text_file` requests.", + "type": "boolean" }, - "url": { - "description": "URL to the MCP server.", - "type": "string" + "writeTextFile": { + "default": false, + "description": "Whether the Client supports `fs/write_text_file` requests.", + "type": "boolean" } }, - "required": [ - "name", - "url", - "headers" - ], "type": "object" }, - "McpServerSse": { - "description": "SSE transport configuration for MCP.", + "ForkSessionRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for forking an existing session.\n\nCreates a new session based on the context of an existing one, allowing\noperations like generating summaries without affecting the original session's history.\n\nOnly available if the Agent supports the `session.fork` capability.", "properties": { "_meta": { "additionalProperties": true, @@ -2413,31 +3076,43 @@ "null" ] }, - "headers": { - "description": "HTTP headers to set when making requests to the MCP server.", + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", "items": { - "$ref": "#/$defs/HttpHeader" + "type": "string" }, "type": "array" }, - "name": { - "description": "Human-readable name identifying this MCP server.", + "cwd": { + "description": "The working directory for this session.", "type": "string" }, - "url": { - "description": "URL to the MCP server.", - "type": "string" + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "items": { + "$ref": "#/$defs/McpServer" + }, + "type": "array" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to fork." } }, "required": [ - "name", - "url", - "headers" + "sessionId", + "cwd" ], - "type": "object" + "type": "object", + "x-method": "session/fork", + "x-side": "agent" }, - "McpServerStdio": { - "description": "Stdio transport configuration for MCP.", + "ForkSessionResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from forking an existing session.", "properties": { "_meta": { "additionalProperties": true, @@ -2447,43 +3122,56 @@ "null" ] }, - "args": { - "description": "Command-line arguments to pass to the MCP server.", + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", "items": { - "type": "string" + "$ref": "#/$defs/SessionConfigOption" }, - "type": "array" + "type": [ + "array", + "null" + ] }, - "command": { - "description": "Path to the MCP server executable.", - "type": "string" + "models": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModelState" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" }, - "env": { - "description": "Environment variables to set when launching the MCP server.", - "items": { - "$ref": "#/$defs/EnvVariable" - }, - "type": "array" + "modes": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" }, - "name": { - "description": "Human-readable name identifying this MCP server.", - "type": "string" + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "Unique identifier for the newly created forked session." } }, "required": [ - "name", - "command", - "args", - "env" + "sessionId" ], - "type": "object" - }, - "ModelId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for a model.", - "type": "string" + "type": "object", + "x-method": "session/fork", + "x-side": "agent" }, - "ModelInfo": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a selectable model.", + "HttpHeader": { + "description": "An HTTP header to set when making requests to the MCP server.", "properties": { "_meta": { "additionalProperties": true, @@ -2493,34 +3181,63 @@ "null" ] }, - "description": { - "description": "Optional description of the model.", + "name": { + "description": "The name of the HTTP header.", + "type": "string" + }, + "value": { + "description": "The value to set for the HTTP header.", + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "ImageContent": { + "description": "An image provided to or from an LLM.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" ] }, - "modelId": { - "allOf": [ + "annotations": { + "anyOf": [ { - "$ref": "#/$defs/ModelId" + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" } - ], - "description": "Unique identifier for the model." + ] }, - "name": { - "description": "Human-readable name of the model.", + "data": { + "type": "string" + }, + "mimeType": { "type": "string" + }, + "uri": { + "type": [ + "string", + "null" + ] } }, "required": [ - "modelId", - "name" + "data", + "mimeType" ], "type": "object" }, - "NewSessionRequest": { - "description": "Request parameters for creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "Implementation": { + "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an MCP implementation, with an optional\ntitle for UI representation.", "properties": { "_meta": { "additionalProperties": true, @@ -2530,28 +3247,30 @@ "null" ] }, - "cwd": { - "description": "The working directory for this session. Must be an absolute path.", + "name": { + "description": "Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn\u2019t present.", "type": "string" }, - "mcpServers": { - "description": "List of MCP (Model Context Protocol) servers the agent should connect to.", - "items": { - "$ref": "#/$defs/McpServer" - }, - "type": "array" + "title": { + "description": "Intended for UI and end-user contexts \u2014 optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display.", + "type": [ + "string", + "null" + ] + }, + "version": { + "description": "Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. \"1.0.0\").", + "type": "string" } }, "required": [ - "cwd", - "mcpServers" + "name", + "version" ], - "type": "object", - "x-method": "session/new", - "x-side": "agent" + "type": "object" }, - "NewSessionResponse": { - "description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "InitializeRequest": { + "description": "Request parameters for the initialize method.\n\nSent by the client to establish connection and negotiate capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", "properties": { "_meta": { "additionalProperties": true, @@ -2561,56 +3280,53 @@ "null" ] }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, - "type": [ - "array", - "null" - ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, + "clientCapabilities": { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/ClientCapabilities" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "default": { + "auth": { + "terminal": false + }, + "fs": { + "readTextFile": false, + "writeTextFile": false + }, + "terminal": false + }, + "description": "Capabilities supported by the client." }, - "modes": { + "clientInfo": { "anyOf": [ { - "$ref": "#/$defs/SessionModeState" + "$ref": "#/$defs/Implementation" }, { "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required." }, - "sessionId": { + "protocolVersion": { "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/ProtocolVersion" } ], - "description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation." + "description": "The latest protocol version supported by the client." } }, "required": [ - "sessionId" + "protocolVersion" ], "type": "object", - "x-method": "session/new", + "x-method": "initialize", "x-side": "agent" }, - "PermissionOption": { - "description": "An option presented to the user when requesting permission.", + "InitializeResponse": { + "description": "Response to the `initialize` method.\n\nContains the negotiated protocol version and agent capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", "properties": { "_meta": { "additionalProperties": true, @@ -2620,89 +3336,109 @@ "null" ] }, - "kind": { + "agentCapabilities": { "allOf": [ { - "$ref": "#/$defs/PermissionOptionKind" + "$ref": "#/$defs/AgentCapabilities" } ], - "description": "Hint about the nature of this permission option." + "default": { + "auth": {}, + "loadSession": false, + "mcpCapabilities": { + "http": false, + "sse": false + }, + "promptCapabilities": { + "audio": false, + "embeddedContext": false, + "image": false + }, + "sessionCapabilities": {} + }, + "description": "Capabilities supported by the agent." }, - "name": { - "description": "Human-readable label to display to the user.", - "type": "string" + "agentInfo": { + "anyOf": [ + { + "$ref": "#/$defs/Implementation" + }, + { + "type": "null" + } + ], + "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required." }, - "optionId": { + "authMethods": { + "default": [], + "description": "Authentication methods supported by the agent.", + "items": { + "$ref": "#/$defs/AuthMethod" + }, + "type": "array" + }, + "protocolVersion": { "allOf": [ { - "$ref": "#/$defs/PermissionOptionId" + "$ref": "#/$defs/ProtocolVersion" } ], - "description": "Unique identifier for this permission option." + "description": "The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version." } }, "required": [ - "optionId", - "name", - "kind" + "protocolVersion" ], - "type": "object" - }, - "PermissionOptionId": { - "description": "Unique identifier for a permission option.", - "type": "string" + "type": "object", + "x-method": "initialize", + "x-side": "agent" }, - "PermissionOptionKind": { - "description": "The type of permission option being presented to the user.\n\nHelps clients choose appropriate icons and UI treatment.", - "oneOf": [ - { - "const": "allow_once", - "description": "Allow this operation only this time.", - "type": "string" + "IntegerPropertySchema": { + "description": "Schema for integer properties in an elicitation form.", + "properties": { + "default": { + "description": "Default value.", + "format": "int64", + "type": [ + "integer", + "null" + ] }, - { - "const": "allow_always", - "description": "Allow this operation and remember the choice.", - "type": "string" + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] }, - { - "const": "reject_once", - "description": "Reject this operation only this time.", - "type": "string" + "maximum": { + "description": "Maximum value (inclusive).", + "format": "int64", + "type": [ + "integer", + "null" + ] }, - { - "const": "reject_always", - "description": "Reject this operation and remember the choice.", - "type": "string" - } - ] - }, - "Plan": { - "description": "An execution plan for accomplishing complex tasks.\n\nPlans consist of multiple entries representing individual tasks or goals.\nAgents report plans to clients to provide visibility into their execution strategy.\nPlans can evolve during execution as the agent discovers new requirements or completes tasks.\n\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "minimum": { + "description": "Minimum value (inclusive).", + "format": "int64", "type": [ - "object", + "integer", "null" ] }, - "entries": { - "description": "The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update.", - "items": { - "$ref": "#/$defs/PlanEntry" - }, - "type": "array" + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] } }, - "required": [ - "entries" - ], "type": "object" }, - "PlanEntry": { - "description": "A single entry in the execution plan.\n\nRepresents a task or goal that the assistant intends to accomplish\nas part of fulfilling the user's request.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "KillTerminalRequest": { + "description": "Request to kill a terminal without releasing it.", "properties": { "_meta": { "additionalProperties": true, @@ -2712,76 +3448,29 @@ "null" ] }, - "content": { - "description": "Human-readable description of what this task aims to accomplish.", - "type": "string" - }, - "priority": { + "sessionId": { "allOf": [ { - "$ref": "#/$defs/PlanEntryPriority" + "$ref": "#/$defs/SessionId" } ], - "description": "The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." + "description": "The session ID for this request." }, - "status": { - "allOf": [ - { - "$ref": "#/$defs/PlanEntryStatus" - } - ], - "description": "Current execution status of this task." + "terminalId": { + "description": "The ID of the terminal to kill.", + "type": "string" } }, "required": [ - "content", - "priority", - "status" + "sessionId", + "terminalId" ], - "type": "object" - }, - "PlanEntryPriority": { - "description": "Priority levels for plan entries.\n\nUsed to indicate the relative importance or urgency of different\ntasks in the execution plan.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", - "oneOf": [ - { - "const": "high", - "description": "High priority task - critical to the overall goal.", - "type": "string" - }, - { - "const": "medium", - "description": "Medium priority task - important but not critical.", - "type": "string" - }, - { - "const": "low", - "description": "Low priority task - nice to have but not essential.", - "type": "string" - } - ] - }, - "PlanEntryStatus": { - "description": "Status of a plan entry in the execution flow.\n\nTracks the lifecycle of each task from planning through completion.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", - "oneOf": [ - { - "const": "pending", - "description": "The task has not started yet.", - "type": "string" - }, - { - "const": "in_progress", - "description": "The task is currently being worked on.", - "type": "string" - }, - { - "const": "completed", - "description": "The task has been successfully completed.", - "type": "string" - } - ] + "type": "object", + "x-method": "terminal/kill", + "x-side": "client" }, - "PromptCapabilities": { - "description": "Prompt capabilities supported by the agent in `session/prompt` requests.\n\nBaseline agent functionality requires support for [`ContentBlock::Text`]\nand [`ContentBlock::ResourceLink`] in prompt requests.\n\nOther variants must be explicitly opted in to.\nCapabilities for different types of content in prompt requests.\n\nIndicates which content types beyond the baseline (text and resource links)\nthe agent can process.\n\nSee protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)", + "KillTerminalResponse": { + "description": "Response to `terminal/kill` method", "properties": { "_meta": { "additionalProperties": true, @@ -2790,27 +3479,14 @@ "object", "null" ] - }, - "audio": { - "default": false, - "description": "Agent supports [`ContentBlock::Audio`].", - "type": "boolean" - }, - "embeddedContext": { - "default": false, - "description": "Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", - "type": "boolean" - }, - "image": { - "default": false, - "description": "Agent supports [`ContentBlock::Image`].", - "type": "boolean" } }, - "type": "object" + "type": "object", + "x-method": "terminal/kill", + "x-side": "client" }, - "PromptRequest": { - "description": "Request parameters for sending a user prompt to the agent.\n\nContains the user's message and any additional context.\n\nSee protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)", + "ListProvidersRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/list`.", "properties": { "_meta": { "additionalProperties": true, @@ -2819,40 +3495,40 @@ "object", "null" ] - }, - "messageId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", + } + }, + "type": "object", + "x-method": "providers/list", + "x-side": "agent" + }, + "ListProvidersResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/list`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" ] }, - "prompt": { - "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", + "providers": { + "description": "Configurable providers with current routing info suitable for UI display.", "items": { - "$ref": "#/$defs/ContentBlock" + "$ref": "#/$defs/ProviderInfo" }, "type": "array" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session to send this user message to" } }, "required": [ - "sessionId", - "prompt" + "providers" ], "type": "object", - "x-method": "session/prompt", + "x-method": "providers/list", "x-side": "agent" }, - "PromptResponse": { - "description": "Response from processing a user prompt.\n\nSee protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)", + "ListSessionsRequest": { + "description": "Request parameters for listing existing sessions.\n\nOnly available if the Agent supports the `sessionCapabilities.list` capability.", "properties": { "_meta": { "additionalProperties": true, @@ -2862,49 +3538,34 @@ "null" ] }, - "stopReason": { - "allOf": [ - { - "$ref": "#/$defs/StopReason" - } - ], - "description": "Indicates why the agent stopped processing the turn." + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nFilter sessions by the exact ordered additional workspace roots. Each path must be absolute.\n\nThis filter applies only when the field is present and non-empty. When\nomitted or empty, no additional-root filter is applied.", + "items": { + "type": "string" + }, + "type": "array" }, - "usage": { - "anyOf": [ - { - "$ref": "#/$defs/Usage" - }, - { - "type": "null" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." + "cursor": { + "description": "Opaque cursor token from a previous response's nextCursor field for cursor-based pagination", + "type": [ + "string", + "null" + ] }, - "userMessageId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", + "cwd": { + "description": "Filter sessions by working directory. Must be an absolute path.", "type": [ "string", "null" ] } }, - "required": [ - "stopReason" - ], "type": "object", - "x-method": "session/prompt", + "x-method": "session/list", "x-side": "agent" }, - "ProtocolVersion": { - "description": "Protocol version identifier.\n\nThis version is only bumped for breaking changes.\nNon-breaking changes should be introduced via capabilities.", - "format": "uint16", - "maximum": 65535, - "minimum": 0, - "type": "integer" - }, - "ReadTextFileRequest": { - "description": "Request to read content from a text file.\n\nOnly available if the client supports the `fs.readTextFile` capability.", + "ListSessionsResponse": { + "description": "Response from listing sessions.", "properties": { "_meta": { "additionalProperties": true, @@ -2914,47 +3575,65 @@ "null" ] }, - "limit": { - "description": "Maximum number of lines to read.", - "format": "uint32", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "line": { - "description": "Line number to start reading from (1-based).", - "format": "uint32", - "minimum": 0, + "nextCursor": { + "description": "Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", "type": [ - "integer", + "string", "null" ] }, - "path": { - "description": "Absolute path to the file to read.", - "type": "string" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The session ID for this request." + "sessions": { + "description": "Array of session information objects", + "items": { + "$ref": "#/$defs/SessionInfo" + }, + "type": "array" } }, "required": [ - "sessionId", - "path" + "sessions" ], "type": "object", - "x-method": "fs/read_text_file", - "x-side": "client" + "x-method": "session/list", + "x-side": "agent" }, - "ReadTextFileResponse": { - "description": "Response containing the contents of a text file.", + "LlmProtocol": { + "anyOf": [ + { + "const": "anthropic", + "description": "Anthropic API protocol.", + "type": "string" + }, + { + "const": "openai", + "description": "OpenAI API protocol.", + "type": "string" + }, + { + "const": "azure", + "description": "Azure OpenAI API protocol.", + "type": "string" + }, + { + "const": "vertex", + "description": "Google Vertex AI API protocol.", + "type": "string" + }, + { + "const": "bedrock", + "description": "AWS Bedrock API protocol.", + "type": "string" + }, + { + "description": "Unknown or custom protocol.", + "title": "other", + "type": "string" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWell-known API protocol identifiers for LLM providers.\n\nAgents and clients MUST handle unknown protocol identifiers gracefully.\n\nProtocol names beginning with `_` are free for custom use, like other ACP extension methods.\nProtocol names that do not begin with `_` are reserved for the ACP spec." + }, + "LoadSessionRequest": { + "description": "Request parameters for loading an existing session.\n\nOnly available if the Agent supports the `loadSession` capability.\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", "properties": { "_meta": { "additionalProperties": true, @@ -2964,19 +3643,44 @@ "null" ] }, - "content": { + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession.", + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "description": "The working directory for this session.", "type": "string" + }, + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "items": { + "$ref": "#/$defs/McpServer" + }, + "type": "array" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to load." } }, "required": [ - "content" + "mcpServers", + "cwd", + "sessionId" ], "type": "object", - "x-method": "fs/read_text_file", - "x-side": "client" + "x-method": "session/load", + "x-side": "agent" }, - "ReleaseTerminalRequest": { - "description": "Request to release a terminal and free its resources.", + "LoadSessionResponse": { + "description": "Response from loading an existing session.", "properties": { "_meta": { "additionalProperties": true, @@ -2986,29 +3690,59 @@ "null" ] }, - "sessionId": { - "allOf": [ + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "type": [ + "array", + "null" + ] + }, + "models": { + "anyOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/SessionModelState" + }, + { + "type": "null" } ], - "description": "The session ID for this request." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" }, - "terminalId": { - "description": "The ID of the terminal to release.", - "type": "string" + "modes": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" } }, - "required": [ - "sessionId", - "terminalId" - ], "type": "object", - "x-method": "terminal/release", - "x-side": "client" + "x-method": "session/load", + "x-side": "agent" }, - "ReleaseTerminalResponse": { - "description": "Response to terminal/release method", + "LogoutCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLogout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "LogoutRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for the logout method.\n\nTerminates the current authenticated session.", "properties": { "_meta": { "additionalProperties": true, @@ -3020,68 +3754,101 @@ } }, "type": "object", - "x-method": "terminal/release", - "x-side": "client" + "x-method": "logout", + "x-side": "agent" }, - "RequestId": { - "anyOf": [ - { - "title": "Null", - "type": "null" + "LogoutResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to the `logout` method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "logout", + "x-side": "agent" + }, + "McpCapabilities": { + "description": "MCP capabilities supported by the agent", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] }, - { - "format": "int64", - "title": "Number", - "type": "integer" + "http": { + "default": false, + "description": "Agent supports [`McpServer::Http`].", + "type": "boolean" }, - { - "title": "Str", - "type": "string" + "sse": { + "default": false, + "description": "Agent supports [`McpServer::Sse`].", + "type": "boolean" } - ], - "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." - }, - "RequestPermissionOutcome": { - "description": "The outcome of a permission request.", - "discriminator": { - "propertyName": "outcome" }, - "oneOf": [ + "type": "object" + }, + "McpServer": { + "anyOf": [ { - "description": "The prompt turn was cancelled before the user responded.\n\nWhen a client sends a `session/cancel` notification to cancel an ongoing\nprompt turn, it MUST respond to all pending `session/request_permission`\nrequests with this `Cancelled` outcome.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "allOf": [ + { + "$ref": "#/$defs/McpServerHttp" + } + ], + "description": "HTTP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.", "properties": { - "outcome": { - "const": "cancelled", + "type": { + "const": "http", "type": "string" } }, "required": [ - "outcome" + "type" ], "type": "object" }, { "allOf": [ { - "$ref": "#/$defs/SelectedPermissionOutcome" + "$ref": "#/$defs/McpServerSse" } ], - "description": "The user selected one of the provided options.", + "description": "SSE transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.", "properties": { - "outcome": { - "const": "selected", + "type": { + "const": "sse", "type": "string" } }, "required": [ - "outcome" + "type" ], "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/McpServerStdio" + } + ], + "description": "Stdio transport configuration\n\nAll Agents MUST support this transport.", + "title": "stdio" } - ] + ], + "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)" }, - "RequestPermissionRequest": { - "description": "Request for user permission to execute a tool call.\n\nSent when the agent needs authorization before performing a sensitive operation.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", + "McpServerHttp": { + "description": "HTTP transport configuration for MCP.", "properties": { "_meta": { "additionalProperties": true, @@ -3091,68 +3858,31 @@ "null" ] }, - "options": { - "description": "Available permission options for the user to choose from.", + "headers": { + "description": "HTTP headers to set when making requests to the MCP server.", "items": { - "$ref": "#/$defs/PermissionOption" + "$ref": "#/$defs/HttpHeader" }, "type": "array" }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The session ID for this request." + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" }, - "toolCall": { - "allOf": [ - { - "$ref": "#/$defs/ToolCallUpdate" - } - ], - "description": "Details about the tool call requiring permission." - } - }, - "required": [ - "sessionId", - "toolCall", - "options" - ], - "type": "object", - "x-method": "session/request_permission", - "x-side": "client" - }, - "RequestPermissionResponse": { - "description": "Response to a permission request.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "outcome": { - "allOf": [ - { - "$ref": "#/$defs/RequestPermissionOutcome" - } - ], - "description": "The user's decision on the permission request." + "url": { + "description": "URL to the MCP server.", + "type": "string" } }, "required": [ - "outcome" + "name", + "url", + "headers" ], - "type": "object", - "x-method": "session/request_permission", - "x-side": "client" + "type": "object" }, - "ResourceLink": { - "description": "A resource that the server is capable of reading, included in a prompt or tool call result.", + "McpServerSse": { + "description": "SSE transport configuration for MCP.", "properties": { "_meta": { "additionalProperties": true, @@ -3162,56 +3892,31 @@ "null" ] }, - "annotations": { - "anyOf": [ - { - "$ref": "#/$defs/Annotations" - }, - { - "type": "null" - } - ] - }, - "description": { - "type": [ - "string", - "null" - ] - }, - "mimeType": { - "type": [ - "string", - "null" - ] + "headers": { + "description": "HTTP headers to set when making requests to the MCP server.", + "items": { + "$ref": "#/$defs/HttpHeader" + }, + "type": "array" }, "name": { + "description": "Human-readable name identifying this MCP server.", "type": "string" }, - "size": { - "format": "int64", - "type": [ - "integer", - "null" - ] - }, - "title": { - "type": [ - "string", - "null" - ] - }, - "uri": { + "url": { + "description": "URL to the MCP server.", "type": "string" } }, "required": [ "name", - "uri" + "url", + "headers" ], "type": "object" }, - "ResumeSessionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for resuming an existing session.\n\nResumes an existing session without returning previous messages (unlike `session/load`).\nThis is useful for agents that can resume sessions but don't implement full session loading.\n\nOnly available if the Agent supports the `session.resume` capability.", + "McpServerStdio": { + "description": "Stdio transport configuration for MCP.", "properties": { "_meta": { "additionalProperties": true, @@ -3221,36 +3926,43 @@ "null" ] }, - "cwd": { - "description": "The working directory for this session.", + "args": { + "description": "Command-line arguments to pass to the MCP server.", + "items": { + "type": "string" + }, + "type": "array" + }, + "command": { + "description": "Path to the MCP server executable.", "type": "string" }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", + "env": { + "description": "Environment variables to set when launching the MCP server.", "items": { - "$ref": "#/$defs/McpServer" + "$ref": "#/$defs/EnvVariable" }, "type": "array" }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session to resume." + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" } }, "required": [ - "sessionId", - "cwd" + "name", + "command", + "args", + "env" ], - "type": "object", - "x-method": "session/resume", - "x-side": "agent" + "type": "object" }, - "ResumeSessionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from resuming an existing session.", + "ModelId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for a model.", + "type": "string" + }, + "ModelInfo": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a selectable model.", "properties": { "_meta": { "additionalProperties": true, @@ -3260,78 +3972,116 @@ "null" ] }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, + "description": { + "description": "Optional description of the model.", "type": [ - "array", + "string", "null" ] }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, + "modelId": { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/ModelId" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "description": "Unique identifier for the model." }, - "modes": { - "anyOf": [ + "name": { + "description": "Human-readable name of the model.", + "type": "string" + } + }, + "required": [ + "modelId", + "name" + ], + "type": "object" + }, + "MultiSelectItems": { + "anyOf": [ + { + "allOf": [ { - "$ref": "#/$defs/SessionModeState" - }, + "$ref": "#/$defs/UntitledMultiSelectItems" + } + ], + "description": "Untitled multi-select items with plain string values.", + "title": "Untitled" + }, + { + "allOf": [ { - "type": "null" + "$ref": "#/$defs/TitledMultiSelectItems" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Titled multi-select items with human-readable labels.", + "title": "Titled" } - }, - "type": "object", - "x-method": "session/resume", - "x-side": "agent" - }, - "Role": { - "description": "The sender or recipient of messages and data in a conversation.", - "enum": [ - "assistant", - "user" ], - "type": "string" + "description": "Items for a multi-select (array) property schema." }, - "SelectedPermissionOutcome": { - "description": "The user selected one of the provided options.", + "MultiSelectPropertySchema": { + "description": "Schema for multi-select (array) properties in an elicitation form.", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "default": { + "description": "Default selected values.", + "items": { + "type": "string" + }, "type": [ - "object", + "array", "null" ] }, - "optionId": { + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "items": { "allOf": [ { - "$ref": "#/$defs/PermissionOptionId" + "$ref": "#/$defs/MultiSelectItems" } ], - "description": "The ID of the option the user selected." + "description": "The items definition describing allowed values." + }, + "maxItems": { + "description": "Maximum number of items to select.", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "minItems": { + "description": "Minimum number of items to select.", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] } }, "required": [ - "optionId" + "items" ], "type": "object" }, - "SessionCapabilities": { - "description": "Session capabilities supported by the agent.\n\nAs a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.\n\nOptionally, they **MAY** support other session methods and notifications by specifying additional capabilities.\n\nNote: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.\n\nSee protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)", + "NesCapabilities": { + "description": "NES capabilities advertised by the agent during initialization.", "properties": { "_meta": { "additionalProperties": true, @@ -3341,230 +4091,188 @@ "null" ] }, - "close": { + "context": { "anyOf": [ { - "$ref": "#/$defs/SessionCloseCapabilities" + "$ref": "#/$defs/NesContextCapabilities" }, { "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/close`." + "description": "Context the agent wants attached to each suggestion request." }, - "fork": { + "events": { "anyOf": [ { - "$ref": "#/$defs/SessionForkCapabilities" + "$ref": "#/$defs/NesEventCapabilities" }, { "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + "description": "Events the agent wants to receive." + } + }, + "type": "object" + }, + "NesContextCapabilities": { + "description": "Context capabilities the agent wants attached to each suggestion request.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] }, - "list": { + "diagnostics": { "anyOf": [ { - "$ref": "#/$defs/SessionListCapabilities" + "$ref": "#/$defs/NesDiagnosticsCapabilities" }, { "type": "null" } ], - "description": "Whether the agent supports `session/list`." + "description": "Whether the agent wants diagnostics context." }, - "resume": { + "editHistory": { "anyOf": [ { - "$ref": "#/$defs/SessionResumeCapabilities" + "$ref": "#/$defs/NesEditHistoryCapabilities" }, { "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/resume`." - } - }, - "type": "object" - }, - "SessionCloseCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - } - }, - "type": "object" - }, - "SessionConfigBoolean": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", - "properties": { - "currentValue": { - "description": "The current value of the boolean option.", - "type": "boolean" - } - }, - "required": [ - "currentValue" - ], - "type": "object" - }, - "SessionConfigGroupId": { - "description": "Unique identifier for a session configuration option value group.", - "type": "string" - }, - "SessionConfigId": { - "description": "Unique identifier for a session configuration option.", - "type": "string" - }, - "SessionConfigOption": { - "description": "A session configuration option selector and its current state.", - "discriminator": { - "propertyName": "type" - }, - "oneOf": [ - { - "allOf": [ + "description": "Whether the agent wants edit history context." + }, + "openFiles": { + "anyOf": [ { - "$ref": "#/$defs/SessionConfigSelect" - } - ], - "description": "Single-value selector (dropdown).", - "properties": { - "type": { - "const": "select", - "type": "string" + "$ref": "#/$defs/NesOpenFilesCapabilities" + }, + { + "type": "null" } - }, - "required": [ - "type" ], - "type": "object" + "description": "Whether the agent wants open files context." }, - { - "allOf": [ + "recentFiles": { + "anyOf": [ { - "$ref": "#/$defs/SessionConfigBoolean" + "$ref": "#/$defs/NesRecentFilesCapabilities" + }, + { + "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", - "properties": { - "type": { - "const": "boolean", - "type": "string" + "description": "Whether the agent wants recent files context." + }, + "relatedSnippets": { + "anyOf": [ + { + "$ref": "#/$defs/NesRelatedSnippetsCapabilities" + }, + { + "type": "null" } - }, - "required": [ - "type" ], - "type": "object" - } - ], - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "description": "Whether the agent wants related snippets context." }, - "category": { + "userActions": { "anyOf": [ { - "$ref": "#/$defs/SessionConfigOptionCategory" + "$ref": "#/$defs/NesUserActionsCapabilities" }, { "type": "null" } ], - "description": "Optional semantic category for this option (UX only)." + "description": "Whether the agent wants user actions context." + } + }, + "type": "object" + }, + "NesDiagnostic": { + "description": "A diagnostic (error, warning, etc.).", + "properties": { + "message": { + "description": "The diagnostic message.", + "type": "string" }, - "description": { - "description": "Optional description for the Client to display to the user.", - "type": [ - "string", - "null" - ] + "range": { + "allOf": [ + { + "$ref": "#/$defs/Range" + } + ], + "description": "The range of the diagnostic." }, - "id": { + "severity": { "allOf": [ { - "$ref": "#/$defs/SessionConfigId" + "$ref": "#/$defs/NesDiagnosticSeverity" } ], - "description": "Unique identifier for the configuration option." + "description": "The severity of the diagnostic." }, - "name": { - "description": "Human-readable label for the option.", + "uri": { + "description": "The URI of the file containing the diagnostic.", "type": "string" } }, "required": [ - "id", - "name" + "uri", + "range", + "severity", + "message" ], "type": "object" }, - "SessionConfigOptionCategory": { - "anyOf": [ + "NesDiagnosticSeverity": { + "description": "Severity of a diagnostic.", + "oneOf": [ { - "const": "mode", - "description": "Session mode selector.", + "const": "error", + "description": "An error.", "type": "string" }, { - "const": "model", - "description": "Model selector.", + "const": "warning", + "description": "A warning.", "type": "string" }, { - "const": "thought_level", - "description": "Thought/reasoning level selector.", + "const": "information", + "description": "An informational message.", "type": "string" }, { - "description": "Unknown / uncategorized selector.", - "title": "other", + "const": "hint", + "description": "A hint.", "type": "string" } - ], - "description": "Semantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec." + ] }, - "SessionConfigSelect": { - "description": "A single-value selector (dropdown) session configuration option payload.", + "NesDiagnosticsCapabilities": { + "description": "Capabilities for diagnostics context.", "properties": { - "currentValue": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } - ], - "description": "The currently selected value." - }, - "options": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigSelectOptions" - } - ], - "description": "The set of selectable options." + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] } }, - "required": [ - "currentValue", - "options" - ], "type": "object" }, - "SessionConfigSelectGroup": { - "description": "A group of possible values for a session configuration option.", + "NesDocumentDidChangeCapabilities": { + "description": "Capabilities for `document/didChange` events.", "properties": { "_meta": { "additionalProperties": true, @@ -3574,35 +4282,22 @@ "null" ] }, - "group": { + "syncKind": { "allOf": [ { - "$ref": "#/$defs/SessionConfigGroupId" + "$ref": "#/$defs/TextDocumentSyncKind" } ], - "description": "Unique identifier for this group." - }, - "name": { - "description": "Human-readable label for this group.", - "type": "string" - }, - "options": { - "description": "The set of option values in this group.", - "items": { - "$ref": "#/$defs/SessionConfigSelectOption" - }, - "type": "array" + "description": "The sync kind the agent wants: `\"full\"` or `\"incremental\"`." } }, "required": [ - "group", - "name", - "options" + "syncKind" ], "type": "object" }, - "SessionConfigSelectOption": { - "description": "A possible value for a session configuration option.", + "NesDocumentDidCloseCapabilities": { + "description": "Marker for `document/didClose` capability support.", "properties": { "_meta": { "additionalProperties": true, @@ -3611,60 +4306,26 @@ "object", "null" ] - }, - "description": { - "description": "Optional description for this option value.", + } + }, + "type": "object" + }, + "NesDocumentDidFocusCapabilities": { + "description": "Marker for `document/didFocus` capability support.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" ] - }, - "name": { - "description": "Human-readable label for this option value.", - "type": "string" - }, - "value": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } - ], - "description": "Unique identifier for this option value." } }, - "required": [ - "value", - "name" - ], "type": "object" }, - "SessionConfigSelectOptions": { - "anyOf": [ - { - "description": "A flat list of options with no grouping.", - "items": { - "$ref": "#/$defs/SessionConfigSelectOption" - }, - "title": "Ungrouped", - "type": "array" - }, - { - "description": "A list of options grouped under headers.", - "items": { - "$ref": "#/$defs/SessionConfigSelectGroup" - }, - "title": "Grouped", - "type": "array" - } - ], - "description": "Possible values for a session configuration option." - }, - "SessionConfigValueId": { - "description": "Unique identifier for a session configuration option value.", - "type": "string" - }, - "SessionForkCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", + "NesDocumentDidOpenCapabilities": { + "description": "Marker for `document/didOpen` capability support.", "properties": { "_meta": { "additionalProperties": true, @@ -3677,12 +4338,22 @@ }, "type": "object" }, - "SessionId": { - "description": "A unique identifier for a conversation session between a client and agent.\n\nSessions maintain their own context, conversation history, and state,\nallowing multiple independent interactions with the same agent.\n\nSee protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)", - "type": "string" - }, - "SessionInfo": { - "description": "Information about a session returned by session/list", + "NesDocumentDidSaveCapabilities": { + "description": "Marker for `document/didSave` capability support.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "NesDocumentEventCapabilities": { + "description": "Document event capabilities the agent wants to receive.", "properties": { "_meta": { "additionalProperties": true, @@ -3692,41 +4363,66 @@ "null" ] }, - "cwd": { - "description": "The working directory for this session. Must be an absolute path.", - "type": "string" - }, - "sessionId": { - "allOf": [ + "didChange": { + "anyOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/NesDocumentDidChangeCapabilities" + }, + { + "type": "null" } ], - "description": "Unique identifier for the session" + "description": "Whether the agent wants `document/didChange` events, and the sync kind." }, - "title": { - "description": "Human-readable title for the session", - "type": [ - "string", - "null" - ] + "didClose": { + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidCloseCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent wants `document/didClose` events." }, - "updatedAt": { - "description": "ISO 8601 timestamp of last activity", - "type": [ - "string", - "null" - ] + "didFocus": { + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidFocusCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent wants `document/didFocus` events." + }, + "didOpen": { + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidOpenCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent wants `document/didOpen` events." + }, + "didSave": { + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidSaveCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent wants `document/didSave` events." } }, - "required": [ - "sessionId", - "cwd" - ], "type": "object" }, - "SessionInfoUpdate": { - "description": "Update to session metadata. All fields are optional to support partial updates.\n\nAgents send this notification to update session information like title or custom metadata.\nThis allows clients to display dynamic session names and track session state changes.", + "NesEditHistoryCapabilities": { + "description": "Capabilities for edit history context.", "properties": { "_meta": { "additionalProperties": true, @@ -3736,39 +4432,75 @@ "null" ] }, - "title": { - "description": "Human-readable title for the session. Set to null to clear.", + "maxCount": { + "description": "Maximum number of edit history entries the agent can use.", + "format": "uint32", + "minimum": 0, "type": [ - "string", + "integer", "null" ] + } + }, + "type": "object" + }, + "NesEditHistoryEntry": { + "description": "An entry in the edit history.", + "properties": { + "diff": { + "description": "A diff representing the edit.", + "type": "string" }, - "updatedAt": { - "description": "ISO 8601 timestamp of last activity. Set to null to clear.", - "type": [ - "string", - "null" - ] + "uri": { + "description": "The URI of the edited file.", + "type": "string" } }, + "required": [ + "uri", + "diff" + ], "type": "object" }, - "SessionListCapabilities": { - "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", + "NesEditSuggestion": { + "description": "A text edit suggestion.", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "cursorPosition": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "description": "Optional suggested cursor position after applying edits." + }, + "edits": { + "description": "The text edits to apply.", + "items": { + "$ref": "#/$defs/NesTextEdit" + }, + "type": "array" + }, + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "uri": { + "description": "The URI of the file to edit.", + "type": "string" } }, + "required": [ + "id", + "uri", + "edits" + ], "type": "object" }, - "SessionMode": { - "description": "A mode the agent can operate in.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "NesEventCapabilities": { + "description": "Event capabilities the agent can consume.", "properties": { "_meta": { "additionalProperties": true, @@ -3778,31 +4510,49 @@ "null" ] }, - "description": { - "type": [ - "string", - "null" - ] + "document": { + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentEventCapabilities" + }, + { + "type": "null" + } + ], + "description": "Document event capabilities." + } + }, + "type": "object" + }, + "NesExcerpt": { + "description": "A code excerpt from a file.", + "properties": { + "endLine": { + "description": "The end line of the excerpt (zero-based).", + "format": "uint32", + "minimum": 0, + "type": "integer" }, - "id": { - "$ref": "#/$defs/SessionModeId" + "startLine": { + "description": "The start line of the excerpt (zero-based).", + "format": "uint32", + "minimum": 0, + "type": "integer" }, - "name": { + "text": { + "description": "The text content of the excerpt.", "type": "string" } }, "required": [ - "id", - "name" + "startLine", + "endLine", + "text" ], "type": "object" }, - "SessionModeId": { - "description": "Unique identifier for a Session Mode.", - "type": "string" - }, - "SessionModeState": { - "description": "The set of modes and the one currently active.", + "NesJumpCapabilities": { + "description": "Marker for jump suggestion support.", "properties": { "_meta": { "additionalProperties": true, @@ -3811,64 +4561,77 @@ "object", "null" ] + } + }, + "type": "object" + }, + "NesJumpSuggestion": { + "description": "A jump-to-location suggestion.", + "properties": { + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" }, - "availableModes": { - "description": "The set of modes that the Agent can operate in", - "items": { - "$ref": "#/$defs/SessionMode" - }, - "type": "array" - }, - "currentModeId": { + "position": { "allOf": [ { - "$ref": "#/$defs/SessionModeId" + "$ref": "#/$defs/Position" } ], - "description": "The current mode the Agent is in." + "description": "The target position within the file." + }, + "uri": { + "description": "The file to navigate to.", + "type": "string" } }, "required": [ - "currentModeId", - "availableModes" + "id", + "uri", + "position" ], "type": "object" }, - "SessionModelState": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe set of models and the one currently active.", + "NesOpenFile": { + "description": "An open file in the editor.", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "languageId": { + "description": "The language identifier.", + "type": "string" + }, + "lastFocusedMs": { + "description": "Timestamp in milliseconds since epoch of when the file was last focused.", + "format": "uint64", + "minimum": 0, "type": [ - "object", + "integer", "null" ] }, - "availableModels": { - "description": "The set of models that the Agent can use", - "items": { - "$ref": "#/$defs/ModelInfo" - }, - "type": "array" + "uri": { + "description": "The URI of the file.", + "type": "string" }, - "currentModelId": { - "allOf": [ + "visibleRange": { + "anyOf": [ { - "$ref": "#/$defs/ModelId" + "$ref": "#/$defs/Range" + }, + { + "type": "null" } ], - "description": "The current model the Agent is in." + "description": "The visible range in the editor, if any." } }, "required": [ - "currentModelId", - "availableModels" + "uri", + "languageId" ], "type": "object" }, - "SessionNotification": { - "description": "Notification containing a session update from the agent.\n\nUsed to stream real-time progress and results during prompt processing.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "NesOpenFilesCapabilities": { + "description": "Capabilities for open files context.", "properties": { "_meta": { "additionalProperties": true, @@ -3877,34 +4640,35 @@ "object", "null" ] + } + }, + "type": "object" + }, + "NesRecentFile": { + "description": "A recently accessed file.", + "properties": { + "languageId": { + "description": "The language identifier.", + "type": "string" }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session this update pertains to." + "text": { + "description": "The full text content of the file.", + "type": "string" }, - "update": { - "allOf": [ - { - "$ref": "#/$defs/SessionUpdate" - } - ], - "description": "The actual update content." + "uri": { + "description": "The URI of the file.", + "type": "string" } }, "required": [ - "sessionId", - "update" + "uri", + "languageId", + "text" ], - "type": "object", - "x-method": "session/update", - "x-side": "client" + "type": "object" }, - "SessionResumeCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/resume` method.\n\nBy supplying `{}` it means that the agent supports resuming of sessions.", + "NesRecentFilesCapabilities": { + "description": "Capabilities for recent files context.", "properties": { "_meta": { "additionalProperties": true, @@ -3913,151 +4677,2271 @@ "object", "null" ] + }, + "maxCount": { + "description": "Maximum number of recent files the agent can use.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] } }, "type": "object" }, - "SessionUpdate": { - "description": "Different types of updates that can be sent during session processing.\n\nThese updates provide real-time feedback about the agent's progress.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", - "discriminator": { - "propertyName": "sessionUpdate" - }, + "NesRejectReason": { + "description": "The reason a suggestion was rejected.", "oneOf": [ { - "allOf": [ - { - "$ref": "#/$defs/ContentChunk" - } - ], - "description": "A chunk of the user's message being streamed.", - "properties": { - "sessionUpdate": { - "const": "user_message_chunk", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + "const": "rejected", + "description": "The user explicitly dismissed the suggestion.", + "type": "string" }, { + "const": "ignored", + "description": "The suggestion was shown but the user continued editing without interacting.", + "type": "string" + }, + { + "const": "replaced", + "description": "The suggestion was superseded by a newer suggestion.", + "type": "string" + }, + { + "const": "cancelled", + "description": "The request was cancelled before the agent returned a response.", + "type": "string" + } + ] + }, + "NesRelatedSnippet": { + "description": "A related code snippet from a file.", + "properties": { + "excerpts": { + "description": "The code excerpts.", + "items": { + "$ref": "#/$defs/NesExcerpt" + }, + "type": "array" + }, + "uri": { + "description": "The URI of the file containing the snippets.", + "type": "string" + } + }, + "required": [ + "uri", + "excerpts" + ], + "type": "object" + }, + "NesRelatedSnippetsCapabilities": { + "description": "Capabilities for related snippets context.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "NesRenameCapabilities": { + "description": "Marker for rename suggestion support.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "NesRenameSuggestion": { + "description": "A rename symbol suggestion.", + "properties": { + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "newName": { + "description": "The new name for the symbol.", + "type": "string" + }, + "position": { "allOf": [ { - "$ref": "#/$defs/ContentChunk" + "$ref": "#/$defs/Position" } ], - "description": "A chunk of the agent's response being streamed.", - "properties": { - "sessionUpdate": { - "const": "agent_message_chunk", - "type": "string" - } + "description": "The position of the symbol to rename." + }, + "uri": { + "description": "The file URI containing the symbol.", + "type": "string" + } + }, + "required": [ + "id", + "uri", + "position", + "newName" + ], + "type": "object" + }, + "NesRepository": { + "description": "Repository metadata for an NES session.", + "properties": { + "name": { + "description": "The repository name.", + "type": "string" + }, + "owner": { + "description": "The repository owner.", + "type": "string" + }, + "remoteUrl": { + "description": "The remote URL of the repository.", + "type": "string" + } + }, + "required": [ + "name", + "owner", + "remoteUrl" + ], + "type": "object" + }, + "NesSearchAndReplaceCapabilities": { + "description": "Marker for search and replace suggestion support.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "NesSearchAndReplaceSuggestion": { + "description": "A search-and-replace suggestion.", + "properties": { + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "isRegex": { + "description": "Whether `search` is a regular expression. Defaults to `false`.", + "type": [ + "boolean", + "null" + ] + }, + "replace": { + "description": "The replacement text.", + "type": "string" + }, + "search": { + "description": "The text or pattern to find.", + "type": "string" + }, + "uri": { + "description": "The file URI to search within.", + "type": "string" + } + }, + "required": [ + "id", + "uri", + "search", + "replace" + ], + "type": "object" + }, + "NesSuggestContext": { + "description": "Context attached to a suggestion request.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "diagnostics": { + "description": "Current diagnostics (errors, warnings).", + "items": { + "$ref": "#/$defs/NesDiagnostic" }, - "required": [ - "sessionUpdate" - ], - "type": "object" + "type": [ + "array", + "null" + ] + }, + "editHistory": { + "description": "Recent edit history.", + "items": { + "$ref": "#/$defs/NesEditHistoryEntry" + }, + "type": [ + "array", + "null" + ] + }, + "openFiles": { + "description": "Currently open files in the editor.", + "items": { + "$ref": "#/$defs/NesOpenFile" + }, + "type": [ + "array", + "null" + ] + }, + "recentFiles": { + "description": "Recently accessed files.", + "items": { + "$ref": "#/$defs/NesRecentFile" + }, + "type": [ + "array", + "null" + ] + }, + "relatedSnippets": { + "description": "Related code snippets.", + "items": { + "$ref": "#/$defs/NesRelatedSnippet" + }, + "type": [ + "array", + "null" + ] }, + "userActions": { + "description": "Recent user actions (typing, navigation, etc.).", + "items": { + "$ref": "#/$defs/NesUserAction" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "NesSuggestion": { + "description": "A suggestion returned by the agent.", + "discriminator": { + "propertyName": "kind" + }, + "oneOf": [ { "allOf": [ { - "$ref": "#/$defs/ContentChunk" + "$ref": "#/$defs/NesEditSuggestion" } ], - "description": "A chunk of the agent's internal reasoning being streamed.", + "description": "A text edit suggestion.", "properties": { - "sessionUpdate": { - "const": "agent_thought_chunk", + "kind": { + "const": "edit", "type": "string" } }, "required": [ - "sessionUpdate" + "kind" ], "type": "object" }, { "allOf": [ { - "$ref": "#/$defs/ToolCall" + "$ref": "#/$defs/NesJumpSuggestion" } ], - "description": "Notification that a new tool call has been initiated.", + "description": "A jump-to-location suggestion.", "properties": { - "sessionUpdate": { - "const": "tool_call", + "kind": { + "const": "jump", "type": "string" } }, "required": [ - "sessionUpdate" + "kind" ], "type": "object" }, { "allOf": [ { - "$ref": "#/$defs/ToolCallUpdate" + "$ref": "#/$defs/NesRenameSuggestion" } ], - "description": "Update on the status or results of a tool call.", + "description": "A rename symbol suggestion.", "properties": { - "sessionUpdate": { - "const": "tool_call_update", + "kind": { + "const": "rename", "type": "string" } }, "required": [ - "sessionUpdate" + "kind" ], "type": "object" }, { "allOf": [ { - "$ref": "#/$defs/Plan" + "$ref": "#/$defs/NesSearchAndReplaceSuggestion" } ], - "description": "The agent's execution plan for complex tasks.\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "description": "A search-and-replace suggestion.", "properties": { - "sessionUpdate": { - "const": "plan", + "kind": { + "const": "searchAndReplace", "type": "string" } }, "required": [ - "sessionUpdate" + "kind" ], "type": "object" + } + ] + }, + "NesTextEdit": { + "description": "A text edit within a suggestion.", + "properties": { + "newText": { + "description": "The replacement text.", + "type": "string" }, - { + "range": { "allOf": [ { - "$ref": "#/$defs/AvailableCommandsUpdate" - } - ], - "description": "Available commands are ready or have changed", - "properties": { - "sessionUpdate": { - "const": "available_commands_update", - "type": "string" + "$ref": "#/$defs/Range" } - }, - "required": [ - "sessionUpdate" ], - "type": "object" + "description": "The range to replace." + } + }, + "required": [ + "range", + "newText" + ], + "type": "object" + }, + "NesTriggerKind": { + "description": "What triggered the suggestion request.", + "oneOf": [ + { + "const": "automatic", + "description": "Triggered by user typing or cursor movement.", + "type": "string" + }, + { + "const": "diagnostic", + "description": "Triggered by a diagnostic appearing at or near the cursor.", + "type": "string" }, { + "const": "manual", + "description": "Triggered by an explicit user action (keyboard shortcut).", + "type": "string" + } + ] + }, + "NesUserAction": { + "description": "A user action (typing, cursor movement, etc.).", + "properties": { + "action": { + "description": "The kind of action (e.g., \"insertChar\", \"cursorMovement\").", + "type": "string" + }, + "position": { "allOf": [ { - "$ref": "#/$defs/CurrentModeUpdate" + "$ref": "#/$defs/Position" } ], - "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", - "properties": { - "sessionUpdate": { + "description": "The position where the action occurred." + }, + "timestampMs": { + "description": "Timestamp in milliseconds since epoch.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "uri": { + "description": "The URI of the file where the action occurred.", + "type": "string" + } + }, + "required": [ + "action", + "uri", + "position", + "timestampMs" + ], + "type": "object" + }, + "NesUserActionsCapabilities": { + "description": "Capabilities for user actions context.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "maxCount": { + "description": "Maximum number of user actions the agent can use.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + }, + "NewSessionRequest": { + "description": "Request parameters for creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "description": "The working directory for this session. Must be an absolute path.", + "type": "string" + }, + "mcpServers": { + "description": "List of MCP (Model Context Protocol) servers the agent should connect to.", + "items": { + "$ref": "#/$defs/McpServer" + }, + "type": "array" + } + }, + "required": [ + "cwd", + "mcpServers" + ], + "type": "object", + "x-method": "session/new", + "x-side": "agent" + }, + "NewSessionResponse": { + "description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "type": [ + "array", + "null" + ] + }, + "models": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModelState" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + }, + "modes": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation." + } + }, + "required": [ + "sessionId" + ], + "type": "object", + "x-method": "session/new", + "x-side": "agent" + }, + "NumberPropertySchema": { + "description": "Schema for number (floating-point) properties in an elicitation form.", + "properties": { + "default": { + "description": "Default value.", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "maximum": { + "description": "Maximum value (inclusive).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "minimum": { + "description": "Minimum value (inclusive).", + "format": "double", + "type": [ + "number", + "null" + ] + }, + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "PermissionOption": { + "description": "An option presented to the user when requesting permission.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "kind": { + "allOf": [ + { + "$ref": "#/$defs/PermissionOptionKind" + } + ], + "description": "Hint about the nature of this permission option." + }, + "name": { + "description": "Human-readable label to display to the user.", + "type": "string" + }, + "optionId": { + "allOf": [ + { + "$ref": "#/$defs/PermissionOptionId" + } + ], + "description": "Unique identifier for this permission option." + } + }, + "required": [ + "optionId", + "name", + "kind" + ], + "type": "object" + }, + "PermissionOptionId": { + "description": "Unique identifier for a permission option.", + "type": "string" + }, + "PermissionOptionKind": { + "description": "The type of permission option being presented to the user.\n\nHelps clients choose appropriate icons and UI treatment.", + "oneOf": [ + { + "const": "allow_once", + "description": "Allow this operation only this time.", + "type": "string" + }, + { + "const": "allow_always", + "description": "Allow this operation and remember the choice.", + "type": "string" + }, + { + "const": "reject_once", + "description": "Reject this operation only this time.", + "type": "string" + }, + { + "const": "reject_always", + "description": "Reject this operation and remember the choice.", + "type": "string" + } + ] + }, + "Plan": { + "description": "An execution plan for accomplishing complex tasks.\n\nPlans consist of multiple entries representing individual tasks or goals.\nAgents report plans to clients to provide visibility into their execution strategy.\nPlans can evolve during execution as the agent discovers new requirements or completes tasks.\n\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "entries": { + "description": "The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update.", + "items": { + "$ref": "#/$defs/PlanEntry" + }, + "type": "array" + } + }, + "required": [ + "entries" + ], + "type": "object" + }, + "PlanEntry": { + "description": "A single entry in the execution plan.\n\nRepresents a task or goal that the assistant intends to accomplish\nas part of fulfilling the user's request.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "content": { + "description": "Human-readable description of what this task aims to accomplish.", + "type": "string" + }, + "priority": { + "allOf": [ + { + "$ref": "#/$defs/PlanEntryPriority" + } + ], + "description": "The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." + }, + "status": { + "allOf": [ + { + "$ref": "#/$defs/PlanEntryStatus" + } + ], + "description": "Current execution status of this task." + } + }, + "required": [ + "content", + "priority", + "status" + ], + "type": "object" + }, + "PlanEntryPriority": { + "description": "Priority levels for plan entries.\n\nUsed to indicate the relative importance or urgency of different\ntasks in the execution plan.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "oneOf": [ + { + "const": "high", + "description": "High priority task - critical to the overall goal.", + "type": "string" + }, + { + "const": "medium", + "description": "Medium priority task - important but not critical.", + "type": "string" + }, + { + "const": "low", + "description": "Low priority task - nice to have but not essential.", + "type": "string" + } + ] + }, + "PlanEntryStatus": { + "description": "Status of a plan entry in the execution flow.\n\nTracks the lifecycle of each task from planning through completion.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "oneOf": [ + { + "const": "pending", + "description": "The task has not started yet.", + "type": "string" + }, + { + "const": "in_progress", + "description": "The task is currently being worked on.", + "type": "string" + }, + { + "const": "completed", + "description": "The task has been successfully completed.", + "type": "string" + } + ] + }, + "Position": { + "description": "A zero-based position in a text document.\n\nThe meaning of `character` depends on the negotiated position encoding.", + "properties": { + "character": { + "description": "Zero-based character offset (encoding-dependent).", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "line": { + "description": "Zero-based line number.", + "format": "uint32", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "line", + "character" + ], + "type": "object" + }, + "PositionEncodingKind": { + "description": "The encoding used for character offsets in positions.\n\nFollows the same conventions as LSP 3.17. The default is UTF-16.", + "oneOf": [ + { + "const": "utf-16", + "description": "Character offsets count UTF-16 code units. This is the default.", + "type": "string" + }, + { + "const": "utf-32", + "description": "Character offsets count Unicode code points.", + "type": "string" + }, + { + "const": "utf-8", + "description": "Character offsets count UTF-8 code units (bytes).", + "type": "string" + } + ] + }, + "PromptCapabilities": { + "description": "Prompt capabilities supported by the agent in `session/prompt` requests.\n\nBaseline agent functionality requires support for [`ContentBlock::Text`]\nand [`ContentBlock::ResourceLink`] in prompt requests.\n\nOther variants must be explicitly opted in to.\nCapabilities for different types of content in prompt requests.\n\nIndicates which content types beyond the baseline (text and resource links)\nthe agent can process.\n\nSee protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "audio": { + "default": false, + "description": "Agent supports [`ContentBlock::Audio`].", + "type": "boolean" + }, + "embeddedContext": { + "default": false, + "description": "Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", + "type": "boolean" + }, + "image": { + "default": false, + "description": "Agent supports [`ContentBlock::Image`].", + "type": "boolean" + } + }, + "type": "object" + }, + "PromptRequest": { + "description": "Request parameters for sending a user prompt to the agent.\n\nContains the user's message and any additional context.\n\nSee protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "messageId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", + "type": [ + "string", + "null" + ] + }, + "prompt": { + "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", + "items": { + "$ref": "#/$defs/ContentBlock" + }, + "type": "array" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to send this user message to" + } + }, + "required": [ + "sessionId", + "prompt" + ], + "type": "object", + "x-method": "session/prompt", + "x-side": "agent" + }, + "PromptResponse": { + "description": "Response from processing a user prompt.\n\nSee protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "stopReason": { + "allOf": [ + { + "$ref": "#/$defs/StopReason" + } + ], + "description": "Indicates why the agent stopped processing the turn." + }, + "usage": { + "anyOf": [ + { + "$ref": "#/$defs/Usage" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." + }, + "userMessageId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "stopReason" + ], + "type": "object", + "x-method": "session/prompt", + "x-side": "agent" + }, + "ProtocolVersion": { + "description": "Protocol version identifier.\n\nThis version is only bumped for breaking changes.\nNon-breaking changes should be introduced via capabilities.", + "format": "uint16", + "maximum": 65535, + "minimum": 0, + "type": "integer" + }, + "ProviderCurrentConfig": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCurrent effective non-secret routing configuration for a provider.", + "properties": { + "apiType": { + "allOf": [ + { + "$ref": "#/$defs/LlmProtocol" + } + ], + "description": "Protocol currently used by this provider." + }, + "baseUrl": { + "description": "Base URL currently used by this provider.", + "type": "string" + } + }, + "required": [ + "apiType", + "baseUrl" + ], + "type": "object" + }, + "ProviderInfo": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a configurable LLM provider.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "current": { + "anyOf": [ + { + "$ref": "#/$defs/ProviderCurrentConfig" + }, + { + "type": "null" + } + ], + "description": "Current effective non-secret routing config.\nNull or omitted means provider is disabled." + }, + "id": { + "description": "Provider identifier, for example \"main\" or \"openai\".", + "type": "string" + }, + "required": { + "description": "Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id.", + "type": "boolean" + }, + "supported": { + "description": "Supported protocol types for this provider.", + "items": { + "$ref": "#/$defs/LlmProtocol" + }, + "type": "array" + } + }, + "required": [ + "id", + "supported", + "required" + ], + "type": "object" + }, + "ProvidersCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "Range": { + "description": "A range in a text document, expressed as start and end positions.", + "properties": { + "end": { + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ], + "description": "The end position (exclusive)." + }, + "start": { + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ], + "description": "The start position (inclusive)." + } + }, + "required": [ + "start", + "end" + ], + "type": "object" + }, + "ReadTextFileRequest": { + "description": "Request to read content from a text file.\n\nOnly available if the client supports the `fs.readTextFile` capability.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "limit": { + "description": "Maximum number of lines to read.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "line": { + "description": "Line number to start reading from (1-based).", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "path": { + "description": "Absolute path to the file to read.", + "type": "string" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this request." + } + }, + "required": [ + "sessionId", + "path" + ], + "type": "object", + "x-method": "fs/read_text_file", + "x-side": "client" + }, + "ReadTextFileResponse": { + "description": "Response containing the contents of a text file.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "content": { + "type": "string" + } + }, + "required": [ + "content" + ], + "type": "object", + "x-method": "fs/read_text_file", + "x-side": "client" + }, + "RejectNesNotification": { + "description": "Notification sent when a suggestion is rejected.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "id": { + "description": "The ID of the rejected suggestion.", + "type": "string" + }, + "reason": { + "anyOf": [ + { + "$ref": "#/$defs/NesRejectReason" + }, + { + "type": "null" + } + ], + "description": "The reason for rejection." + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this notification." + } + }, + "required": [ + "sessionId", + "id" + ], + "type": "object", + "x-method": "nes/reject", + "x-side": "agent" + }, + "ReleaseTerminalRequest": { + "description": "Request to release a terminal and free its resources.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this request." + }, + "terminalId": { + "description": "The ID of the terminal to release.", + "type": "string" + } + }, + "required": [ + "sessionId", + "terminalId" + ], + "type": "object", + "x-method": "terminal/release", + "x-side": "client" + }, + "ReleaseTerminalResponse": { + "description": "Response to terminal/release method", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "terminal/release", + "x-side": "client" + }, + "RequestId": { + "anyOf": [ + { + "title": "Null", + "type": "null" + }, + { + "format": "int64", + "title": "Number", + "type": "integer" + }, + { + "title": "Str", + "type": "string" + } + ], + "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + }, + "RequestPermissionOutcome": { + "description": "The outcome of a permission request.", + "discriminator": { + "propertyName": "outcome" + }, + "oneOf": [ + { + "description": "The prompt turn was cancelled before the user responded.\n\nWhen a client sends a `session/cancel` notification to cancel an ongoing\nprompt turn, it MUST respond to all pending `session/request_permission`\nrequests with this `Cancelled` outcome.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "properties": { + "outcome": { + "const": "cancelled", + "type": "string" + } + }, + "required": [ + "outcome" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SelectedPermissionOutcome" + } + ], + "description": "The user selected one of the provided options.", + "properties": { + "outcome": { + "const": "selected", + "type": "string" + } + }, + "required": [ + "outcome" + ], + "type": "object" + } + ] + }, + "RequestPermissionRequest": { + "description": "Request for user permission to execute a tool call.\n\nSent when the agent needs authorization before performing a sensitive operation.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "options": { + "description": "Available permission options for the user to choose from.", + "items": { + "$ref": "#/$defs/PermissionOption" + }, + "type": "array" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for this request." + }, + "toolCall": { + "allOf": [ + { + "$ref": "#/$defs/ToolCallUpdate" + } + ], + "description": "Details about the tool call requiring permission." + } + }, + "required": [ + "sessionId", + "toolCall", + "options" + ], + "type": "object", + "x-method": "session/request_permission", + "x-side": "client" + }, + "RequestPermissionResponse": { + "description": "Response to a permission request.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "outcome": { + "allOf": [ + { + "$ref": "#/$defs/RequestPermissionOutcome" + } + ], + "description": "The user's decision on the permission request." + } + }, + "required": [ + "outcome" + ], + "type": "object", + "x-method": "session/request_permission", + "x-side": "client" + }, + "ResourceLink": { + "description": "A resource that the server is capable of reading, included in a prompt or tool call result.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "annotations": { + "anyOf": [ + { + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "mimeType": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "size": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "uri": { + "type": "string" + } + }, + "required": [ + "name", + "uri" + ], + "type": "object" + }, + "ResumeSessionRequest": { + "description": "Request parameters for resuming an existing session.\n\nResumes an existing session without returning previous messages (unlike `session/load`).\nThis is useful for agents that can resume sessions but don't implement full session loading.\n\nOnly available if the Agent supports the `sessionCapabilities.resume` capability.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession.", + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "description": "The working directory for this session.", + "type": "string" + }, + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "items": { + "$ref": "#/$defs/McpServer" + }, + "type": "array" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to resume." + } + }, + "required": [ + "sessionId", + "cwd" + ], + "type": "object", + "x-method": "session/resume", + "x-side": "agent" + }, + "ResumeSessionResponse": { + "description": "Response from resuming an existing session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "type": [ + "array", + "null" + ] + }, + "models": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModelState" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + }, + "modes": { + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + } + }, + "type": "object", + "x-method": "session/resume", + "x-side": "agent" + }, + "Role": { + "description": "The sender or recipient of messages and data in a conversation.", + "enum": [ + "assistant", + "user" + ], + "type": "string" + }, + "SelectedPermissionOutcome": { + "description": "The user selected one of the provided options.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "optionId": { + "allOf": [ + { + "$ref": "#/$defs/PermissionOptionId" + } + ], + "description": "The ID of the option the user selected." + } + }, + "required": [ + "optionId" + ], + "type": "object" + }, + "SessionAdditionalDirectoriesCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories` field on\nsupported session lifecycle requests and `session/list`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionCapabilities": { + "description": "Session capabilities supported by the agent.\n\nAs a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.\n\nOptionally, they **MAY** support other session methods and notifications by specifying additional capabilities.\n\nNote: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.\n\nSee protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "additionalDirectories": { + "anyOf": [ + { + "$ref": "#/$defs/SessionAdditionalDirectoriesCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`." + }, + "close": { + "anyOf": [ + { + "$ref": "#/$defs/SessionCloseCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent supports `session/close`." + }, + "fork": { + "anyOf": [ + { + "$ref": "#/$defs/SessionForkCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + }, + "list": { + "anyOf": [ + { + "$ref": "#/$defs/SessionListCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent supports `session/list`." + }, + "resume": { + "anyOf": [ + { + "$ref": "#/$defs/SessionResumeCapabilities" + }, + { + "type": "null" + } + ], + "description": "Whether the agent supports `session/resume`." + } + }, + "type": "object" + }, + "SessionCloseCapabilities": { + "description": "Capabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionConfigBoolean": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", + "properties": { + "currentValue": { + "description": "The current value of the boolean option.", + "type": "boolean" + } + }, + "required": [ + "currentValue" + ], + "type": "object" + }, + "SessionConfigGroupId": { + "description": "Unique identifier for a session configuration option value group.", + "type": "string" + }, + "SessionConfigId": { + "description": "Unique identifier for a session configuration option.", + "type": "string" + }, + "SessionConfigOption": { + "description": "A session configuration option selector and its current state.", + "discriminator": { + "propertyName": "type" + }, + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigSelect" + } + ], + "description": "Single-value selector (dropdown).", + "properties": { + "type": { + "const": "select", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigBoolean" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", + "properties": { + "type": { + "const": "boolean", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ], + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "category": { + "anyOf": [ + { + "$ref": "#/$defs/SessionConfigOptionCategory" + }, + { + "type": "null" + } + ], + "description": "Optional semantic category for this option (UX only)." + }, + "description": { + "description": "Optional description for the Client to display to the user.", + "type": [ + "string", + "null" + ] + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigId" + } + ], + "description": "Unique identifier for the configuration option." + }, + "name": { + "description": "Human-readable label for the option.", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "SessionConfigOptionCategory": { + "anyOf": [ + { + "const": "mode", + "description": "Session mode selector.", + "type": "string" + }, + { + "const": "model", + "description": "Model selector.", + "type": "string" + }, + { + "const": "thought_level", + "description": "Thought/reasoning level selector.", + "type": "string" + }, + { + "description": "Unknown / uncategorized selector.", + "title": "other", + "type": "string" + } + ], + "description": "Semantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec." + }, + "SessionConfigSelect": { + "description": "A single-value selector (dropdown) session configuration option payload.", + "properties": { + "currentValue": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigValueId" + } + ], + "description": "The currently selected value." + }, + "options": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigSelectOptions" + } + ], + "description": "The set of selectable options." + } + }, + "required": [ + "currentValue", + "options" + ], + "type": "object" + }, + "SessionConfigSelectGroup": { + "description": "A group of possible values for a session configuration option.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "group": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigGroupId" + } + ], + "description": "Unique identifier for this group." + }, + "name": { + "description": "Human-readable label for this group.", + "type": "string" + }, + "options": { + "description": "The set of option values in this group.", + "items": { + "$ref": "#/$defs/SessionConfigSelectOption" + }, + "type": "array" + } + }, + "required": [ + "group", + "name", + "options" + ], + "type": "object" + }, + "SessionConfigSelectOption": { + "description": "A possible value for a session configuration option.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "description": { + "description": "Optional description for this option value.", + "type": [ + "string", + "null" + ] + }, + "name": { + "description": "Human-readable label for this option value.", + "type": "string" + }, + "value": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigValueId" + } + ], + "description": "Unique identifier for this option value." + } + }, + "required": [ + "value", + "name" + ], + "type": "object" + }, + "SessionConfigSelectOptions": { + "anyOf": [ + { + "description": "A flat list of options with no grouping.", + "items": { + "$ref": "#/$defs/SessionConfigSelectOption" + }, + "title": "Ungrouped", + "type": "array" + }, + { + "description": "A list of options grouped under headers.", + "items": { + "$ref": "#/$defs/SessionConfigSelectGroup" + }, + "title": "Grouped", + "type": "array" + } + ], + "description": "Possible values for a session configuration option." + }, + "SessionConfigValueId": { + "description": "Unique identifier for a session configuration option value.", + "type": "string" + }, + "SessionForkCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionId": { + "description": "A unique identifier for a conversation session between a client and agent.\n\nSessions maintain their own context, conversation history, and state,\nallowing multiple independent interactions with the same agent.\n\nSee protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)", + "type": "string" + }, + "SessionInfo": { + "description": "Information about a session returned by session/list", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "additionalDirectories": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthoritative ordered additional workspace roots for this session. Each path must be absolute.\n\nWhen omitted or empty, there are no additional roots for the session.", + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "description": "The working directory for this session. Must be an absolute path.", + "type": "string" + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "Unique identifier for the session" + }, + "title": { + "description": "Human-readable title for the session", + "type": [ + "string", + "null" + ] + }, + "updatedAt": { + "description": "ISO 8601 timestamp of last activity", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "sessionId", + "cwd" + ], + "type": "object" + }, + "SessionInfoUpdate": { + "description": "Update to session metadata. All fields are optional to support partial updates.\n\nAgents send this notification to update session information like title or custom metadata.\nThis allows clients to display dynamic session names and track session state changes.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "title": { + "description": "Human-readable title for the session. Set to null to clear.", + "type": [ + "string", + "null" + ] + }, + "updatedAt": { + "description": "ISO 8601 timestamp of last activity. Set to null to clear.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "SessionListCapabilities": { + "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionMode": { + "description": "A mode the agent can operate in.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "id": { + "$ref": "#/$defs/SessionModeId" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "SessionModeId": { + "description": "Unique identifier for a Session Mode.", + "type": "string" + }, + "SessionModeState": { + "description": "The set of modes and the one currently active.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "availableModes": { + "description": "The set of modes that the Agent can operate in", + "items": { + "$ref": "#/$defs/SessionMode" + }, + "type": "array" + }, + "currentModeId": { + "allOf": [ + { + "$ref": "#/$defs/SessionModeId" + } + ], + "description": "The current mode the Agent is in." + } + }, + "required": [ + "currentModeId", + "availableModes" + ], + "type": "object" + }, + "SessionModelState": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe set of models and the one currently active.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "availableModels": { + "description": "The set of models that the Agent can use", + "items": { + "$ref": "#/$defs/ModelInfo" + }, + "type": "array" + }, + "currentModelId": { + "allOf": [ + { + "$ref": "#/$defs/ModelId" + } + ], + "description": "The current model the Agent is in." + } + }, + "required": [ + "currentModelId", + "availableModels" + ], + "type": "object" + }, + "SessionNotification": { + "description": "Notification containing a session update from the agent.\n\nUsed to stream real-time progress and results during prompt processing.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session this update pertains to." + }, + "update": { + "allOf": [ + { + "$ref": "#/$defs/SessionUpdate" + } + ], + "description": "The actual update content." + } + }, + "required": [ + "sessionId", + "update" + ], + "type": "object", + "x-method": "session/update", + "x-side": "client" + }, + "SessionResumeCapabilities": { + "description": "Capabilities for the `session/resume` method.\n\nBy supplying `{}` it means that the agent supports resuming of sessions.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "SessionUpdate": { + "description": "Different types of updates that can be sent during session processing.\n\nThese updates provide real-time feedback about the agent's progress.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "discriminator": { + "propertyName": "sessionUpdate" + }, + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } + ], + "description": "A chunk of the user's message being streamed.", + "properties": { + "sessionUpdate": { + "const": "user_message_chunk", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } + ], + "description": "A chunk of the agent's response being streamed.", + "properties": { + "sessionUpdate": { + "const": "agent_message_chunk", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } + ], + "description": "A chunk of the agent's internal reasoning being streamed.", + "properties": { + "sessionUpdate": { + "const": "agent_thought_chunk", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ToolCall" + } + ], + "description": "Notification that a new tool call has been initiated.", + "properties": { + "sessionUpdate": { + "const": "tool_call", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/ToolCallUpdate" + } + ], + "description": "Update on the status or results of a tool call.", + "properties": { + "sessionUpdate": { + "const": "tool_call_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/Plan" + } + ], + "description": "The agent's execution plan for complex tasks.\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "properties": { + "sessionUpdate": { + "const": "plan", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/AvailableCommandsUpdate" + } + ], + "description": "Available commands are ready or have changed", + "properties": { + "sessionUpdate": { + "const": "available_commands_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/CurrentModeUpdate" + } + ], + "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "properties": { + "sessionUpdate": { "const": "current_mode_update", "type": "string" } @@ -4067,216 +6951,537 @@ ], "type": "object" }, - { + { + "allOf": [ + { + "$ref": "#/$defs/ConfigOptionUpdate" + } + ], + "description": "Session configuration options have been updated.", + "properties": { + "sessionUpdate": { + "const": "config_option_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/SessionInfoUpdate" + } + ], + "description": "Session metadata has been updated (title, timestamps, custom metadata)", + "properties": { + "sessionUpdate": { + "const": "session_info_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/UsageUpdate" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.", + "properties": { + "sessionUpdate": { + "const": "usage_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + } + ] + }, + "SetProvidersRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider id.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "apiType": { + "allOf": [ + { + "$ref": "#/$defs/LlmProtocol" + } + ], + "description": "Protocol type for this provider." + }, + "baseUrl": { + "description": "Base URL for requests sent through this provider.", + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers.", + "type": "object" + }, + "id": { + "description": "Provider id to configure.", + "type": "string" + } + }, + "required": [ + "id", + "apiType", + "baseUrl" + ], + "type": "object", + "x-method": "providers/set", + "x-side": "agent" + }, + "SetProvidersResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/set`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "providers/set", + "x-side": "agent" + }, + "SetSessionConfigOptionRequest": { + "anyOf": [ + { + "description": "A boolean value (`type: \"boolean\"`).", + "properties": { + "type": { + "const": "boolean", + "type": "string" + }, + "value": { + "description": "The boolean value.", + "type": "boolean" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "description": "A [`SessionConfigValueId`] string value.\n\nThis is the default when `type` is absent on the wire. Unknown `type`\nvalues with string payloads also gracefully deserialize into this\nvariant.", + "properties": { + "value": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigValueId" + } + ], + "description": "The value ID." + } + }, + "required": [ + "value" + ], + "title": "value_id", + "type": "object" + } + ], + "description": "Request parameters for setting a session configuration option.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "configId": { + "allOf": [ + { + "$ref": "#/$defs/SessionConfigId" + } + ], + "description": "The ID of the configuration option to set." + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to set the configuration option for." + } + }, + "required": [ + "sessionId", + "configId" + ], + "type": "object", + "x-method": "session/set_config_option", + "x-side": "agent" + }, + "SetSessionConfigOptionResponse": { + "description": "Response to `session/set_config_option` method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "configOptions": { + "description": "The full set of configuration options and their current values.", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "type": "array" + } + }, + "required": [ + "configOptions" + ], + "type": "object", + "x-method": "session/set_config_option", + "x-side": "agent" + }, + "SetSessionModeRequest": { + "description": "Request parameters for setting a session mode.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "modeId": { "allOf": [ { - "$ref": "#/$defs/ConfigOptionUpdate" - } - ], - "description": "Session configuration options have been updated.", - "properties": { - "sessionUpdate": { - "const": "config_option_update", - "type": "string" + "$ref": "#/$defs/SessionModeId" } - }, - "required": [ - "sessionUpdate" ], - "type": "object" + "description": "The ID of the mode to set." }, - { + "sessionId": { "allOf": [ { - "$ref": "#/$defs/SessionInfoUpdate" - } - ], - "description": "Session metadata has been updated (title, timestamps, custom metadata)", - "properties": { - "sessionUpdate": { - "const": "session_info_update", - "type": "string" + "$ref": "#/$defs/SessionId" } - }, - "required": [ - "sessionUpdate" ], - "type": "object" + "description": "The ID of the session to set the mode for." + } + }, + "required": [ + "sessionId", + "modeId" + ], + "type": "object", + "x-method": "session/set_mode", + "x-side": "agent" + }, + "SetSessionModeResponse": { + "description": "Response to `session/set_mode` method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "session/set_mode", + "x-side": "agent" + }, + "SetSessionModelRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for setting a session model.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] }, - { + "modelId": { "allOf": [ { - "$ref": "#/$defs/UsageUpdate" + "$ref": "#/$defs/ModelId" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.", - "properties": { - "sessionUpdate": { - "const": "usage_update", - "type": "string" + "description": "The ID of the model to set." + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" } - }, - "required": [ - "sessionUpdate" ], - "type": "object" + "description": "The ID of the session to set the model for." } - ] + }, + "required": [ + "sessionId", + "modelId" + ], + "type": "object", + "x-method": "session/set_model", + "x-side": "agent" }, - "SetSessionConfigOptionRequest": { - "anyOf": [ - { - "description": "A boolean value (`type: \"boolean\"`).", - "properties": { - "type": { - "const": "boolean", - "type": "string" + "SetSessionModelResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `session/set_model` method.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "session/set_model", + "x-side": "agent" + }, + "StartNesRequest": { + "description": "Request to start an NES session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "repository": { + "anyOf": [ + { + "$ref": "#/$defs/NesRepository" }, - "value": { - "description": "The boolean value.", - "type": "boolean" + { + "type": "null" } - }, - "required": [ - "type", - "value" ], - "type": "object" + "description": "Repository metadata, if the workspace is a git repository." }, - { - "description": "A [`SessionConfigValueId`] string value.\n\nThis is the default when `type` is absent on the wire. Unknown `type`\nvalues with string payloads also gracefully deserialize into this\nvariant.", - "properties": { - "value": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } - ], - "description": "The value ID." - } + "workspaceFolders": { + "description": "The workspace folders.", + "items": { + "$ref": "#/$defs/WorkspaceFolder" }, - "required": [ - "value" - ], - "title": "value_id", - "type": "object" + "type": [ + "array", + "null" + ] + }, + "workspaceUri": { + "description": "The root URI of the workspace.", + "type": [ + "string", + "null" + ] } - ], - "description": "Request parameters for setting a session configuration option.", + }, + "type": "object", + "x-method": "nes/start", + "x-side": "agent" + }, + "StartNesResponse": { + "description": "Response to `nes/start`.", "properties": { "_meta": { "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "object", + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The session ID for the newly started NES session." + } + }, + "required": [ + "sessionId" + ], + "type": "object", + "x-method": "nes/start", + "x-side": "agent" + }, + "StopReason": { + "description": "Reasons why an agent stops processing a prompt turn.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)", + "oneOf": [ + { + "const": "end_turn", + "description": "The turn ended successfully.", + "type": "string" + }, + { + "const": "max_tokens", + "description": "The turn ended because the agent reached the maximum number of tokens.", + "type": "string" + }, + { + "const": "max_turn_requests", + "description": "The turn ended because the agent reached the maximum number of allowed\nagent requests between user turns.", + "type": "string" + }, + { + "const": "refusal", + "description": "The turn ended because the agent refused to continue. The user prompt\nand everything that comes after it won't be included in the next\nprompt, so this should be reflected in the UI.", + "type": "string" + }, + { + "const": "cancelled", + "description": "The turn was cancelled by the client via `session/cancel`.\n\nThis stop reason MUST be returned when the client sends a `session/cancel`\nnotification, even if the cancellation causes exceptions in underlying operations.\nAgents should catch these exceptions and return this semantically meaningful\nresponse to confirm successful cancellation.", + "type": "string" + } + ] + }, + "StringFormat": { + "description": "String format types for string properties in elicitation schemas.", + "oneOf": [ + { + "const": "email", + "description": "Email address format.", + "type": "string" + }, + { + "const": "uri", + "description": "URI format.", + "type": "string" + }, + { + "const": "date", + "description": "Date format (YYYY-MM-DD).", + "type": "string" + }, + { + "const": "date-time", + "description": "Date-time format (ISO 8601).", + "type": "string" + } + ] + }, + "StringPropertySchema": { + "description": "Schema for string properties in an elicitation form.\n\nWhen `enum` or `oneOf` is set, this represents a single-select enum\nwith `\"type\": \"string\"`.", + "properties": { + "default": { + "description": "Default value.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", "null" ] }, - "configId": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigId" - } - ], - "description": "The ID of the configuration option to set." + "enum": { + "description": "Enum values for untitled single-select enums.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] }, - "sessionId": { - "allOf": [ + "format": { + "anyOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/StringFormat" + }, + { + "type": "null" } ], - "description": "The ID of the session to set the configuration option for." - } - }, - "required": [ - "sessionId", - "configId" - ], - "type": "object", - "x-method": "session/set_config_option", - "x-side": "agent" - }, - "SetSessionConfigOptionResponse": { - "description": "Response to `session/set_config_option` method.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "description": "String format." + }, + "maxLength": { + "description": "Maximum string length.", + "format": "uint32", + "minimum": 0, "type": [ - "object", + "integer", "null" ] }, - "configOptions": { - "description": "The full set of configuration options and their current values.", + "minLength": { + "description": "Minimum string length.", + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "oneOf": { + "description": "Titled enum options for titled single-select enums.", "items": { - "$ref": "#/$defs/SessionConfigOption" + "$ref": "#/$defs/EnumOption" }, - "type": "array" - } - }, - "required": [ - "configOptions" - ], - "type": "object", - "x-method": "session/set_config_option", - "x-side": "agent" - }, - "SetSessionModeRequest": { - "description": "Request parameters for setting a session mode.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "object", + "array", "null" ] }, - "modeId": { - "allOf": [ - { - "$ref": "#/$defs/SessionModeId" - } - ], - "description": "The ID of the mode to set." + "pattern": { + "description": "Pattern the string must match.", + "type": [ + "string", + "null" + ] }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session to set the mode for." - } - }, - "required": [ - "sessionId", - "modeId" - ], - "type": "object", - "x-method": "session/set_mode", - "x-side": "agent" - }, - "SetSessionModeResponse": { - "description": "Response to `session/set_mode` method.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "title": { + "description": "Optional title for the property.", "type": [ - "object", + "string", "null" ] } }, - "type": "object", - "x-method": "session/set_mode", - "x-side": "agent" + "type": "object" }, - "SetSessionModelRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for setting a session model.", + "SuggestNesRequest": { + "description": "Request for a code suggestion.", "properties": { "_meta": { "additionalProperties": true, @@ -4286,13 +7491,35 @@ "null" ] }, - "modelId": { + "context": { + "anyOf": [ + { + "$ref": "#/$defs/NesSuggestContext" + }, + { + "type": "null" + } + ], + "description": "Context for the suggestion, included based on agent capabilities." + }, + "position": { "allOf": [ { - "$ref": "#/$defs/ModelId" + "$ref": "#/$defs/Position" } ], - "description": "The ID of the model to set." + "description": "The current cursor position." + }, + "selection": { + "anyOf": [ + { + "$ref": "#/$defs/Range" + }, + { + "type": "null" + } + ], + "description": "The current text selection range, if any." }, "sessionId": { "allOf": [ @@ -4300,19 +7527,39 @@ "$ref": "#/$defs/SessionId" } ], - "description": "The ID of the session to set the model for." + "description": "The session ID for this request." + }, + "triggerKind": { + "allOf": [ + { + "$ref": "#/$defs/NesTriggerKind" + } + ], + "description": "What triggered this suggestion request." + }, + "uri": { + "description": "The URI of the document to suggest for.", + "type": "string" + }, + "version": { + "description": "The version number of the document.", + "format": "int64", + "type": "integer" } }, "required": [ "sessionId", - "modelId" + "uri", + "version", + "position", + "triggerKind" ], "type": "object", - "x-method": "session/set_model", + "x-method": "nes/suggest", "x-side": "agent" }, - "SetSessionModelResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `session/set_model` method.", + "SuggestNesResponse": { + "description": "Response to `nes/suggest`.", "properties": { "_meta": { "additionalProperties": true, @@ -4321,42 +7568,22 @@ "object", "null" ] + }, + "suggestions": { + "description": "The list of suggestions.", + "items": { + "$ref": "#/$defs/NesSuggestion" + }, + "type": "array" } }, + "required": [ + "suggestions" + ], "type": "object", - "x-method": "session/set_model", + "x-method": "nes/suggest", "x-side": "agent" }, - "StopReason": { - "description": "Reasons why an agent stops processing a prompt turn.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)", - "oneOf": [ - { - "const": "end_turn", - "description": "The turn ended successfully.", - "type": "string" - }, - { - "const": "max_tokens", - "description": "The turn ended because the agent reached the maximum number of tokens.", - "type": "string" - }, - { - "const": "max_turn_requests", - "description": "The turn ended because the agent reached the maximum number of allowed\nagent requests between user turns.", - "type": "string" - }, - { - "const": "refusal", - "description": "The turn ended because the agent refused to continue. The user prompt\nand everything that comes after it won't be included in the next\nprompt, so this should be reflected in the UI.", - "type": "string" - }, - { - "const": "cancelled", - "description": "The turn was cancelled by the client via `session/cancel`.\n\nThis stop reason MUST be returned when the client sends a `session/cancel`\nnotification, even if the cancellation causes exceptions in underlying operations.\nAgents should catch these exceptions and return this semantically meaningful\nresponse to confirm successful cancellation.", - "type": "string" - } - ] - }, "Terminal": { "description": "Embed a terminal created with `terminal/create` by its id.\n\nThe terminal must be added before calling `terminal/release`.\n\nSee protocol docs: [Terminal](https://agentclientprotocol.com/protocol/terminals)", "properties": { @@ -4508,6 +7735,45 @@ ], "type": "object" }, + "TextDocumentContentChangeEvent": { + "description": "A content change event for a document.\n\nWhen `range` is `None`, `text` is the full content of the document.\nWhen `range` is `Some`, `text` replaces the given range.", + "properties": { + "range": { + "anyOf": [ + { + "$ref": "#/$defs/Range" + }, + { + "type": "null" + } + ], + "description": "The range of the document that changed. If `None`, the entire content is replaced." + }, + "text": { + "description": "The new text for the range, or the full document content if `range` is `None`.", + "type": "string" + } + }, + "required": [ + "text" + ], + "type": "object" + }, + "TextDocumentSyncKind": { + "description": "How the agent wants document changes delivered.", + "oneOf": [ + { + "const": "full", + "description": "Client sends the entire file content on each change.", + "type": "string" + }, + { + "const": "incremental", + "description": "Client sends only the changed ranges.", + "type": "string" + } + ] + }, "TextResourceContents": { "description": "Text-based resource contents.", "properties": { @@ -4538,6 +7804,22 @@ ], "type": "object" }, + "TitledMultiSelectItems": { + "description": "Items definition for titled multi-select enum properties.", + "properties": { + "anyOf": { + "description": "Titled enum options.", + "items": { + "$ref": "#/$defs/EnumOption" + }, + "type": "array" + } + }, + "required": [ + "anyOf" + ], + "type": "object" + }, "ToolCall": { "description": "Represents a tool call that the language model has requested.\n\nTool calls are actions that the agent executes on behalf of the language model,\nsuch as reading files, executing code, or fetching data from external sources.\n\nSee protocol docs: [Tool Calls](https://agentclientprotocol.com/protocol/tool-calls)", "properties": { @@ -4881,6 +8163,31 @@ ], "type": "object" }, + "UntitledMultiSelectItems": { + "description": "Items definition for untitled multi-select enum properties.", + "properties": { + "enum": { + "description": "Allowed enum values.", + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "allOf": [ + { + "$ref": "#/$defs/ElicitationStringType" + } + ], + "description": "Item type discriminator. Must be `\"string\"`." + } + }, + "required": [ + "type", + "enum" + ], + "type": "object" + }, "Usage": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage information for a prompt turn.", "properties": { @@ -5042,6 +8349,24 @@ "x-method": "terminal/wait_for_exit", "x-side": "client" }, + "WorkspaceFolder": { + "description": "A workspace folder.", + "properties": { + "name": { + "description": "The display name of the folder.", + "type": "string" + }, + "uri": { + "description": "The URI of the folder.", + "type": "string" + } + }, + "required": [ + "uri", + "name" + ], + "type": "object" + }, "WriteTextFileRequest": { "description": "Request to write content to a text file.\n\nOnly available if the client supports the `fs.writeTextFile` capability.", "properties": { diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index ad9c6fb..9a181c9 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -71,6 +71,24 @@ "ToolCallContent1": "ContentToolCallContent", "ToolCallContent2": "FileEditToolCallContent", "ToolCallContent3": "TerminalToolCallContent", + "CreateElicitationRequest1": "CreateFormElicitationRequest", + "CreateElicitationRequest2": "CreateUrlElicitationRequest", + "CreateElicitationResponse1": "AcceptElicitationResponse", + "CreateElicitationResponse2": "DeclineElicitationResponse", + "CreateElicitationResponse3": "CancelElicitationResponse", + "ElicitationFormMode1": "ElicitationFormSessionMode", + "ElicitationFormMode2": "ElicitationFormRequestMode", + "ElicitationPropertySchema1": "ElicitationStringPropertySchema", + "ElicitationPropertySchema2": "ElicitationNumberPropertySchema", + "ElicitationPropertySchema3": "ElicitationIntegerPropertySchema", + "ElicitationPropertySchema4": "ElicitationBooleanPropertySchema", + "ElicitationPropertySchema5": "ElicitationMultiSelectPropertySchema", + "ElicitationUrlMode1": "ElicitationUrlSessionMode", + "ElicitationUrlMode2": "ElicitationUrlRequestMode", + "NesSuggestion1": "NesEditSuggestionVariant", + "NesSuggestion2": "NesJumpSuggestionVariant", + "NesSuggestion3": "NesRenameSuggestionVariant", + "NesSuggestion4": "NesSearchAndReplaceSuggestionVariant", } ENUM_LITERAL_MAP: dict[str, tuple[str, ...]] = { diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index bb8fdc2..024884a 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -98,13 +98,22 @@ async def initialize( @param_model(NewSessionRequest) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: resolved_mcp_servers = mcp_servers or [] return await request_model( self._conn, AGENT_METHODS["session_new"], - NewSessionRequest(cwd=cwd, mcp_servers=resolved_mcp_servers, field_meta=kwargs or None), + NewSessionRequest( + cwd=cwd, + additional_directories=additional_directories, + mcp_servers=resolved_mcp_servers, + field_meta=kwargs or None, + ), NewSessionResponse, ) @@ -113,6 +122,7 @@ async def load_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> LoadSessionResponse: @@ -121,19 +131,29 @@ async def load_session( self._conn, AGENT_METHODS["session_load"], LoadSessionRequest( - cwd=cwd, mcp_servers=resolved_mcp_servers, session_id=session_id, field_meta=kwargs or None + cwd=cwd, + additional_directories=additional_directories, + mcp_servers=resolved_mcp_servers, + session_id=session_id, + field_meta=kwargs or None, ), LoadSessionResponse, ) @param_model(ListSessionsRequest) async def list_sessions( - self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any + self, + additional_directories: list[str] | None = None, + cursor: str | None = None, + cwd: str | None = None, + **kwargs: Any, ) -> ListSessionsResponse: return await request_model_from_dict( self._conn, AGENT_METHODS["session_list"], - ListSessionsRequest(cursor=cursor, cwd=cwd, field_meta=kwargs or None), + ListSessionsRequest( + additional_directories=additional_directories, cursor=cursor, cwd=cwd, field_meta=kwargs or None + ), ListSessionsResponse, ) @@ -161,25 +181,15 @@ async def set_config_option( ) -> SetSessionConfigOptionResponse: request = ( SetSessionConfigOptionBooleanRequest( - config_id=config_id, - session_id=session_id, - type="boolean", - value=value, - field_meta=kwargs or None, + config_id=config_id, session_id=session_id, type="boolean", value=value, field_meta=kwargs or None ) if isinstance(value, bool) else SetSessionConfigOptionSelectRequest( - config_id=config_id, - session_id=session_id, - value=value, - field_meta=kwargs or None, + config_id=config_id, session_id=session_id, value=value, field_meta=kwargs or None ) ) return await request_model_from_dict( - self._conn, - AGENT_METHODS["session_set_config_option"], - request, - SetSessionConfigOptionResponse, + self._conn, AGENT_METHODS["session_set_config_option"], request, SetSessionConfigOptionResponse ) @param_model(AuthenticateRequest) @@ -208,12 +218,7 @@ async def prompt( return await request_model( self._conn, AGENT_METHODS["session_prompt"], - PromptRequest( - prompt=prompt, - session_id=session_id, - message_id=message_id, - field_meta=kwargs or None, - ), + PromptRequest(prompt=prompt, session_id=session_id, message_id=message_id, field_meta=kwargs or None), PromptResponse, ) @@ -222,13 +227,20 @@ async def fork_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ForkSessionResponse: return await request_model( self._conn, AGENT_METHODS["session_fork"], - ForkSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None), + ForkSessionRequest( + session_id=session_id, + cwd=cwd, + additional_directories=additional_directories, + mcp_servers=mcp_servers, + field_meta=kwargs or None, + ), ForkSessionResponse, ) @@ -237,13 +249,20 @@ async def resume_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ResumeSessionResponse: return await request_model( self._conn, AGENT_METHODS["session_resume"], - ResumeSessionRequest(session_id=session_id, cwd=cwd, mcp_servers=mcp_servers, field_meta=kwargs or None), + ResumeSessionRequest( + session_id=session_id, + cwd=cwd, + additional_directories=additional_directories, + mcp_servers=mcp_servers, + field_meta=kwargs or None, + ), ResumeSessionResponse, ) diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 2decdb2..0568731 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -157,7 +157,11 @@ async def initialize( @param_model(NewSessionRequest) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: ... @param_model(LoadSessionRequest) @@ -165,13 +169,18 @@ async def load_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> LoadSessionResponse | None: ... @param_model(ListSessionsRequest) async def list_sessions( - self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any + self, + additional_directories: list[str] | None = None, + cursor: str | None = None, + cwd: str | None = None, + **kwargs: Any, ) -> ListSessionsResponse: ... @param_model(SetSessionModeRequest) @@ -210,6 +219,7 @@ async def fork_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ForkSessionResponse: ... @@ -219,6 +229,7 @@ async def resume_session( self, cwd: str, session_id: str, + additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ResumeSessionResponse: ... diff --git a/src/acp/meta.py b/src/acp/meta.py index bc57869..ed9a25f 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,8 +1,22 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.11.2 +# Schema ref: refs/tags/v0.12.2 AGENT_METHODS = { "authenticate": "authenticate", + "document_did_change": "document/didChange", + "document_did_close": "document/didClose", + "document_did_focus": "document/didFocus", + "document_did_open": "document/didOpen", + "document_did_save": "document/didSave", "initialize": "initialize", + "logout": "logout", + "nes_accept": "nes/accept", + "nes_close": "nes/close", + "nes_reject": "nes/reject", + "nes_start": "nes/start", + "nes_suggest": "nes/suggest", + "providers_disable": "providers/disable", + "providers_list": "providers/list", + "providers_set": "providers/set", "session_cancel": "session/cancel", "session_close": "session/close", "session_fork": "session/fork", @@ -16,6 +30,8 @@ "session_set_model": "session/set_model", } CLIENT_METHODS = { + "elicitation_complete": "elicitation/complete", + "elicitation_create": "elicitation/create", "fs_read_text_file": "fs/read_text_file", "fs_write_text_file": "fs/write_text_file", "session_request_permission": "session/request_permission", diff --git a/src/acp/schema.py b/src/acp/schema.py index 32031c4..e942245 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,12 +1,12 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.11.2 +# Schema ref: refs/tags/v0.12.2 from __future__ import annotations from enum import Enum from typing import Annotated, Any, Dict, List, Literal, Optional, Union -from pydantic import BaseModel as _BaseModel, Field, RootModel, ConfigDict +from pydantic import AnyUrl, BaseModel as _BaseModel, Field, RootModel, ConfigDict PermissionOptionKind = Literal["allow_once", "allow_always", "reject_once", "reject_always"] PlanEntryPriority = Literal["high", "medium", "low"] @@ -245,6 +245,30 @@ class BlobResourceContents(BaseModel): uri: str +class BooleanPropertySchema(BaseModel): + # Default value. + default: Annotated[Optional[bool], Field(description="Default value.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + + +class CloseNesResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class CloseSessionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -267,6 +291,38 @@ class Cost(BaseModel): currency: Annotated[str, Field(description='ISO 4217 currency code (e.g., "USD", "EUR").')] +class DeclineElicitationResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + action: Literal["decline"] + + +class CancelElicitationResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + action: Literal["cancel"] + + class CreateTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -314,6 +370,91 @@ class Diff(BaseModel): path: Annotated[str, Field(description="The file path being modified.")] +class DisableProvidersRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Provider id to disable. + id: Annotated[str, Field(description="Provider id to disable.")] + + +class DisableProvidersResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ElicitationAcceptAction(BaseModel): + # The user-provided content, if any, as an object matching the requested schema. + content: Annotated[ + Optional[Dict[str, Any]], + Field(description="The user-provided content, if any, as an object matching the requested schema."), + ] = None + + +class ElicitationContentValue(RootModel[Union[str, int, float, bool, List[str]]]): + root: Union[str, int, float, bool, List[str]] + + +class ElicitationFormCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ElicitationBooleanPropertySchema(BooleanPropertySchema): + type: Literal["boolean"] + + +class ElicitationUrlCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class EnumOption(BaseModel): + # The constant value for this option. + const: Annotated[str, Field(description="The constant value for this option.")] + # Human-readable title for this option. + title: Annotated[str, Field(description="Human-readable title for this option.")] + + class EnvVariable(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -424,6 +565,19 @@ class Implementation(BaseModel): ] +class IntegerPropertySchema(BaseModel): + # Default value. + default: Annotated[Optional[int], Field(description="Default value.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Maximum value (inclusive). + maximum: Annotated[Optional[int], Field(description="Maximum value (inclusive).")] = None + # Minimum value (inclusive). + minimum: Annotated[Optional[int], Field(description="Minimum value (inclusive).")] = None + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + + class KillTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -439,6 +593,21 @@ class KillTerminalResponse(BaseModel): ] = None +class ListProvidersRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class ListSessionsRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -452,6 +621,21 @@ class ListSessionsRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Filter sessions by the exact ordered additional workspace roots. Each path must be absolute. + # + # This filter applies only when the field is present and non-empty. When + # omitted or empty, no additional-root filter is applied. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nFilter sessions by the exact ordered additional workspace roots. Each path must be absolute.\n\nThis filter applies only when the field is present and non-empty. When\nomitted or empty, no additional-root filter is applied.", + ), + ] = None # Opaque cursor token from a previous response's nextCursor field for cursor-based pagination cursor: Annotated[ Optional[str], @@ -466,6 +650,51 @@ class ListSessionsRequest(BaseModel): ] = None +class LogoutCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class LogoutRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class LogoutResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class McpCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -583,7 +812,7 @@ class ModelInfo(BaseModel): name: Annotated[str, Field(description="Human-readable name of the model.")] -class PromptCapabilities(BaseModel): +class NesDiagnosticsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -596,24 +825,24 @@ class PromptCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Agent supports [`ContentBlock::Audio`]. - audio: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Audio`].")] = False - # Agent supports embedded context in `session/prompt` requests. + + +class NesDocumentDidCloseCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # When enabled, the Client is allowed to include [`ContentBlock::Resource`] - # in prompt requests for pieces of context that are referenced in the message. - embedded_context: Annotated[ - Optional[bool], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="embeddedContext", - description="Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] = False - # Agent supports [`ContentBlock::Image`]. - image: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Image`].")] = False + ] = None -class ReadTextFileResponse(BaseModel): +class NesDocumentDidFocusCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -626,10 +855,9 @@ class ReadTextFileResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - content: str -class ReleaseTerminalResponse(BaseModel): +class NesDocumentDidOpenCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -644,16 +872,7 @@ class ReleaseTerminalResponse(BaseModel): ] = None -class DeniedOutcome(BaseModel): - outcome: Literal["cancelled"] - - -class Role(Enum): - assistant = "assistant" - user = "user" - - -class SelectedPermissionOutcome(BaseModel): +class NesDocumentDidSaveCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -666,14 +885,9 @@ class SelectedPermissionOutcome(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the option the user selected. - option_id: Annotated[ - str, - Field(alias="optionId", description="The ID of the option the user selected."), - ] -class SessionCloseCapabilities(BaseModel): +class NesEditHistoryCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -686,17 +900,48 @@ class SessionCloseCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # Maximum number of edit history entries the agent can use. + max_count: Annotated[ + Optional[int], + Field( + alias="maxCount", + description="Maximum number of edit history entries the agent can use.", + ge=0, + ), + ] = None -class SessionConfigBoolean(BaseModel): - # The current value of the boolean option. - current_value: Annotated[ - bool, - Field(alias="currentValue", description="The current value of the boolean option."), +class NesEditHistoryEntry(BaseModel): + # A diff representing the edit. + diff: Annotated[str, Field(description="A diff representing the edit.")] + # The URI of the edited file. + uri: Annotated[str, Field(description="The URI of the edited file.")] + + +class NesExcerpt(BaseModel): + # The end line of the excerpt (zero-based). + end_line: Annotated[ + int, + Field( + alias="endLine", + description="The end line of the excerpt (zero-based).", + ge=0, + ), + ] + # The start line of the excerpt (zero-based). + start_line: Annotated[ + int, + Field( + alias="startLine", + description="The start line of the excerpt (zero-based).", + ge=0, + ), ] + # The text content of the excerpt. + text: Annotated[str, Field(description="The text content of the excerpt.")] -class SessionForkCapabilities(BaseModel): +class NesJumpCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -711,7 +956,7 @@ class SessionForkCapabilities(BaseModel): ] = None -class SessionInfo(BaseModel): +class NesOpenFilesCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -724,23 +969,18 @@ class SessionInfo(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Unique identifier for the session - session_id: Annotated[str, Field(alias="sessionId", description="Unique identifier for the session")] - # Human-readable title for the session - title: Annotated[Optional[str], Field(description="Human-readable title for the session")] = None - # ISO 8601 timestamp of last activity - updated_at: Annotated[ - Optional[str], - Field(alias="updatedAt", description="ISO 8601 timestamp of last activity"), - ] = None -class _SessionInfoUpdate(BaseModel): +class NesRecentFile(BaseModel): + # The language identifier. + language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] + # The full text content of the file. + text: Annotated[str, Field(description="The full text content of the file.")] + # The URI of the file. + uri: Annotated[str, Field(description="The URI of the file.")] + + +class NesRecentFilesCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -753,22 +993,25 @@ class _SessionInfoUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Human-readable title for the session. Set to null to clear. - title: Annotated[ - Optional[str], - Field(description="Human-readable title for the session. Set to null to clear."), - ] = None - # ISO 8601 timestamp of last activity. Set to null to clear. - updated_at: Annotated[ - Optional[str], + # Maximum number of recent files the agent can use. + max_count: Annotated[ + Optional[int], Field( - alias="updatedAt", - description="ISO 8601 timestamp of last activity. Set to null to clear.", + alias="maxCount", + description="Maximum number of recent files the agent can use.", + ge=0, ), ] = None -class SessionListCapabilities(BaseModel): +class NesRelatedSnippet(BaseModel): + # The code excerpts. + excerpts: Annotated[List[NesExcerpt], Field(description="The code excerpts.")] + # The URI of the file containing the snippets. + uri: Annotated[str, Field(description="The URI of the file containing the snippets.")] + + +class NesRelatedSnippetsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -783,7 +1026,7 @@ class SessionListCapabilities(BaseModel): ] = None -class SessionModelState(BaseModel): +class NesRenameCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -796,22 +1039,18 @@ class SessionModelState(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The set of models that the Agent can use - available_models: Annotated[ - List[ModelInfo], - Field( - alias="availableModels", - description="The set of models that the Agent can use", - ), - ] - # The current model the Agent is in. - current_model_id: Annotated[ - str, - Field(alias="currentModelId", description="The current model the Agent is in."), - ] -class SessionResumeCapabilities(BaseModel): +class NesRepository(BaseModel): + # The repository name. + name: Annotated[str, Field(description="The repository name.")] + # The repository owner. + owner: Annotated[str, Field(description="The repository owner.")] + # The remote URL of the repository. + remote_url: Annotated[str, Field(alias="remoteUrl", description="The remote URL of the repository.")] + + +class NesSearchAndReplaceCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -826,11 +1065,30 @@ class SessionResumeCapabilities(BaseModel): ] = None -class SessionInfoUpdate(_SessionInfoUpdate): - session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] +class NesSearchAndReplaceSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # Whether `search` is a regular expression. Defaults to `false`. + is_regex: Annotated[ + Optional[bool], + Field( + alias="isRegex", + description="Whether `search` is a regular expression. Defaults to `false`.", + ), + ] = None + # The replacement text. + replace: Annotated[str, Field(description="The replacement text.")] + # The text or pattern to find. + search: Annotated[str, Field(description="The text or pattern to find.")] + # The file URI to search within. + uri: Annotated[str, Field(description="The file URI to search within.")] -class SetSessionConfigOptionBooleanRequest(BaseModel): +class NesSearchAndReplaceSuggestionVariant(NesSearchAndReplaceSuggestion): + kind: Literal["searchAndReplace"] + + +class NesUserActionsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -843,25 +1101,41 @@ class SetSessionConfigOptionBooleanRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the configuration option to set. - config_id: Annotated[ - str, - Field(alias="configId", description="The ID of the configuration option to set."), - ] - # The ID of the session to set the configuration option for. - session_id: Annotated[ - str, + # Maximum number of user actions the agent can use. + max_count: Annotated[ + Optional[int], Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", + alias="maxCount", + description="Maximum number of user actions the agent can use.", + ge=0, ), + ] = None + + +class NumberPropertySchema(BaseModel): + # Default value. + default: Annotated[Optional[float], Field(description="Default value.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Maximum value (inclusive). + maximum: Annotated[Optional[float], Field(description="Maximum value (inclusive).")] = None + # Minimum value (inclusive). + minimum: Annotated[Optional[float], Field(description="Minimum value (inclusive).")] = None + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + + +class Position(BaseModel): + # Zero-based character offset (encoding-dependent). + character: Annotated[ + int, + Field(description="Zero-based character offset (encoding-dependent).", ge=0), ] - type: Literal["boolean"] - # The boolean value. - value: Annotated[bool, Field(description="The boolean value.")] + # Zero-based line number. + line: Annotated[int, Field(description="Zero-based line number.", ge=0)] -class SetSessionConfigOptionSelectRequest(BaseModel): +class PromptCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -874,24 +1148,37 @@ class SetSessionConfigOptionSelectRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the configuration option to set. - config_id: Annotated[ + # Agent supports [`ContentBlock::Audio`]. + audio: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Audio`].")] = False + # Agent supports embedded context in `session/prompt` requests. + # + # When enabled, the Client is allowed to include [`ContentBlock::Resource`] + # in prompt requests for pieces of context that are referenced in the message. + embedded_context: Annotated[ + Optional[bool], + Field( + alias="embeddedContext", + description="Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", + ), + ] = False + # Agent supports [`ContentBlock::Image`]. + image: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Image`].")] = False + + +class ProviderCurrentConfig(BaseModel): + # Protocol currently used by this provider. + api_type: Annotated[ str, - Field(alias="configId", description="The ID of the configuration option to set."), + Field(alias="apiType", description="Protocol currently used by this provider."), ] - # The ID of the session to set the configuration option for. - session_id: Annotated[ + # Base URL currently used by this provider. + base_url: Annotated[ str, - Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", - ), + Field(alias="baseUrl", description="Base URL currently used by this provider."), ] - # The value ID. - value: Annotated[str, Field(description="The value ID.")] -class SetSessionModeRequest(BaseModel): +class ProviderInfo(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -904,16 +1191,27 @@ class SetSessionModeRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the mode to set. - mode_id: Annotated[str, Field(alias="modeId", description="The ID of the mode to set.")] - # The ID of the session to set the mode for. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The ID of the session to set the mode for."), + # Current effective non-secret routing config. + # Null or omitted means provider is disabled. + current: Annotated[ + Optional[ProviderCurrentConfig], + Field(description="Current effective non-secret routing config.\nNull or omitted means provider is disabled."), + ] = None + # Provider identifier, for example "main" or "openai". + id: Annotated[str, Field(description='Provider identifier, for example "main" or "openai".')] + # Whether this provider is mandatory and cannot be disabled via `providers/disable`. + # If true, clients must not call `providers/disable` for this id. + required: Annotated[ + bool, + Field( + description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id." + ), ] + # Supported protocol types for this provider. + supported: Annotated[List[str], Field(description="Supported protocol types for this provider.")] -class SetSessionModeResponse(BaseModel): +class ProvidersCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -928,7 +1226,14 @@ class SetSessionModeResponse(BaseModel): ] = None -class SetSessionModelRequest(BaseModel): +class Range(BaseModel): + # The end position (exclusive). + end: Annotated[Position, Field(description="The end position (exclusive).")] + # The start position (inclusive). + start: Annotated[Position, Field(description="The start position (inclusive).")] + + +class ReadTextFileResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -941,16 +1246,10 @@ class SetSessionModelRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the model to set. - model_id: Annotated[str, Field(alias="modelId", description="The ID of the model to set.")] - # The ID of the session to set the model for. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The ID of the session to set the model for."), - ] + content: str -class SetSessionModelResponse(BaseModel): +class ReleaseTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -965,7 +1264,16 @@ class SetSessionModelResponse(BaseModel): ] = None -class Terminal(BaseModel): +class DeniedOutcome(BaseModel): + outcome: Literal["cancelled"] + + +class Role(Enum): + assistant = "assistant" + user = "user" + + +class SelectedPermissionOutcome(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -978,10 +1286,14 @@ class Terminal(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - terminal_id: Annotated[str, Field(alias="terminalId")] + # The ID of the option the user selected. + option_id: Annotated[ + str, + Field(alias="optionId", description="The ID of the option the user selected."), + ] -class TerminalExitStatus(BaseModel): +class SessionAdditionalDirectoriesCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -994,23 +1306,32 @@ class TerminalExitStatus(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], + + +class SessionCloseCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None -class TerminalOutputRequest(BaseModel): +class SessionConfigBoolean(BaseModel): + # The current value of the boolean option. + current_value: Annotated[ + bool, + Field(alias="currentValue", description="The current value of the boolean option."), + ] + + +class SessionForkCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1023,16 +1344,9 @@ class TerminalOutputRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to get output from. - terminal_id: Annotated[ - str, - Field(alias="terminalId", description="The ID of the terminal to get output from."), - ] -class TerminalOutputResponse(BaseModel): +class SessionInfo(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1045,18 +1359,37 @@ class TerminalOutputResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Exit status if the command has completed. - exit_status: Annotated[ - Optional[TerminalExitStatus], - Field(alias="exitStatus", description="Exit status if the command has completed."), + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Authoritative ordered additional workspace roots for this session. Each path must be absolute. + # + # When omitted or empty, there are no additional roots for the session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthoritative ordered additional workspace roots for this session. Each path must be absolute.\n\nWhen omitted or empty, there are no additional roots for the session.", + ), + ] = None + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] + # Unique identifier for the session + session_id: Annotated[str, Field(alias="sessionId", description="Unique identifier for the session")] + # Human-readable title for the session + title: Annotated[Optional[str], Field(description="Human-readable title for the session")] = None + # ISO 8601 timestamp of last activity + updated_at: Annotated[ + Optional[str], + Field(alias="updatedAt", description="ISO 8601 timestamp of last activity"), ] = None - # The terminal output captured so far. - output: Annotated[str, Field(description="The terminal output captured so far.")] - # Whether the output was truncated due to byte limits. - truncated: Annotated[bool, Field(description="Whether the output was truncated due to byte limits.")] -class TextResourceContents(BaseModel): +class _SessionInfoUpdate(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1069,20 +1402,22 @@ class TextResourceContents(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None - text: str - uri: str - - -class FileEditToolCallContent(Diff): - type: Literal["diff"] - - -class TerminalToolCallContent(Terminal): - type: Literal["terminal"] + # Human-readable title for the session. Set to null to clear. + title: Annotated[ + Optional[str], + Field(description="Human-readable title for the session. Set to null to clear."), + ] = None + # ISO 8601 timestamp of last activity. Set to null to clear. + updated_at: Annotated[ + Optional[str], + Field( + alias="updatedAt", + description="ISO 8601 timestamp of last activity. Set to null to clear.", + ), + ] = None -class ToolCallLocation(BaseModel): +class SessionListCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1095,13 +1430,9 @@ class ToolCallLocation(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional line number within the file. - line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None - # The file path being accessed or modified. - path: Annotated[str, Field(description="The file path being accessed or modified.")] -class UnstructuredCommandInput(BaseModel): +class SessionModelState(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1114,59 +1445,22 @@ class UnstructuredCommandInput(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # A hint to display when the input hasn't been provided yet - hint: Annotated[ - str, - Field(description="A hint to display when the input hasn't been provided yet"), - ] - - -class Usage(BaseModel): - # Total cache read tokens. - cached_read_tokens: Annotated[ - Optional[int], - Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), - ] = None - # Total cache write tokens. - cached_write_tokens: Annotated[ - Optional[int], - Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), - ] = None - # Total input tokens across all turns. - input_tokens: Annotated[ - int, - Field( - alias="inputTokens", - description="Total input tokens across all turns.", - ge=0, - ), - ] - # Total output tokens across all turns. - output_tokens: Annotated[ - int, + # The set of models that the Agent can use + available_models: Annotated[ + List[ModelInfo], Field( - alias="outputTokens", - description="Total output tokens across all turns.", - ge=0, + alias="availableModels", + description="The set of models that the Agent can use", ), ] - # Total thought/reasoning tokens - thought_tokens: Annotated[ - Optional[int], - Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), - ] = None - # Sum of all token types across session. - total_tokens: Annotated[ - int, - Field( - alias="totalTokens", - description="Sum of all token types across session.", - ge=0, - ), + # The current model the Agent is in. + current_model_id: Annotated[ + str, + Field(alias="currentModelId", description="The current model the Agent is in."), ] -class _UsageUpdate(BaseModel): +class SessionResumeCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1179,15 +1473,13 @@ class _UsageUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Cumulative session cost (optional). - cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None - # Total context window size in tokens. - size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] - # Tokens currently in context. - used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] -class WaitForTerminalExitRequest(BaseModel): +class SessionInfoUpdate(_SessionInfoUpdate): + session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] + + +class SetProvidersRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1200,16 +1492,29 @@ class WaitForTerminalExitRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to wait for. - terminal_id: Annotated[ + # Protocol type for this provider. + api_type: Annotated[str, Field(alias="apiType", description="Protocol type for this provider.")] + # Base URL for requests sent through this provider. + base_url: Annotated[ str, - Field(alias="terminalId", description="The ID of the terminal to wait for."), + Field( + alias="baseUrl", + description="Base URL for requests sent through this provider.", + ), ] + # Full headers map for this provider. + # May include authorization, routing, or other integration-specific headers. + headers: Annotated[ + Optional[Dict[str, str]], + Field( + description="Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers." + ), + ] = None + # Provider id to configure. + id: Annotated[str, Field(description="Provider id to configure.")] -class WaitForTerminalExitResponse(BaseModel): +class SetProvidersResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1222,23 +1527,9 @@ class WaitForTerminalExitResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], - Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, - ), - ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None -class WriteTextFileRequest(BaseModel): +class SetSessionConfigOptionBooleanRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1251,15 +1542,25 @@ class WriteTextFileRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The text content to write to the file. - content: Annotated[str, Field(description="The text content to write to the file.")] - # Absolute path to the file to write. - path: Annotated[str, Field(description="Absolute path to the file to write.")] - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the configuration option to set. + config_id: Annotated[ + str, + Field(alias="configId", description="The ID of the configuration option to set."), + ] + # The ID of the session to set the configuration option for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to set the configuration option for.", + ), + ] + type: Literal["boolean"] + # The boolean value. + value: Annotated[bool, Field(description="The boolean value.")] -class WriteTextFileResponse(BaseModel): +class SetSessionConfigOptionSelectRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1272,9 +1573,24 @@ class WriteTextFileResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # The ID of the configuration option to set. + config_id: Annotated[ + str, + Field(alias="configId", description="The ID of the configuration option to set."), + ] + # The ID of the session to set the configuration option for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to set the configuration option for.", + ), + ] + # The value ID. + value: Annotated[str, Field(description="The value ID.")] -class Annotations(BaseModel): +class SetSessionModeRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1287,12 +1603,16 @@ class Annotations(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - audience: Optional[List[Role]] = None - last_modified: Annotated[Optional[str], Field(alias="lastModified")] = None - priority: Optional[float] = None + # The ID of the mode to set. + mode_id: Annotated[str, Field(alias="modeId", description="The ID of the mode to set.")] + # The ID of the session to set the mode for. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The ID of the session to set the mode for."), + ] -class AudioContent(BaseModel): +class SetSessionModeResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1305,28 +1625,9 @@ class AudioContent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - data: str - mime_type: Annotated[str, Field(alias="mimeType")] - - -class EnvVarAuthMethod(AuthMethodEnvVar): - type: Literal["env_var"] - - -class TerminalAuthMethod(AuthMethodTerminal): - type: Literal["terminal"] - - -class AvailableCommandInput(RootModel[UnstructuredCommandInput]): - # The input specification for a command. - root: Annotated[ - UnstructuredCommandInput, - Field(description="The input specification for a command."), - ] -class CancelNotification(BaseModel): +class SetSessionModelRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1339,17 +1640,16 @@ class CancelNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the session to cancel operations for. + # The ID of the model to set. + model_id: Annotated[str, Field(alias="modelId", description="The ID of the model to set.")] + # The ID of the session to set the model for. session_id: Annotated[ str, - Field( - alias="sessionId", - description="The ID of the session to cancel operations for.", - ), + Field(alias="sessionId", description="The ID of the session to set the model for."), ] -class CancelRequestNotification(BaseModel): +class SetSessionModelResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1362,14 +1662,9 @@ class CancelRequestNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the request to cancel. - request_id: Annotated[ - Optional[Union[int, str]], - Field(alias="requestId", description="The ID of the request to cancel."), - ] = None -class ClientCapabilities(BaseModel): +class StartNesResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1382,40 +1677,53 @@ class ClientCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Authentication capabilities supported by the client. - # Determines which authentication method types the agent may include - # in its `InitializeResponse`. - auth: Annotated[ - Optional[AuthCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." - ), - ] = {"terminal": False} - # File system capabilities supported by the client. - # Determines which file operations the agent can request. - fs: Annotated[ - Optional[FileSystemCapabilities], + # The session ID for the newly started NES session. + session_id: Annotated[ + str, Field( - description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." + alias="sessionId", + description="The session ID for the newly started NES session.", ), - ] = FileSystemCapabilities() - # Whether the Client support all `terminal/*` methods. - terminal: Annotated[ - Optional[bool], - Field(description="Whether the Client support all `terminal/*` methods."), - ] = False + ] -class ClientNotification(BaseModel): - method: str - params: Optional[Union[CancelNotification, Any]] = None +class StringPropertySchema(BaseModel): + # Default value. + default: Annotated[Optional[str], Field(description="Default value.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Enum values for untitled single-select enums. + enum: Annotated[ + Optional[List[str]], + Field(description="Enum values for untitled single-select enums."), + ] = None + # String format. + format: Annotated[Optional[str], Field(description="String format.")] = None + # Maximum string length. + max_length: Annotated[ + Optional[int], + Field(alias="maxLength", description="Maximum string length.", ge=0), + ] = None + # Minimum string length. + min_length: Annotated[ + Optional[int], + Field(alias="minLength", description="Minimum string length.", ge=0), + ] = None + # Titled enum options for titled single-select enums. + one_of: Annotated[ + Optional[List[EnumOption]], + Field( + alias="oneOf", + description="Titled enum options for titled single-select enums.", + ), + ] = None + # Pattern the string must match. + pattern: Annotated[Optional[str], Field(description="Pattern the string must match.")] = None + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class CloseSessionRequest(BaseModel): +class Terminal(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1428,15 +1736,10 @@ class CloseSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the session to close. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] - - -class AudioContentBlock(AudioContent): - type: Literal["audio"] + terminal_id: Annotated[str, Field(alias="terminalId")] -class CreateTerminalRequest(BaseModel): +class TerminalExitStatus(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1449,41 +1752,685 @@ class CreateTerminalRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Array of command arguments. - args: Annotated[Optional[List[str]], Field(description="Array of command arguments.")] = None - # The command to execute. - command: Annotated[str, Field(description="The command to execute.")] - # Working directory for the command (absolute path). - cwd: Annotated[ - Optional[str], - Field(description="Working directory for the command (absolute path)."), - ] = None - # Environment variables for the command. - env: Annotated[ - Optional[List[EnvVariable]], - Field(description="Environment variables for the command."), - ] = None - # Maximum number of output bytes to retain. - # - # When the limit is exceeded, the Client truncates from the beginning of the output - # to stay within the limit. - # - # The Client MUST ensure truncation happens at a character boundary to maintain valid - # string output, even if this means the retained output is slightly less than the - # specified limit. - output_byte_limit: Annotated[ + # The process exit code (may be null if terminated by signal). + exit_code: Annotated[ Optional[int], Field( - alias="outputByteLimit", + alias="exitCode", + description="The process exit code (may be null if terminated by signal).", + ge=0, + ), + ] = None + # The signal that terminated the process (may be null if exited normally). + signal: Annotated[ + Optional[str], + Field(description="The signal that terminated the process (may be null if exited normally)."), + ] = None + + +class TerminalOutputRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to get output from. + terminal_id: Annotated[ + str, + Field(alias="terminalId", description="The ID of the terminal to get output from."), + ] + + +class TerminalOutputResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Exit status if the command has completed. + exit_status: Annotated[ + Optional[TerminalExitStatus], + Field(alias="exitStatus", description="Exit status if the command has completed."), + ] = None + # The terminal output captured so far. + output: Annotated[str, Field(description="The terminal output captured so far.")] + # Whether the output was truncated due to byte limits. + truncated: Annotated[bool, Field(description="Whether the output was truncated due to byte limits.")] + + +class TextDocumentContentChangeEvent(BaseModel): + # The range of the document that changed. If `None`, the entire content is replaced. + range: Annotated[ + Optional[Range], + Field(description="The range of the document that changed. If `None`, the entire content is replaced."), + ] = None + # The new text for the range, or the full document content if `range` is `None`. + text: Annotated[ + str, + Field(description="The new text for the range, or the full document content if `range` is `None`."), + ] + + +class TextResourceContents(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None + text: str + uri: str + + +class TitledMultiSelectItems(BaseModel): + # Titled enum options. + any_of: Annotated[List[EnumOption], Field(alias="anyOf", description="Titled enum options.")] + + +class FileEditToolCallContent(Diff): + type: Literal["diff"] + + +class TerminalToolCallContent(Terminal): + type: Literal["terminal"] + + +class ToolCallLocation(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Optional line number within the file. + line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None + # The file path being accessed or modified. + path: Annotated[str, Field(description="The file path being accessed or modified.")] + + +class UnstructuredCommandInput(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # A hint to display when the input hasn't been provided yet + hint: Annotated[ + str, + Field(description="A hint to display when the input hasn't been provided yet"), + ] + + +class UntitledMultiSelectItems(BaseModel): + # Allowed enum values. + enum: Annotated[List[str], Field(description="Allowed enum values.")] + # Item type discriminator. Must be `"string"`. + type: Annotated[str, Field(description='Item type discriminator. Must be `"string"`.')] + + +class Usage(BaseModel): + # Total cache read tokens. + cached_read_tokens: Annotated[ + Optional[int], + Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), + ] = None + # Total cache write tokens. + cached_write_tokens: Annotated[ + Optional[int], + Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), + ] = None + # Total input tokens across all turns. + input_tokens: Annotated[ + int, + Field( + alias="inputTokens", + description="Total input tokens across all turns.", + ge=0, + ), + ] + # Total output tokens across all turns. + output_tokens: Annotated[ + int, + Field( + alias="outputTokens", + description="Total output tokens across all turns.", + ge=0, + ), + ] + # Total thought/reasoning tokens + thought_tokens: Annotated[ + Optional[int], + Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), + ] = None + # Sum of all token types across session. + total_tokens: Annotated[ + int, + Field( + alias="totalTokens", + description="Sum of all token types across session.", + ge=0, + ), + ] + + +class _UsageUpdate(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Cumulative session cost (optional). + cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None + # Total context window size in tokens. + size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] + # Tokens currently in context. + used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] + + +class WaitForTerminalExitRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to wait for. + terminal_id: Annotated[ + str, + Field(alias="terminalId", description="The ID of the terminal to wait for."), + ] + + +class WaitForTerminalExitResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The process exit code (may be null if terminated by signal). + exit_code: Annotated[ + Optional[int], + Field( + alias="exitCode", + description="The process exit code (may be null if terminated by signal).", + ge=0, + ), + ] = None + # The signal that terminated the process (may be null if exited normally). + signal: Annotated[ + Optional[str], + Field(description="The signal that terminated the process (may be null if exited normally)."), + ] = None + + +class WorkspaceFolder(BaseModel): + # The display name of the folder. + name: Annotated[str, Field(description="The display name of the folder.")] + # The URI of the folder. + uri: Annotated[str, Field(description="The URI of the folder.")] + + +class WriteTextFileRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The text content to write to the file. + content: Annotated[str, Field(description="The text content to write to the file.")] + # Absolute path to the file to write. + path: Annotated[str, Field(description="Absolute path to the file to write.")] + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + + +class WriteTextFileResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class AcceptNesNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the accepted suggestion. + id: Annotated[str, Field(description="The ID of the accepted suggestion.")] + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + + +class AgentAuthCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Whether the agent supports the logout method. + # + # By supplying `{}` it means that the agent supports the logout method. + logout: Annotated[ + Optional[LogoutCapabilities], + Field( + description="Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." + ), + ] = None + + +class Annotations(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + audience: Optional[List[Role]] = None + last_modified: Annotated[Optional[str], Field(alias="lastModified")] = None + priority: Optional[float] = None + + +class AudioContent(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + annotations: Optional[Annotations] = None + data: str + mime_type: Annotated[str, Field(alias="mimeType")] + + +class EnvVarAuthMethod(AuthMethodEnvVar): + type: Literal["env_var"] + + +class TerminalAuthMethod(AuthMethodTerminal): + type: Literal["terminal"] + + +class AvailableCommandInput(RootModel[UnstructuredCommandInput]): + # The input specification for a command. + root: Annotated[ + UnstructuredCommandInput, + Field(description="The input specification for a command."), + ] + + +class CancelNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the session to cancel operations for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to cancel operations for.", + ), + ] + + +class CancelRequestNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the request to cancel. + request_id: Annotated[ + Optional[Union[int, str]], + Field(alias="requestId", description="The ID of the request to cancel."), + ] = None + + +class ClientNesCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Whether the client supports the `jump` suggestion kind. + jump: Annotated[ + Optional[NesJumpCapabilities], + Field(description="Whether the client supports the `jump` suggestion kind."), + ] = None + # Whether the client supports the `rename` suggestion kind. + rename: Annotated[ + Optional[NesRenameCapabilities], + Field(description="Whether the client supports the `rename` suggestion kind."), + ] = None + # Whether the client supports the `searchAndReplace` suggestion kind. + search_and_replace: Annotated[ + Optional[NesSearchAndReplaceCapabilities], + Field( + alias="searchAndReplace", + description="Whether the client supports the `searchAndReplace` suggestion kind.", + ), + ] = None + + +class CloseNesRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the NES session to close. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the NES session to close.")] + + +class CloseSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the session to close. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] + + +class CompleteElicitationNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the elicitation that completed. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The ID of the elicitation that completed.", + ), + ] + + +class AudioContentBlock(AudioContent): + type: Literal["audio"] + + +class AcceptElicitationResponse(ElicitationAcceptAction): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + action: Literal["accept"] + + +class CreateTerminalRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Array of command arguments. + args: Annotated[Optional[List[str]], Field(description="Array of command arguments.")] = None + # The command to execute. + command: Annotated[str, Field(description="The command to execute.")] + # Working directory for the command (absolute path). + cwd: Annotated[ + Optional[str], + Field(description="Working directory for the command (absolute path)."), + ] = None + # Environment variables for the command. + env: Annotated[ + Optional[List[EnvVariable]], + Field(description="Environment variables for the command."), + ] = None + # Maximum number of output bytes to retain. + # + # When the limit is exceeded, the Client truncates from the beginning of the output + # to stay within the limit. + # + # The Client MUST ensure truncation happens at a character boundary to maintain valid + # string output, even if this means the retained output is slightly less than the + # specified limit. + output_byte_limit: Annotated[ + Optional[int], + Field( + alias="outputByteLimit", description="Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", ge=0, ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + + +class _CurrentModeUpdate(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the current mode + current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] + + +class DidChangeDocumentNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The content changes. + content_changes: Annotated[ + List[TextDocumentContentChangeEvent], + Field(alias="contentChanges", description="The content changes."), + ] + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the changed document. + uri: Annotated[str, Field(description="The URI of the changed document.")] + # The new version number of the document. + version: Annotated[int, Field(description="The new version number of the document.")] + + +class DidCloseDocumentNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the closed document. + uri: Annotated[str, Field(description="The URI of the closed document.")] -class _CurrentModeUpdate(BaseModel): +class DidFocusDocumentNotification(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1496,8 +2443,179 @@ class _CurrentModeUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the current mode - current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] + # The current cursor position. + position: Annotated[Position, Field(description="The current cursor position.")] + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the focused document. + uri: Annotated[str, Field(description="The URI of the focused document.")] + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + # The portion of the file currently visible in the editor viewport. + visible_range: Annotated[ + Range, + Field( + alias="visibleRange", + description="The portion of the file currently visible in the editor viewport.", + ), + ] + + +class DidOpenDocumentNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The language identifier of the document (e.g., "rust", "python"). + language_id: Annotated[ + str, + Field( + alias="languageId", + description='The language identifier of the document (e.g., "rust", "python").', + ), + ] + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The full text content of the document. + text: Annotated[str, Field(description="The full text content of the document.")] + # The URI of the opened document. + uri: Annotated[str, Field(description="The URI of the opened document.")] + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + + +class DidSaveDocumentNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the saved document. + uri: Annotated[str, Field(description="The URI of the saved document.")] + + +class ElicitationCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Whether the client supports form-based elicitation. + form: Annotated[ + Optional[ElicitationFormCapabilities], + Field(description="Whether the client supports form-based elicitation."), + ] = None + # Whether the client supports URL-based elicitation. + url: Annotated[ + Optional[ElicitationUrlCapabilities], + Field(description="Whether the client supports URL-based elicitation."), + ] = None + + +class ElicitationStringPropertySchema(StringPropertySchema): + type: Literal["string"] + + +class ElicitationNumberPropertySchema(NumberPropertySchema): + type: Literal["number"] + + +class ElicitationIntegerPropertySchema(IntegerPropertySchema): + type: Literal["integer"] + + +class ElicitationRequestScope(BaseModel): + # The request this elicitation is tied to. + request_id: Annotated[ + Optional[Union[int, str]], + Field(alias="requestId", description="The request this elicitation is tied to."), + ] = None + + +class ElicitationSessionScope(BaseModel): + # The session this elicitation is tied to. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session this elicitation is tied to."), + ] + # Optional tool call within the session. + tool_call_id: Annotated[ + Optional[str], + Field(alias="toolCallId", description="Optional tool call within the session."), + ] = None + + +class ElicitationUrlSessionMode(ElicitationSessionScope): + # The unique identifier for this elicitation. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The unique identifier for this elicitation.", + ), + ] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + + +class ElicitationUrlRequestMode(ElicitationRequestScope): + # The unique identifier for this elicitation. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The unique identifier for this elicitation.", + ), + ] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + + +class ElicitationUrlMode(RootModel[Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode]]): + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # URL-based elicitation mode where the client directs the user to a URL. + root: Annotated[ + Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL." + ), + ] class Error(BaseModel): @@ -1546,7 +2664,7 @@ class ImageContent(BaseModel): uri: Optional[str] = None -class InitializeRequest(BaseModel): +class KillTerminalRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1559,37 +2677,91 @@ class InitializeRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Capabilities supported by the client. - client_capabilities: Annotated[ - Optional[ClientCapabilities], + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to kill. + terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to kill.")] + + +class ListProvidersResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="clientCapabilities", - description="Capabilities supported by the client.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] = ClientCapabilities() - # Information about the Client name and version sent to the Agent. + ] = None + # Configurable providers with current routing info suitable for UI display. + providers: Annotated[ + List[ProviderInfo], + Field(description="Configurable providers with current routing info suitable for UI display."), + ] + + +class ListSessionsResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # Note: in future versions of the protocol, this will be required. - client_info: Annotated[ - Optional[Implementation], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="clientInfo", - description="Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The latest protocol version supported by the client. - protocol_version: Annotated[ - int, + # Opaque cursor token. If present, pass this in the next request's cursor parameter + # to fetch the next page. If absent, there are no more results. + next_cursor: Annotated[ + Optional[str], Field( - alias="protocolVersion", - description="The latest protocol version supported by the client.", - ge=0, - le=65535, + alias="nextCursor", + description="Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", ), + ] = None + # Array of session information objects + sessions: Annotated[List[SessionInfo], Field(description="Array of session information objects")] + + +class HttpMcpServer(McpServerHttp): + type: Literal["http"] + + +class SseMcpServer(McpServerSse): + type: Literal["sse"] + + +class MultiSelectPropertySchema(BaseModel): + # Default selected values. + default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # The items definition describing allowed values. + items: Annotated[ + Union[UntitledMultiSelectItems, TitledMultiSelectItems], + Field(description="The items definition describing allowed values."), ] + # Maximum number of items to select. + max_items: Annotated[ + Optional[int], + Field(alias="maxItems", description="Maximum number of items to select.", ge=0), + ] = None + # Minimum number of items to select. + min_items: Annotated[ + Optional[int], + Field(alias="minItems", description="Minimum number of items to select.", ge=0), + ] = None + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class KillTerminalRequest(BaseModel): +class NesContextCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1602,13 +2774,62 @@ class KillTerminalRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to kill. - terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to kill.")] + # Whether the agent wants diagnostics context. + diagnostics: Annotated[ + Optional[NesDiagnosticsCapabilities], + Field(description="Whether the agent wants diagnostics context."), + ] = None + # Whether the agent wants edit history context. + edit_history: Annotated[ + Optional[NesEditHistoryCapabilities], + Field( + alias="editHistory", + description="Whether the agent wants edit history context.", + ), + ] = None + # Whether the agent wants open files context. + open_files: Annotated[ + Optional[NesOpenFilesCapabilities], + Field(alias="openFiles", description="Whether the agent wants open files context."), + ] = None + # Whether the agent wants recent files context. + recent_files: Annotated[ + Optional[NesRecentFilesCapabilities], + Field( + alias="recentFiles", + description="Whether the agent wants recent files context.", + ), + ] = None + # Whether the agent wants related snippets context. + related_snippets: Annotated[ + Optional[NesRelatedSnippetsCapabilities], + Field( + alias="relatedSnippets", + description="Whether the agent wants related snippets context.", + ), + ] = None + # Whether the agent wants user actions context. + user_actions: Annotated[ + Optional[NesUserActionsCapabilities], + Field( + alias="userActions", + description="Whether the agent wants user actions context.", + ), + ] = None -class ListSessionsResponse(BaseModel): +class NesDiagnostic(BaseModel): + # The diagnostic message. + message: Annotated[str, Field(description="The diagnostic message.")] + # The range of the diagnostic. + range: Annotated[Range, Field(description="The range of the diagnostic.")] + # The severity of the diagnostic. + severity: Annotated[str, Field(description="The severity of the diagnostic.")] + # The URI of the file containing the diagnostic. + uri: Annotated[str, Field(description="The URI of the file containing the diagnostic.")] + + +class NesDocumentDidChangeCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1621,25 +2842,166 @@ class ListSessionsResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Opaque cursor token. If present, pass this in the next request's cursor parameter - # to fetch the next page. If absent, there are no more results. - next_cursor: Annotated[ - Optional[str], + # The sync kind the agent wants: `"full"` or `"incremental"`. + sync_kind: Annotated[ + str, + Field( + alias="syncKind", + description='The sync kind the agent wants: `"full"` or `"incremental"`.', + ), + ] + + +class NesDocumentEventCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Whether the agent wants `document/didChange` events, and the sync kind. + did_change: Annotated[ + Optional[NesDocumentDidChangeCapabilities], + Field( + alias="didChange", + description="Whether the agent wants `document/didChange` events, and the sync kind.", + ), + ] = None + # Whether the agent wants `document/didClose` events. + did_close: Annotated[ + Optional[NesDocumentDidCloseCapabilities], + Field( + alias="didClose", + description="Whether the agent wants `document/didClose` events.", + ), + ] = None + # Whether the agent wants `document/didFocus` events. + did_focus: Annotated[ + Optional[NesDocumentDidFocusCapabilities], + Field( + alias="didFocus", + description="Whether the agent wants `document/didFocus` events.", + ), + ] = None + # Whether the agent wants `document/didOpen` events. + did_open: Annotated[ + Optional[NesDocumentDidOpenCapabilities], + Field( + alias="didOpen", + description="Whether the agent wants `document/didOpen` events.", + ), + ] = None + # Whether the agent wants `document/didSave` events. + did_save: Annotated[ + Optional[NesDocumentDidSaveCapabilities], + Field( + alias="didSave", + description="Whether the agent wants `document/didSave` events.", + ), + ] = None + + +class NesEventCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Document event capabilities. + document: Annotated[ + Optional[NesDocumentEventCapabilities], + Field(description="Document event capabilities."), + ] = None + + +class NesJumpSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The target position within the file. + position: Annotated[Position, Field(description="The target position within the file.")] + # The file to navigate to. + uri: Annotated[str, Field(description="The file to navigate to.")] + + +class NesOpenFile(BaseModel): + # The language identifier. + language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] + # Timestamp in milliseconds since epoch of when the file was last focused. + last_focused_ms: Annotated[ + Optional[int], Field( - alias="nextCursor", - description="Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", + alias="lastFocusedMs", + description="Timestamp in milliseconds since epoch of when the file was last focused.", + ge=0, ), ] = None - # Array of session information objects - sessions: Annotated[List[SessionInfo], Field(description="Array of session information objects")] + # The URI of the file. + uri: Annotated[str, Field(description="The URI of the file.")] + # The visible range in the editor, if any. + visible_range: Annotated[ + Optional[Range], + Field(alias="visibleRange", description="The visible range in the editor, if any."), + ] = None -class HttpMcpServer(McpServerHttp): - type: Literal["http"] +class NesRenameSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The new name for the symbol. + new_name: Annotated[str, Field(alias="newName", description="The new name for the symbol.")] + # The position of the symbol to rename. + position: Annotated[Position, Field(description="The position of the symbol to rename.")] + # The file URI containing the symbol. + uri: Annotated[str, Field(description="The file URI containing the symbol.")] -class SseMcpServer(McpServerSse): - type: Literal["sse"] +class NesJumpSuggestionVariant(NesJumpSuggestion): + kind: Literal["jump"] + + +class NesRenameSuggestionVariant(NesRenameSuggestion): + kind: Literal["rename"] + + +class NesTextEdit(BaseModel): + # The replacement text. + new_text: Annotated[str, Field(alias="newText", description="The replacement text.")] + # The range to replace. + range: Annotated[Range, Field(description="The range to replace.")] + + +class NesUserAction(BaseModel): + # The kind of action (e.g., "insertChar", "cursorMovement"). + action: Annotated[ + str, + Field(description='The kind of action (e.g., "insertChar", "cursorMovement").'), + ] + # The position where the action occurred. + position: Annotated[Position, Field(description="The position where the action occurred.")] + # Timestamp in milliseconds since epoch. + timestamp_ms: Annotated[ + int, + Field( + alias="timestampMs", + description="Timestamp in milliseconds since epoch.", + ge=0, + ), + ] + # The URI of the file where the action occurred. + uri: Annotated[str, Field(description="The URI of the file where the action occurred.")] class NewSessionRequest(BaseModel): @@ -1655,6 +3017,22 @@ class NewSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots for this session. Each path must be absolute. + # + # These expand the session's filesystem scope without changing `cwd`, which + # remains the base for relative paths. When omitted or empty, no + # additional roots are activated for the new session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + ), + ] = None # The working directory for this session. Must be an absolute path. cwd: Annotated[ str, @@ -1803,6 +3181,30 @@ class ReadTextFileRequest(BaseModel): session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] +class RejectNesNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the rejected suggestion. + id: Annotated[str, Field(description="The ID of the rejected suggestion.")] + # The reason for rejection. + reason: Annotated[Optional[str], Field(description="The reason for rejection.")] = None + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + + class ReleaseTerminalRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1884,6 +3286,22 @@ class ResumeSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the resumed + # session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession.", + ), + ] = None # The working directory for this session. cwd: Annotated[str, Field(description="The working directory for this session.")] # List of MCP servers to connect to for this session. @@ -1915,12 +3333,18 @@ class SessionCapabilities(BaseModel): # # This capability is not part of the spec yet, and may be removed or changed at any point. # + # Whether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`. + additional_directories: Annotated[ + Optional[SessionAdditionalDirectoriesCapabilities], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`.", + ), + ] = None # Whether the agent supports `session/close`. close: Annotated[ Optional[SessionCloseCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/close`." - ), + Field(description="Whether the agent supports `session/close`."), ] = None # **UNSTABLE** # @@ -1938,16 +3362,10 @@ class SessionCapabilities(BaseModel): Optional[SessionListCapabilities], Field(description="Whether the agent supports `session/list`."), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Whether the agent supports `session/resume`. resume: Annotated[ Optional[SessionResumeCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/resume`." - ), + Field(description="Whether the agent supports `session/resume`."), ] = None @@ -2057,7 +3475,7 @@ class UsageUpdate(_UsageUpdate): session_update: Annotated[Literal["usage_update"], Field(alias="sessionUpdate")] -class TextContent(BaseModel): +class StartNesRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2070,11 +3488,24 @@ class TextContent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - text: str + # Repository metadata, if the workspace is a git repository. + repository: Annotated[ + Optional[NesRepository], + Field(description="Repository metadata, if the workspace is a git repository."), + ] = None + # The workspace folders. + workspace_folders: Annotated[ + Optional[List[WorkspaceFolder]], + Field(alias="workspaceFolders", description="The workspace folders."), + ] = None + # The root URI of the workspace. + workspace_uri: Annotated[ + Optional[str], + Field(alias="workspaceUri", description="The root URI of the workspace."), + ] = None -class AgentCapabilities(BaseModel): +class TextContent(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2087,33 +3518,8 @@ class AgentCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the agent supports `session/load`. - load_session: Annotated[ - Optional[bool], - Field( - alias="loadSession", - description="Whether the agent supports `session/load`.", - ), - ] = False - # MCP capabilities supported by the agent. - mcp_capabilities: Annotated[ - Optional[McpCapabilities], - Field( - alias="mcpCapabilities", - description="MCP capabilities supported by the agent.", - ), - ] = McpCapabilities() - # Prompt capabilities supported by the agent. - prompt_capabilities: Annotated[ - Optional[PromptCapabilities], - Field( - alias="promptCapabilities", - description="Prompt capabilities supported by the agent.", - ), - ] = PromptCapabilities() - session_capabilities: Annotated[Optional[SessionCapabilities], Field(alias="sessionCapabilities")] = ( - SessionCapabilities() - ) + annotations: Optional[Annotations] = None + text: str class AgentErrorMessage(BaseModel): @@ -2182,6 +3588,99 @@ class _AvailableCommandsUpdate(BaseModel): ] +class ClientCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Authentication capabilities supported by the client. + # Determines which authentication method types the agent may include + # in its `InitializeResponse`. + auth: Annotated[ + Optional[AuthCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." + ), + ] = {"terminal": False} + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Elicitation capabilities supported by the client. + # Determines which elicitation modes the agent may use. + elicitation: Annotated[ + Optional[ElicitationCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + ), + ] = None + # File system capabilities supported by the client. + # Determines which file operations the agent can request. + fs: Annotated[ + Optional[FileSystemCapabilities], + Field( + description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." + ), + ] = FileSystemCapabilities() + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # NES (Next Edit Suggestions) capabilities supported by the client. + nes: Annotated[ + Optional[ClientNesCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # The position encodings supported by the client, in order of preference. + position_encodings: Annotated[ + Optional[List[str]], + Field( + alias="positionEncodings", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", + ), + ] = None + # Whether the Client support all `terminal/*` methods. + terminal: Annotated[ + Optional[bool], + Field(description="Whether the Client support all `terminal/*` methods."), + ] = False + + +class ClientNotification(BaseModel): + method: str + params: Optional[ + Union[ + CancelNotification, + DidOpenDocumentNotification, + DidChangeDocumentNotification, + DidCloseDocumentNotification, + DidSaveDocumentNotification, + DidFocusDocumentNotification, + AcceptNesNotification, + RejectNesNotification, + Any, + ] + ] = None + + class ClientResponseMessage(BaseModel): # JSON RPC Request Id # @@ -2214,6 +3713,11 @@ class ClientResponseMessage(BaseModel): ReleaseTerminalResponse, WaitForTerminalExitResponse, KillTerminalResponse, + Union[ + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, + ], Any, ], Field( @@ -2257,6 +3761,61 @@ class ResourceContentBlock(ResourceLink): type: Literal["resource_link"] +class CreateUrlElicitationRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] + mode: Literal["url"] + + +class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): + type: Literal["array"] + + +class ElicitationSchema(BaseModel): + # Optional description of what this schema represents. + description: Annotated[ + Optional[str], + Field(description="Optional description of what this schema represents."), + ] = None + # Property definitions (must be primitive types). + properties: Annotated[ + Optional[ + Dict[ + str, + Union[ + ElicitationStringPropertySchema, + ElicitationNumberPropertySchema, + ElicitationIntegerPropertySchema, + ElicitationBooleanPropertySchema, + ElicitationMultiSelectPropertySchema, + ], + ] + ], + Field(description="Property definitions (must be primitive types)."), + ] = {} + # List of required property names. + required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None + # Optional title for the schema. + title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None + # Type discriminator. Always `"object"`. + type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" + + class EmbeddedResource(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2291,6 +3850,22 @@ class ForkSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the forked + # session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + ), + ] = None # The working directory for this session. cwd: Annotated[str, Field(description="The working directory for this session.")] # List of MCP servers to connect to for this session. @@ -2305,7 +3880,7 @@ class ForkSessionRequest(BaseModel): session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] -class InitializeResponse(BaseModel): +class InitializeRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2318,41 +3893,30 @@ class InitializeResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Capabilities supported by the agent. - agent_capabilities: Annotated[ - Optional[AgentCapabilities], + # Capabilities supported by the client. + client_capabilities: Annotated[ + Optional[ClientCapabilities], Field( - alias="agentCapabilities", - description="Capabilities supported by the agent.", + alias="clientCapabilities", + description="Capabilities supported by the client.", ), - ] = AgentCapabilities() - # Information about the Agent name and version sent to the Client. + ] = ClientCapabilities() + # Information about the Client name and version sent to the Agent. # # Note: in future versions of the protocol, this will be required. - agent_info: Annotated[ + client_info: Annotated[ Optional[Implementation], Field( - alias="agentInfo", - description="Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", + alias="clientInfo", + description="Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", ), ] = None - # Authentication methods supported by the agent. - auth_methods: Annotated[ - Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], - Field( - alias="authMethods", - description="Authentication methods supported by the agent.", - ), - ] = [] - # The protocol version the client specified if supported by the agent, - # or the latest protocol version supported by the agent. - # - # The client should disconnect, if it doesn't support this version. + # The latest protocol version supported by the client. protocol_version: Annotated[ int, Field( alias="protocolVersion", - description="The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", + description="The latest protocol version supported by the client.", ge=0, le=65535, ), @@ -2372,6 +3936,22 @@ class LoadSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the loaded + # session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession.", + ), + ] = None # The working directory for this session. cwd: Annotated[str, Field(description="The working directory for this session.")] # List of MCP servers to connect to for this session. @@ -2386,6 +3966,100 @@ class LoadSessionRequest(BaseModel): session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] +class NesCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Context the agent wants attached to each suggestion request. + context: Annotated[ + Optional[NesContextCapabilities], + Field(description="Context the agent wants attached to each suggestion request."), + ] = None + # Events the agent wants to receive. + events: Annotated[ + Optional[NesEventCapabilities], + Field(description="Events the agent wants to receive."), + ] = None + + +class NesEditSuggestion(BaseModel): + # Optional suggested cursor position after applying edits. + cursor_position: Annotated[ + Optional[Position], + Field( + alias="cursorPosition", + description="Optional suggested cursor position after applying edits.", + ), + ] = None + # The text edits to apply. + edits: Annotated[List[NesTextEdit], Field(description="The text edits to apply.")] + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The URI of the file to edit. + uri: Annotated[str, Field(description="The URI of the file to edit.")] + + +class NesSuggestContext(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Current diagnostics (errors, warnings). + diagnostics: Annotated[ + Optional[List[NesDiagnostic]], + Field(description="Current diagnostics (errors, warnings)."), + ] = None + # Recent edit history. + edit_history: Annotated[ + Optional[List[NesEditHistoryEntry]], + Field(alias="editHistory", description="Recent edit history."), + ] = None + # Currently open files in the editor. + open_files: Annotated[ + Optional[List[NesOpenFile]], + Field(alias="openFiles", description="Currently open files in the editor."), + ] = None + # Recently accessed files. + recent_files: Annotated[ + Optional[List[NesRecentFile]], + Field(alias="recentFiles", description="Recently accessed files."), + ] = None + # Related code snippets. + related_snippets: Annotated[ + Optional[List[NesRelatedSnippet]], + Field(alias="relatedSnippets", description="Related code snippets."), + ] = None + # Recent user actions (typing, navigation, etc.). + user_actions: Annotated[ + Optional[List[NesUserAction]], + Field( + alias="userActions", + description="Recent user actions (typing, navigation, etc.).", + ), + ] = None + + +class NesEditSuggestionVariant(NesEditSuggestion): + kind: Literal["edit"] + + class Plan(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2443,6 +4117,157 @@ class AvailableCommandsUpdate(_AvailableCommandsUpdate): session_update: Annotated[Literal["available_commands_update"], Field(alias="sessionUpdate")] +class SuggestNesRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Context for the suggestion, included based on agent capabilities. + context: Annotated[ + Optional[NesSuggestContext], + Field(description="Context for the suggestion, included based on agent capabilities."), + ] = None + # The current cursor position. + position: Annotated[Position, Field(description="The current cursor position.")] + # The current text selection range, if any. + selection: Annotated[Optional[Range], Field(description="The current text selection range, if any.")] = None + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # What triggered this suggestion request. + trigger_kind: Annotated[ + str, + Field(alias="triggerKind", description="What triggered this suggestion request."), + ] + # The URI of the document to suggest for. + uri: Annotated[str, Field(description="The URI of the document to suggest for.")] + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + + +class SuggestNesResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The list of suggestions. + suggestions: Annotated[ + List[ + Union[ + NesEditSuggestionVariant, + NesJumpSuggestionVariant, + NesRenameSuggestionVariant, + NesSearchAndReplaceSuggestionVariant, + ] + ], + Field(description="The list of suggestions."), + ] + + +class AgentCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Authentication-related capabilities supported by the agent. + auth: Annotated[ + Optional[AgentAuthCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent." + ), + ] = {} + # Whether the agent supports `session/load`. + load_session: Annotated[ + Optional[bool], + Field( + alias="loadSession", + description="Whether the agent supports `session/load`.", + ), + ] = False + # MCP capabilities supported by the agent. + mcp_capabilities: Annotated[ + Optional[McpCapabilities], + Field( + alias="mcpCapabilities", + description="MCP capabilities supported by the agent.", + ), + ] = McpCapabilities() + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # NES (Next Edit Suggestions) capabilities supported by the agent. + nes: Annotated[ + Optional[NesCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # The position encoding selected by the agent from the client's supported encodings. + position_encoding: Annotated[ + Optional[str], + Field( + alias="positionEncoding", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", + ), + ] = None + # Prompt capabilities supported by the agent. + prompt_capabilities: Annotated[ + Optional[PromptCapabilities], + Field( + alias="promptCapabilities", + description="Prompt capabilities supported by the agent.", + ), + ] = PromptCapabilities() + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Provider configuration capabilities supported by the agent. + # + # By supplying `{}` it means that the agent supports provider configuration methods. + providers: Annotated[ + Optional[ProvidersCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." + ), + ] = None + session_capabilities: Annotated[Optional[SessionCapabilities], Field(alias="sessionCapabilities")] = ( + SessionCapabilities() + ) + + class EmbeddedResourceContentBlock(EmbeddedResource): type: Literal["resource"] @@ -2485,6 +4310,96 @@ class ContentChunk(BaseModel): ] = None +class ElicitationFormSessionMode(ElicitationSessionScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, + Field( + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", + ), + ] + + +class ElicitationFormRequestMode(ElicitationRequestScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, + Field( + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", + ), + ] + + +class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Form-based elicitation mode where the client renders a form from the provided schema. + root: Annotated[ + Union[ElicitationFormSessionMode, ElicitationFormRequestMode], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." + ), + ] + + +class InitializeResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Capabilities supported by the agent. + agent_capabilities: Annotated[ + Optional[AgentCapabilities], + Field( + alias="agentCapabilities", + description="Capabilities supported by the agent.", + ), + ] = AgentCapabilities() + # Information about the Agent name and version sent to the Client. + # + # Note: in future versions of the protocol, this will be required. + agent_info: Annotated[ + Optional[Implementation], + Field( + alias="agentInfo", + description="Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", + ), + ] = None + # Authentication methods supported by the agent. + auth_methods: Annotated[ + Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], + Field( + alias="authMethods", + description="Authentication methods supported by the agent.", + ), + ] = [] + # The protocol version the client specified if supported by the agent, + # or the latest protocol version supported by the agent. + # + # The client should disconnect, if it doesn't support this version. + protocol_version: Annotated[ + int, + Field( + alias="protocolVersion", + description="The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", + ge=0, + le=65535, + ), + ] + + class PromptRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2594,6 +4509,10 @@ class ClientRequest(BaseModel): Union[ InitializeRequest, AuthenticateRequest, + ListProvidersRequest, + SetProvidersRequest, + DisableProvidersRequest, + LogoutRequest, NewSessionRequest, LoadSessionRequest, ListSessionsRequest, @@ -2603,6 +4522,9 @@ class ClientRequest(BaseModel): SetSessionModeRequest, PromptRequest, SetSessionModelRequest, + StartNesRequest, + SuggestNesRequest, + CloseNesRequest, Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], Any, ] @@ -2631,6 +4553,27 @@ class Content(BaseModel): ] +class CreateFormElicitationRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] + mode: Literal["form"] + + class SessionConfigOptionSelect(SessionConfigSelect): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3065,6 +5008,7 @@ class AgentRequest(BaseModel): ReleaseTerminalRequest, WaitForTerminalExitRequest, KillTerminalRequest, + Union[CreateFormElicitationRequest, CreateUrlElicitationRequest], Any, ] ] = None @@ -3096,6 +5040,10 @@ class AgentResponseMessage(BaseModel): Union[ InitializeResponse, AuthenticateResponse, + ListProvidersResponse, + SetProvidersResponse, + DisableProvidersResponse, + LogoutResponse, NewSessionResponse, LoadSessionResponse, ListSessionsResponse, @@ -3106,6 +5054,9 @@ class AgentResponseMessage(BaseModel): SetSessionConfigOptionResponse, PromptResponse, SetSessionModelResponse, + StartNesResponse, + SuggestNesResponse, + CloseNesResponse, Any, ], Field( @@ -3164,4 +5115,4 @@ class SessionNotification(BaseModel): class AgentNotification(BaseModel): method: str - params: Optional[Union[SessionNotification, Any]] = None + params: Optional[Union[SessionNotification, CompleteElicitationNotification, Any]] = None diff --git a/tests/test_rpc.py b/tests/test_rpc.py index b30e358..19bdc6c 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -2,7 +2,7 @@ import json import sys from pathlib import Path -from typing import Any +from typing import Any, cast import pytest @@ -36,6 +36,7 @@ DeniedOutcome, EmbeddedResourceContentBlock, EnvVariable, + ForkSessionResponse, HttpMcpServer, ImageContentBlock, Implementation, @@ -43,6 +44,7 @@ McpServerStdio, PermissionOption, ResourceContentBlock, + ResumeSessionResponse, SseMcpServer, TextContentBlock, ToolCallLocation, @@ -51,7 +53,7 @@ ToolCallUpdate, UserMessageChunk, ) -from tests.conftest import TestClient +from tests.conftest import TestAgent, TestClient # ------------------------ Tests -------------------------- @@ -327,6 +329,102 @@ async def test_list_sessions_stable(connect, agent, client): assert resp.sessions == [] +@pytest.mark.asyncio +async def test_session_additional_directories_roundtrip(server): + class _AdditionalDirectoriesAgent(TestAgent): + __test__ = False + + def __init__(self) -> None: + super().__init__() + self.calls: dict[str, list[str] | None] = {} + + async def new_session( + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> NewSessionResponse: + self.calls["new"] = additional_directories + return NewSessionResponse(session_id="sess") + + async def load_session( + self, + cwd: str, + session_id: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> LoadSessionResponse | None: + self.calls["load"] = additional_directories + return LoadSessionResponse() + + async def list_sessions( + self, + additional_directories: list[str] | None = None, + cursor: str | None = None, + cwd: str | None = None, + **kwargs: Any, + ) -> ListSessionsResponse: + self.calls["list"] = additional_directories + return ListSessionsResponse(sessions=[]) + + async def fork_session( + self, + cwd: str, + session_id: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> ForkSessionResponse: + self.calls["fork"] = additional_directories + return ForkSessionResponse(session_id="forked") + + async def resume_session( + self, + cwd: str, + session_id: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, + ) -> ResumeSessionResponse: + self.calls["resume"] = additional_directories + return ResumeSessionResponse() + + agent = _AdditionalDirectoriesAgent() + agent_side = AgentSideConnection( + cast(Agent, agent), + server.server_writer, + server.server_reader, + listening=True, + use_unstable_protocol=True, + ) + client_side = ClientSideConnection( + TestClient(), + server.client_writer, + server.client_reader, + use_unstable_protocol=True, + ) + directories = ["/workspace/lib", "/workspace/tools"] + + await client_side.new_session(cwd="/workspace", additional_directories=directories) + await client_side.load_session(cwd="/workspace", session_id="sess", additional_directories=directories) + await client_side.list_sessions(cwd="/workspace", additional_directories=directories) + await client_side.fork_session(cwd="/workspace", session_id="sess", additional_directories=directories) + await client_side.resume_session(cwd="/workspace", session_id="sess", additional_directories=directories) + + assert agent.calls == { + "new": directories, + "load": directories, + "list": directories, + "fork": directories, + "resume": directories, + } + + await client_side.close() + await agent_side.close() + + @pytest.mark.asyncio async def test_ignore_invalid_messages(connect, server): connect(connect_agent=True, connect_client=False) diff --git a/uv.lock b/uv.lock index eda1e22..8ac1c1f 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.9.0" +version = "0.10.0" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 3381092cb43346e68a468a56a1b13a930e96d3cf Mon Sep 17 00:00:00 2001 From: WeeeeeKdY Date: Thu, 7 May 2026 01:03:08 +0800 Subject: [PATCH 22/52] fix(schema): coerce string protocolVersion in InitializeRequest (#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some ACP clients (notably Zed) send a date string like "2024-11-05" as the protocolVersion instead of an integer. The Rust SDK already handles this gracefully — its Deserialize impl maps any string to V0 with the comment "Old versions used strings". The Python SDK rejected strings outright, causing the agent process to crash on the very first handshake. Changes: - Add `_coerce_protocol_version` field_validator to `InitializeRequest` in `src/acp/schema.py` that maps non-integer values to 1 (current stable version), mirroring the Rust SDK's lenient behaviour. - Add `CLASS_VALIDATOR_INJECTIONS` table and `_inject_field_validators` post-processing step to `scripts/gen_schema.py` so the validator is re-applied automatically on future schema regenerations. - Add `_ensure_pydantic_import` helper used by the injection step to add `field_validator` to the generated pydantic import line. Ref: https://github.com/agentclientprotocol/rust-sdk/blob/main/crates/agent-client-protocol-schema/src/version.rs Co-authored-by: liuyuan90 Co-authored-by: Chojan Shang --- scripts/gen_schema.py | 91 +++++++++++++++++++++++++++++++++++++++++++ src/acp/schema.py | 16 +++++++- tests/test_rpc.py | 20 +++++++++- 3 files changed, 124 insertions(+), 3 deletions(-) diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 9a181c9..9a78b26 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -116,6 +116,30 @@ ("ToolCallUpdate", "status", "ToolCallStatus", True), ) + +@dataclass(frozen=True) +class FieldValidatorInjection: + """A generated field validator that should be appended to one schema class.""" + + class_name: str + field_name: str + method_name: str + argument_name: str + return_type: str + comment_lines: tuple[str, ...] + body_lines: tuple[str, ...] + + def render(self) -> str: + lines = [ + f'@field_validator("{self.field_name}", mode="before")', + "@classmethod", + f"def {self.method_name}(cls, {self.argument_name}: Any) -> {self.return_type}:", + ] + lines.extend(f" # {line}" for line in self.comment_lines) + lines.extend(f" {line}" for line in self.body_lines) + return "\n".join(lines) + + DEFAULT_VALUE_OVERRIDES: tuple[tuple[str, str, str], ...] = ( ("AgentCapabilities", "mcp_capabilities", "McpCapabilities()"), ("AgentCapabilities", "session_capabilities", "SessionCapabilities()"), @@ -138,6 +162,31 @@ ), ) +# Classes that need a field_validator injected after generation. +CLASS_VALIDATOR_INJECTIONS: tuple[FieldValidatorInjection, ...] = ( + FieldValidatorInjection( + class_name="InitializeRequest", + field_name="protocol_version", + method_name="_coerce_protocol_version", + argument_name="value", + return_type="int", + comment_lines=( + 'Some clients (e.g. Zed) send a date string like "2024-11-05" instead', + "of an integer. The Rust SDK treats legacy strings as version 0; this", + "SDK maps unparsable values to 1 so the connection is not rejected.", + "See: https://github.com/agentclientprotocol/rust-sdk/blob/main/crates/agent-client-protocol-schema/src/version.rs", + ), + body_lines=( + "if isinstance(value, int):", + " return value", + "try:", + " return int(value)", + "except (TypeError, ValueError):", + " return 1", + ), + ), +) + @dataclass(frozen=True) class _ProcessingStep: @@ -200,6 +249,7 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: _ProcessingStep("apply default overrides", _apply_default_overrides), _ProcessingStep("attach description comments", _add_description_comments), _ProcessingStep("ensure custom BaseModel", _ensure_custom_base_model), + _ProcessingStep("inject field validators", _inject_field_validators), ) for step in processing_steps: @@ -356,6 +406,47 @@ def __getattr__(self, item: str) -> Any: return "\n".join(lines) + "\n" +def _ensure_pydantic_import(content: str, name: str) -> str: + """Add *name* to the ``from pydantic import ...`` line if not already present.""" + lines = content.splitlines() + for idx, line in enumerate(lines): + if not line.startswith("from pydantic import "): + continue + imports = [part.strip() for part in line[len("from pydantic import ") :].split(",")] + if name not in imports: + imports.append(name) + lines[idx] = "from pydantic import " + ", ".join(imports) + return "\n".join(lines) + "\n" + return content + + +def _inject_field_validators(content: str) -> str: + """Inject field_validator methods into classes listed in CLASS_VALIDATOR_INJECTIONS.""" + for injection in CLASS_VALIDATOR_INJECTIONS: + content = _ensure_pydantic_import(content, "field_validator") + + class_pattern = re.compile( + rf"(class {injection.class_name}\(BaseModel\):)(.*?)(?=\nclass |\Z)", + re.DOTALL, + ) + + def _append_validator( + match: re.Match[str], + _injection: FieldValidatorInjection = injection, + ) -> str: + header, block = match.group(1), match.group(2) + indented = "\n" + textwrap.indent(_injection.render(), " ") + return header + block + indented + "\n" + + content, count = class_pattern.subn(_append_validator, content, count=1) + if count == 0: + print( + f"Warning: class {injection.class_name} not found for validator injection", + file=sys.stderr, + ) + return content + + def _apply_field_overrides(content: str) -> str: for class_name, field_name, new_type, optional in FIELD_TYPE_OVERRIDES: if optional: diff --git a/src/acp/schema.py b/src/acp/schema.py index e942245..614c7ed 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -6,7 +6,7 @@ from enum import Enum from typing import Annotated, Any, Dict, List, Literal, Optional, Union -from pydantic import AnyUrl, BaseModel as _BaseModel, Field, RootModel, ConfigDict +from pydantic import AnyUrl, BaseModel as _BaseModel, Field, RootModel, ConfigDict, field_validator PermissionOptionKind = Literal["allow_once", "allow_always", "reject_once", "reject_always"] PlanEntryPriority = Literal["high", "medium", "low"] @@ -3922,6 +3922,20 @@ class InitializeRequest(BaseModel): ), ] + @field_validator("protocol_version", mode="before") + @classmethod + def _coerce_protocol_version(cls, value: Any) -> int: + # Some clients (e.g. Zed) send a date string like "2024-11-05" instead + # of an integer. The Rust SDK treats legacy strings as version 0; this + # SDK maps unparsable values to 1 so the connection is not rejected. + # See: https://github.com/agentclientprotocol/rust-sdk/blob/main/crates/agent-client-protocol-schema/src/version.rs + if isinstance(value, int): + return value + try: + return int(value) + except (TypeError, ValueError): + return 1 + class LoadSessionRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 19bdc6c..32c7464 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -236,8 +236,8 @@ async def test_invalid_params_results_in_error_response(connect, server): # Only start agent-side (server) so we can inject raw request from client socket connect(connect_agent=True, connect_client=False) - # Send initialize with wrong param type (protocolVersion should be int) - req = {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "oops"}} + # Send initialize without the required protocolVersion field. + req = {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}} server.client_writer.write((json.dumps(req) + "\n").encode()) await server.client_writer.drain() @@ -249,6 +249,22 @@ async def test_invalid_params_results_in_error_response(connect, server): assert resp["error"]["code"] == -32602 # invalid params +@pytest.mark.asyncio +async def test_initialize_accepts_legacy_string_protocol_version(connect, server): + # Only start agent-side (server) so we can inject raw request from client socket. + connect(connect_agent=True, connect_client=False) + + req = {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05"}} + server.client_writer.write((json.dumps(req) + "\n").encode()) + await server.client_writer.drain() + + line = await asyncio.wait_for(server.client_reader.readline(), timeout=1) + resp = json.loads(line) + assert resp["id"] == 1 + assert "error" not in resp + assert resp["result"]["protocolVersion"] == 1 + + @pytest.mark.asyncio async def test_method_not_found_results_in_error_response(connect, server): connect(connect_agent=True, connect_client=False) From 589aff783031e76947c46a5981ed6a241e9cde62 Mon Sep 17 00:00:00 2001 From: Al <7698600+aorumbayev@users.noreply.github.com> Date: Thu, 7 May 2026 20:28:46 +0200 Subject: [PATCH 23/52] fix: skip blank/whitespace-only lines in receive loop (#87) _receive_loop only checked for EOF (b""), but blank lines like b"\n" or b"\r\n" are truthy and reached json.loads(), causing JSONDecodeError. Strip each line and skip when empty before parsing. --- src/acp/connection.py | 3 +++ tests/test_rpc.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/acp/connection.py b/src/acp/connection.py index ccf2fc3..d99df0a 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -154,6 +154,9 @@ async def _receive_loop(self) -> None: line = await self._reader.readline() if not line: break + line = line.strip() + if not line: + continue try: message: dict[str, Any] = json.loads(line) except Exception: diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 32c7464..ecacaa5 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -460,6 +460,20 @@ async def test_ignore_invalid_messages(connect, server): await asyncio.wait_for(server.client_reader.readline(), timeout=0.1) +@pytest.mark.asyncio +async def test_blank_lines_skipped(connect, server): + connect(connect_agent=True, connect_client=False) + + for noise in [b"\n", b" \n", b"\r\n"]: + server.client_writer.write(noise) + req = {"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": 1}} + server.client_writer.write((json.dumps(req) + "\n").encode()) + await server.client_writer.drain() + + resp = json.loads(await asyncio.wait_for(server.client_reader.readline(), timeout=1)) + assert resp["id"] == 1 and "result" in resp + + class _ExampleAgent(Agent): __test__ = False From c864d7dfab878f4eb68a69539acc383930ba72a3 Mon Sep 17 00:00:00 2001 From: bird Date: Fri, 8 May 2026 03:07:28 +0800 Subject: [PATCH 24/52] feat: add receive_timeout parameter to Connection class (#84) - Add optional receive_timeout parameter to Connection.__init__ - Implement timeout handling in _receive_loop using asyncio.wait_for - Raise RequestError.internal_error on timeout for graceful error handling This allows users to configure a timeout for receiving messages from agents, preventing indefinite hangs when an agent becomes unresponsive. --- src/acp/connection.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/acp/connection.py b/src/acp/connection.py index d99df0a..32f150e 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -73,6 +73,7 @@ def __init__( sender_factory: SenderFactory | None = None, observers: list[StreamObserver] | None = None, listening: bool = True, + receive_timeout: float | None = None, ) -> None: self._handler = handler self._writer = writer @@ -103,6 +104,7 @@ def __init__( ) self._dispatcher.start() self._observers: list[StreamObserver] = list(observers or []) + self._receive_timeout = receive_timeout async def close(self) -> None: """Stop the receive loop and cancel any in-flight handler tasks.""" @@ -151,7 +153,7 @@ async def send_notification(self, method: str, params: JsonValue | None = None) async def _receive_loop(self) -> None: try: while True: - line = await self._reader.readline() + line = await asyncio.wait_for(self._reader.readline(), timeout=self._receive_timeout) if not line: break line = line.strip() @@ -166,6 +168,8 @@ async def _receive_loop(self) -> None: await self._process_message(message) except asyncio.CancelledError: return + except asyncio.TimeoutError: + raise RequestError.internal_error({"details": "Agent timeout"}) from None self._disconnect() async def _process_message(self, message: dict[str, Any]) -> None: From 5271d749f4d525899509b2b895e334908873fb93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 11:38:00 +0800 Subject: [PATCH 25/52] chore(deps): bump urllib3 in the uv group across 1 directory (#96) Bumps the uv group with 1 update in the / directory: [urllib3](https://github.com/urllib3/urllib3). Updates `urllib3` from 2.6.3 to 2.7.0 - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0) --- updated-dependencies: - dependency-name: urllib3 dependency-version: 2.7.0 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 8ac1c1f..093a078 100644 --- a/uv.lock +++ b/uv.lock @@ -1503,11 +1503,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.6.3" +version = "2.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] [[package]] From 19e924e9413b7b575582044d4fa92a73eb9c47bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 10:44:04 +0800 Subject: [PATCH 26/52] chore(deps): bump pymdown-extensions in the uv group across 1 directory (#99) Bumps the uv group with 1 update in the / directory: [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions). Updates `pymdown-extensions` from 10.16.1 to 10.21.3 - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.16.1...10.21.3) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-version: 10.21.3 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 093a078..5e9db7c 100644 --- a/uv.lock +++ b/uv.lock @@ -1090,15 +1090,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.16.1" +version = "10.21.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/55/b3/6d2b3f149bc5413b0a29761c2c5832d8ce904a1d7f621e86616d96f505cc/pymdown_extensions-10.16.1.tar.gz", hash = "sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91", size = 853277, upload-time = "2025-07-28T16:19:34.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140, upload-time = "2026-05-13T12:57:32.267Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/06/43084e6cbd4b3bc0e80f6be743b2e79fbc6eed8de9ad8c629939fa55d972/pymdown_extensions-10.16.1-py3-none-any.whl", hash = "sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d", size = 266178, upload-time = "2025-07-28T16:19:31.401Z" }, + { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002, upload-time = "2026-05-13T12:57:30.296Z" }, ] [[package]] From e9c6e9fa659ad98b658d33c55f744d40fad28ac5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 11:01:01 +0800 Subject: [PATCH 27/52] chore(deps): bump idna in the uv group across 1 directory (#100) Bumps the uv group with 1 update in the / directory: [idna](https://github.com/kjd/idna). Updates `idna` from 3.11 to 3.15 - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](https://github.com/kjd/idna/compare/v3.11...v3.15) --- updated-dependencies: - dependency-name: idna dependency-version: '3.15' dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 5e9db7c..991c7d8 100644 --- a/uv.lock +++ b/uv.lock @@ -424,11 +424,11 @@ wheels = [ [[package]] name = "idna" -version = "3.11" +version = "3.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, + { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, ] [[package]] From fd3de6e8483d7d68d325a6d310ffaf9f2f1e59d8 Mon Sep 17 00:00:00 2001 From: He Wang Date: Mon, 25 May 2026 00:48:54 +0800 Subject: [PATCH 28/52] fix(examples): improve gemini.py CLI experience (#103) - Support --acp flag with --experimental-acp fallback for older versions - Suppress Gemini CLI stderr noise in non-debug mode - Drain stdin before terminating subprocess for cleaner shutdown - Catch KeyboardInterrupt in main() to avoid noisy traceback Co-authored-by: Claude Sonnet 4 --- docs/quickstart.md | 4 ++-- examples/gemini.py | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 5e79205..79a5a0e 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -16,7 +16,7 @@ Spin up a working ACP agent/client loop in minutes. Keep this page beside the te - Python 3.10–3.14 with `pip` or `uv` - An ACP-capable client such as Zed (recommended for validation) -- Optional: the Gemini CLI (`gemini --experimental-acp`) for the bridge example +- Optional: the Gemini CLI (`gemini --acp`; use `--experimental-acp` for older versions) for the bridge example ## Step 1 — Install the SDK @@ -145,7 +145,7 @@ Run it with `run_agent()` inside an async entrypoint and wire it to your client. - [`examples/echo_agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/echo_agent.py) for the smallest streaming agent - [`examples/agent.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/agent.py) for an implementation that negotiates capabilities and streams richer updates - [`examples/duet.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/duet.py) to see `spawn_agent_process` in action alongside the interactive client -- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--acp`) directly from Python +- [`examples/gemini.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/gemini.py) to drive the Gemini CLI (`--acp`; use `--experimental-acp` for older versions) directly from Python Need builders for common payloads? `acp.helpers` mirrors the Go/TS helper APIs: diff --git a/examples/gemini.py b/examples/gemini.py index bc824af..85c862f 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -328,7 +328,8 @@ async def run(argv: list[str]) -> int: # noqa: C901 *cmd, stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, - stderr=None, + # Suppress Gemini CLI diagnostic noise unless debugging + stderr=None if args.debug else asyncio.subprocess.DEVNULL, ) except FileNotFoundError as exc: print(f"Failed to start Gemini CLI: {exc}", file=sys.stderr) @@ -412,6 +413,10 @@ def _print_request_error(stage: str, err: RequestError) -> None: async def _shutdown(proc: asyncio.subprocess.Process, conn: ClientSideConnection) -> None: with contextlib.suppress(Exception): await asyncio.wait_for(conn.close(), timeout=2) + if proc.stdin is not None: + with contextlib.suppress(Exception): + proc.stdin.close() + await asyncio.wait_for(proc.stdin.wait_closed(), timeout=2) if proc.returncode is None: proc.terminate() try: @@ -424,7 +429,10 @@ async def _shutdown(proc: asyncio.subprocess.Process, conn: ClientSideConnection def main(argv: list[str] | None = None) -> int: args = sys.argv if argv is None else argv - return asyncio.run(run(list(args))) + try: + return asyncio.run(run(list(args))) + except KeyboardInterrupt: + return 1 if __name__ == "__main__": From 7acca149d3e404400409fdbd97351403b61ff03b Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Sun, 24 May 2026 10:00:41 -0700 Subject: [PATCH 29/52] fix: assign receive-loop attributes before spawning recv task (#102) * fix: assign receive-loop attributes before spawning recv task * fix: guard eager task regression test by Python version --------- Co-authored-by: Chojan Shang --- src/acp/connection.py | 4 ++-- tests/test_rpc.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/acp/connection.py b/src/acp/connection.py index 32f150e..ff1cb19 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -86,6 +86,8 @@ def __init__( self._closed = False self._disconnected = False self._sender = (sender_factory or self._default_sender_factory)(self._writer, self._tasks) + self._observers: list[StreamObserver] = list(observers or []) + self._receive_timeout = receive_timeout if listening: self._recv_task = self._tasks.create( self._receive_loop(), @@ -103,8 +105,6 @@ def __init__( self._run_notification, ) self._dispatcher.start() - self._observers: list[StreamObserver] = list(observers or []) - self._receive_timeout = receive_timeout async def close(self) -> None: """Stop the receive loop and cancel any in-flight handler tasks.""" diff --git a/tests/test_rpc.py b/tests/test_rpc.py index ecacaa5..be5e06c 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -676,3 +676,32 @@ async def test_spawn_agent_process_roundtrip(tmp_path): assert test_client.notifications assert process.returncode is not None + + +@pytest.mark.asyncio +async def test_connection_init_under_eager_task_factory(server): + eager_task_factory = getattr(asyncio, "eager_task_factory", None) + if eager_task_factory is None: + pytest.skip("asyncio.eager_task_factory requires Python 3.12+") + + # Regression: under asyncio.eager_task_factory the receive loop runs synchronously + # up to its first await inside Connection.__init__, so every attribute it reads + # (e.g. _receive_timeout) must be assigned before _tasks.create(_receive_loop()). + loop = asyncio.get_running_loop() + previous_factory = loop.get_task_factory() + loop.set_task_factory(eager_task_factory) + try: + conn = Connection( + lambda method, params, is_notification: None, + server.client_writer, + server.client_reader, + receive_timeout=0.5, + ) + finally: + loop.set_task_factory(previous_factory) + + assert conn._receive_timeout == 0.5 + # Let the loop tick once so any deferred receive-task crash would land. + await asyncio.sleep(0) + assert conn._disconnected is False + await conn.close() From 8cd8391e4e5031d734044d8120a89f988a62b54b Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Mon, 25 May 2026 02:45:07 +0800 Subject: [PATCH 30/52] release: 0.10.1 (#104) * release: 0.10.1 * chore(deps): bump pygments to 2.20.0 --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e8eb93d..eaab0e0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.10.0" +version = "0.10.1" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 991c7d8..c5f8a66 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.10.0" +version = "0.10.1" source = { editable = "." } dependencies = [ { name = "pydantic" }, @@ -1081,11 +1081,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] [[package]] From d6e5defc382ac9a40cc10a06f384703b3706feac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 17:15:27 +0800 Subject: [PATCH 31/52] chore(deps): bump uv in the uv group across 1 directory (#107) Bumps the uv group with 1 update in the / directory: [uv](https://github.com/astral-sh/uv). Updates `uv` from 0.11.6 to 0.11.15 - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.11.6...0.11.15) --- updated-dependencies: - dependency-name: uv dependency-version: 0.11.15 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/uv.lock b/uv.lock index c5f8a66..cdc2105 100644 --- a/uv.lock +++ b/uv.lock @@ -1512,28 +1512,28 @@ wheels = [ [[package]] name = "uv" -version = "0.11.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dd/f3/8aceeab67ea69805293ab290e7ca8cc1b61a064d28b8a35c76d8eba063dd/uv-0.11.6.tar.gz", hash = "sha256:e3b21b7e80024c95ff339fcd147ac6fc3dd98d3613c9d45d3a1f4fd1057f127b", size = 4073298, upload-time = "2026-04-09T12:09:01.738Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/fe/4b61a3d5ad9d02e8a4405026ccd43593d7044598e0fa47d892d4dafe44c9/uv-0.11.6-py3-none-linux_armv6l.whl", hash = "sha256:ada04dcf89ddea5b69d27ac9cdc5ef575a82f90a209a1392e930de504b2321d6", size = 23780079, upload-time = "2026-04-09T12:08:56.609Z" }, - { url = "https://files.pythonhosted.org/packages/52/db/d27519a9e1a5ffee9d71af1a811ad0e19ce7ab9ae815453bef39dd479389/uv-0.11.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5be013888420f96879c6e0d3081e7bcf51b539b034a01777041934457dfbedf3", size = 23214721, upload-time = "2026-04-09T12:09:32.228Z" }, - { url = "https://files.pythonhosted.org/packages/a6/8f/4399fa8b882bd7e0efffc829f73ab24d117d490a93e6bc7104a50282b854/uv-0.11.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ffa5dc1cbb52bdce3b8447e83d1601a57ad4da6b523d77d4b47366db8b1ceb18", size = 21750109, upload-time = "2026-04-09T12:09:24.357Z" }, - { url = "https://files.pythonhosted.org/packages/32/07/5a12944c31c3dda253632da7a363edddb869ed47839d4d92a2dc5f546c93/uv-0.11.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bfb107b4dade1d2c9e572992b06992d51dd5f2136eb8ceee9e62dd124289e825", size = 23551146, upload-time = "2026-04-09T12:09:10.439Z" }, - { url = "https://files.pythonhosted.org/packages/79/5b/2ec8b0af80acd1016ed596baf205ddc77b19ece288473b01926c4a9cf6db/uv-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:9e2fe7ce12161d8016b7deb1eaad7905a76ff7afec13383333ca75e0c4b5425d", size = 23331192, upload-time = "2026-04-09T12:09:34.792Z" }, - { url = "https://files.pythonhosted.org/packages/62/7d/eea35935f2112b21c296a3e42645f3e4b1aa8bcd34dcf13345fbd55134b7/uv-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ed9c6f70c25e8dfeedddf4eddaf14d353f5e6b0eb43da9a14d3a1033d51d915", size = 23337686, upload-time = "2026-04-09T12:09:18.522Z" }, - { url = "https://files.pythonhosted.org/packages/21/47/2584f5ab618f6ebe9bdefb2f765f2ca8540e9d739667606a916b35449eec/uv-0.11.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d68a013e609cebf82077cbeeb0809ed5e205257814273bfd31e02fc0353bbfc2", size = 25008139, upload-time = "2026-04-09T12:09:03.983Z" }, - { url = "https://files.pythonhosted.org/packages/95/81/497ae5c1d36355b56b97dc59f550c7e89d0291c163a3f203c6f341dff195/uv-0.11.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93f736dddca03dae732c6fdea177328d3bc4bf137c75248f3d433c57416a4311", size = 25712458, upload-time = "2026-04-09T12:09:07.598Z" }, - { url = "https://files.pythonhosted.org/packages/3c/1c/74083238e4fab2672b63575b9008f1ea418b02a714bcfcf017f4f6a309b6/uv-0.11.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e96a66abe53fced0e3389008b8d2eff8278cfa8bb545d75631ae8ceb9c929aba", size = 24915507, upload-time = "2026-04-09T12:08:50.892Z" }, - { url = "https://files.pythonhosted.org/packages/5a/ee/e14fe10ba455a823ed18233f12de6699a601890905420b5c504abf115116/uv-0.11.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b096311b2743b228df911a19532b3f18fa420bf9530547aecd6a8e04bbfaccd", size = 24971011, upload-time = "2026-04-09T12:08:54.016Z" }, - { url = "https://files.pythonhosted.org/packages/3c/a1/7b9c83eaadf98e343317ff6384a7227a4855afd02cdaf9696bcc71ee6155/uv-0.11.6-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:904d537b4a6e798015b4a64ff5622023bd4601b43b6cd1e5f423d63471f5e948", size = 23640234, upload-time = "2026-04-09T12:09:15.735Z" }, - { url = "https://files.pythonhosted.org/packages/d6/51/75ccdd23e76ff1703b70eb82881cd5b4d2a954c9679f8ef7e0136ef2cfab/uv-0.11.6-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:4ed8150c26b5e319381d75ae2ce6aba1e9c65888f4850f4e3b3fa839953c90a5", size = 24452664, upload-time = "2026-04-09T12:09:26.875Z" }, - { url = "https://files.pythonhosted.org/packages/4d/86/ace80fe47d8d48b5e3b5aee0b6eb1a49deaacc2313782870250b3faa36f5/uv-0.11.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:1c9218c8d4ac35ca6e617fb0951cc0ab2d907c91a6aea2617de0a5494cf162c0", size = 24494599, upload-time = "2026-04-09T12:09:37.368Z" }, - { url = "https://files.pythonhosted.org/packages/05/2d/4b642669b56648194f026de79bc992cbfc3ac2318b0a8d435f3c284934e8/uv-0.11.6-py3-none-musllinux_1_1_i686.whl", hash = "sha256:9e211c83cc890c569b86a4183fcf5f8b6f0c7adc33a839b699a98d30f1310d3a", size = 24159150, upload-time = "2026-04-09T12:09:13.17Z" }, - { url = "https://files.pythonhosted.org/packages/ae/24/7eecd76fe983a74fed1fc700a14882e70c4e857f1d562a9f2303d4286c12/uv-0.11.6-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:d2a1d2089afdf117ad19a4c1dd36b8189c00ae1ad4135d3bfbfced82342595cf", size = 25164324, upload-time = "2026-04-09T12:08:59.56Z" }, - { url = "https://files.pythonhosted.org/packages/27/e0/bbd4ba7c2e5067bbba617d87d306ec146889edaeeaa2081d3e122178ca08/uv-0.11.6-py3-none-win32.whl", hash = "sha256:6e8344f38fa29f85dcfd3e62dc35a700d2448f8e90381077ef393438dcd5012e", size = 22865693, upload-time = "2026-04-09T12:09:21.415Z" }, - { url = "https://files.pythonhosted.org/packages/a5/33/1983ce113c538a856f2d620d16e39691962ecceef091a84086c5785e32e5/uv-0.11.6-py3-none-win_amd64.whl", hash = "sha256:a28bea69c1186303d1200f155c7a28c449f8a4431e458fcf89360cc7ef546e40", size = 25371258, upload-time = "2026-04-09T12:09:40.52Z" }, - { url = "https://files.pythonhosted.org/packages/35/01/be0873f44b9c9bc250fcbf263367fcfc1f59feab996355bcb6b52fff080d/uv-0.11.6-py3-none-win_arm64.whl", hash = "sha256:a78f6d64b9950e24061bc7ec7f15ff8089ad7f5a976e7b65fcadce58fe02f613", size = 23869585, upload-time = "2026-04-09T12:09:29.425Z" }, +version = "0.11.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/609d5d01ba21dc8f0974610ca7802fbb2c946a0c38665cfe5c5aeddbefb5/uv-0.11.15.tar.gz", hash = "sha256:755f959ec6a2fd8ccb6ee76ad90ab759d2eb1f4797444078645dd1ee4bca92d6", size = 4159545, upload-time = "2026-05-18T19:57:48.133Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/7c/dcc230c5911884d8848145dabcac8fb95a5ed6f9fe1c57fae8242618f28a/uv-0.11.15-py3-none-linux_armv6l.whl", hash = "sha256:83b04ab49514a0a761ffedb36a748ee81f87746671e72088e5f32c9585e5f1a9", size = 23110183, upload-time = "2026-05-18T19:57:23.051Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/efd4e044b60eb9c3c12ee386be098d56c335538ccec7caa49349cfba9344/uv-0.11.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cae61f737be075b90be9e3f07d961072aed7019f4c9b8ed5c5d41c4d6cade3", size = 22637941, upload-time = "2026-05-18T19:57:26.752Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b8/48627f895a1569e576822e0a8416aa4797eb4a4551de21a4ad97b9b5819d/uv-0.11.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9accae33619a9166e5c48531deb455d672cfb89f9357a00975e669c76b0bd49f", size = 21258803, upload-time = "2026-05-18T19:57:05.473Z" }, + { url = "https://files.pythonhosted.org/packages/af/50/4bc8a148274feabee2d9c9f1fa15009e10c0228dfe57981ee3ea2ef1d481/uv-0.11.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c0cf52cd6d50bb9e05e2d968f45f80761107e4cbc8d4a26d9758f9d8274aaec1", size = 23066178, upload-time = "2026-05-18T19:57:33.058Z" }, + { url = "https://files.pythonhosted.org/packages/a9/56/139fc3bec9a8b0a25bfe2196123adb9f16124da437bf4fbcf0d21cfcafb2/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:49dc6ed70bff00937384f96cdc4b1a4742d18e5504ec2c4a1214dba2dee5687a", size = 22705332, upload-time = "2026-05-18T19:57:36.714Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b0/b18b3dd204f8c213236a1ebd148e009861637129a8cce34df0e9aa22ed40/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:adb9a89352539fdd8f7cd5f9966cf9f94fc5b98e0ccdf5003a04123dc6423bec", size = 22707534, upload-time = "2026-05-18T19:58:04.117Z" }, + { url = "https://files.pythonhosted.org/packages/76/36/3ca09f95572df99d361b49c96b1297149e96e120d8d1ecf074095a4b6da4/uv-0.11.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40ff67e3f8e8a7533781a2e892a534975a93acb83ea35460e64e7b2bf2111774", size = 24096607, upload-time = "2026-05-18T19:58:11.625Z" }, + { url = "https://files.pythonhosted.org/packages/64/be/3bdee21a296bbf5336a526e3613d0e7d4538dacc39c62d7fcba55d15f6b0/uv-0.11.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6463a299ed7e6b5a800ed6f108af8e1588352629424133ddef7572b0e1e1118", size = 25082562, upload-time = "2026-05-18T19:57:40.69Z" }, + { url = "https://files.pythonhosted.org/packages/cd/73/f371f3689ffe741066468d001d85f739fc4b5574de83b639ef19b5e8a7f4/uv-0.11.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68c1e62d4b78578b90b833553286b65d6a7e327537716441068583ba652ec4f5", size = 24253391, upload-time = "2026-05-18T19:57:18.47Z" }, + { url = "https://files.pythonhosted.org/packages/d3/16/fe392d618af6b00c064b3e718d585dcf791546a77c5123a5bec07ce53a0a/uv-0.11.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98edf1bdaf82447014852051d93e3ee95012509c567bf057fd117e6bdbd9a807", size = 24415871, upload-time = "2026-05-18T19:58:19.651Z" }, + { url = "https://files.pythonhosted.org/packages/6e/24/2e92a052fb6334fcd746d1c7cb57847c204b118c84f5da53c0f9e129f7b7/uv-0.11.15-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:be8f76d25bcf4c92bb384240ac1bf9aa7f51063d0bdeca4c9cf0ec3ed8b145e0", size = 23159007, upload-time = "2026-05-18T19:57:10.653Z" }, + { url = "https://files.pythonhosted.org/packages/3d/2e/6923d0658d164bb2c435ed1868aa2d49b3074594679917a001ff92dc95bb/uv-0.11.15-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:f9f4fbbf4fe485522054f3c7496c6e8e932d6436e4200ff3daf718db0b7c7bd5", size = 23769385, upload-time = "2026-05-18T19:58:15.856Z" }, + { url = "https://files.pythonhosted.org/packages/a4/99/7e34cd949e57360814e8064cc9fb7104df445d0f6a663504e5f7473480aa/uv-0.11.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0ed920e896b2fd13a35031707e307e42fbb2681458b967440a17272d86d49137", size = 23860973, upload-time = "2026-05-18T19:57:55.575Z" }, + { url = "https://files.pythonhosted.org/packages/28/98/8fe1f5f9d816e94569a0298dd8e0936801097625fa1952162951f0d628b6/uv-0.11.15-py3-none-musllinux_1_1_i686.whl", hash = "sha256:41d907611f3e6a13262807fd7f0a17849f76285ca80f536f6b3943732bdc6656", size = 23431392, upload-time = "2026-05-18T19:57:59.814Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6b/76a1ce2fa860026913a5941700cdc7d715fce9c3277a3fa3489cf2523ca0/uv-0.11.15-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e3b68f8bf1a4568710f77e5bda9182ce7682811d89a8e7468c22460e032b234d", size = 24519478, upload-time = "2026-05-18T19:57:51.165Z" }, + { url = "https://files.pythonhosted.org/packages/43/60/1d58e8a05718cb50494763115710b73846cacb651fd735d285233fd72c59/uv-0.11.15-py3-none-win32.whl", hash = "sha256:8e2da3076761086a5b76869c3f38ef0509c836046ef41ddd19485dfd7271dca9", size = 22020178, upload-time = "2026-05-18T19:58:07.64Z" }, + { url = "https://files.pythonhosted.org/packages/55/53/40fcefcb348af660488597ed3c01363df7344e60611f8883750dc596f5c6/uv-0.11.15-py3-none-win_amd64.whl", hash = "sha256:cc3915ab291a1ecaf31de05f5d8bd70d09c66fe9911a53f70d9efa62ff0dbd8a", size = 24668779, upload-time = "2026-05-18T19:57:44.894Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7d/fa3a9960c95af9bbe2a629048760d0b9b4fead8ccd4f2235af747ec7cdf0/uv-0.11.15-py3-none-win_arm64.whl", hash = "sha256:4f39426a13dee24897aed60c4b98058c66f18bd983885ac5f4a54a04b24fbddf", size = 23198178, upload-time = "2026-05-18T19:57:14.68Z" }, ] [[package]] From 50a27ef41a4aa255e4de5eac675f2e06871b918f Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sun, 31 May 2026 18:15:06 +0800 Subject: [PATCH 32/52] feat: update ACP schema to v0.13.3 (#106) --- pyproject.toml | 2 +- schema/VERSION | 2 +- schema/meta.json | 5 + schema/schema.json | 479 +++++++++++++++++++++-- scripts/gen_schema.py | 1 + src/acp/client/connection.py | 19 +- src/acp/interfaces.py | 15 +- src/acp/meta.py | 7 +- src/acp/schema.py | 715 ++++++++++++++++++++++++----------- tests/test_rpc.py | 7 +- uv.lock | 2 +- 11 files changed, 960 insertions(+), 294 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index eaab0e0..6432be2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.10.1" +version = "0.11.0" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/schema/VERSION b/schema/VERSION index f1d3366..2a50c94 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.12.2 +refs/tags/v0.13.3 diff --git a/schema/meta.json b/schema/meta.json index 6d1dd24..5775e36 100644 --- a/schema/meta.json +++ b/schema/meta.json @@ -8,6 +8,7 @@ "document_did_save": "document/didSave", "initialize": "initialize", "logout": "logout", + "mcp_message": "mcp/message", "nes_accept": "nes/accept", "nes_close": "nes/close", "nes_reject": "nes/reject", @@ -18,6 +19,7 @@ "providers_set": "providers/set", "session_cancel": "session/cancel", "session_close": "session/close", + "session_delete": "session/delete", "session_fork": "session/fork", "session_list": "session/list", "session_load": "session/load", @@ -33,6 +35,9 @@ "elicitation_create": "elicitation/create", "fs_read_text_file": "fs/read_text_file", "fs_write_text_file": "fs/write_text_file", + "mcp_connect": "mcp/connect", + "mcp_disconnect": "mcp/disconnect", + "mcp_message": "mcp/message", "session_request_permission": "session/request_permission", "session_update": "session/update", "terminal_create": "terminal/create", diff --git a/schema/schema.json b/schema/schema.json index 709a0d9..80b2cbf 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -33,7 +33,7 @@ "x-side": "agent" }, "AgentAuthCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent.", + "description": "Authentication-related capabilities supported by the agent.", "properties": { "_meta": { "additionalProperties": true, @@ -75,7 +75,7 @@ } ], "default": {}, - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent." + "description": "Authentication-related capabilities supported by the agent." }, "loadSession": { "default": false, @@ -89,6 +89,7 @@ } ], "default": { + "acp": false, "http": false, "sse": false }, @@ -178,6 +179,15 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification that a URL-based elicitation has completed.", "title": "CompleteElicitationNotification" }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpNotification" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReceives an MCP-over-ACP notification.", + "title": "MessageMcpNotification" + }, { "allOf": [ { @@ -188,7 +198,7 @@ "title": "ExtNotification" } ], - "description": "All possible notifications that an agent can send to a client.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly - use the notification methods on the [`Client`] trait instead.\n\nNotifications do not expect a response." + "description": "All possible notifications that an agent can send to a client.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response." }, { "type": "null" @@ -295,6 +305,33 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests structured user input via a form or URL.", "title": "CreateElicitationRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/ConnectMcpRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nOpens an MCP-over-ACP connection.", + "title": "ConnectMcpRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", + "title": "MessageMcpRequest" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DisconnectMcpRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an MCP-over-ACP connection.", + "title": "DisconnectMcpRequest" + }, { "allOf": [ { @@ -305,7 +342,7 @@ "title": "ExtMethodRequest" } ], - "description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly - instead, use the methods on the [`Client`] trait.\n\nThis enum encompasses all method calls from agent to client." + "description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from agent to client." }, { "type": "null" @@ -356,18 +393,18 @@ { "allOf": [ { - "$ref": "#/$defs/SetProvidersResponse" + "$ref": "#/$defs/SetProviderResponse" } ], - "title": "SetProvidersResponse" + "title": "SetProviderResponse" }, { "allOf": [ { - "$ref": "#/$defs/DisableProvidersResponse" + "$ref": "#/$defs/DisableProviderResponse" } ], - "title": "DisableProvidersResponse" + "title": "DisableProviderResponse" }, { "allOf": [ @@ -401,6 +438,14 @@ ], "title": "ListSessionsResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/DeleteSessionResponse" + } + ], + "title": "DeleteSessionResponse" + }, { "allOf": [ { @@ -488,6 +533,14 @@ } ], "title": "ExtMethodResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpResponse" + } + ], + "title": "MessageMcpResponse" } ], "description": "All possible responses that an agent can send to a client.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `ClientRequest` variants." @@ -1248,6 +1301,15 @@ "description": "**UNSTABLE**\n\nNotification sent when a suggestion is rejected.", "title": "RejectNesNotification" }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpNotification" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSends an MCP-over-ACP notification.", + "title": "MessageMcpNotification" + }, { "allOf": [ { @@ -1258,7 +1320,7 @@ "title": "ExtNotification" } ], - "description": "All possible notifications that a client can send to an agent.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly - use the notification methods on the [`Agent`] trait instead.\n\nNotifications do not expect a response." + "description": "All possible notifications that a client can send to an agent.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response." }, { "type": "null" @@ -1314,20 +1376,20 @@ { "allOf": [ { - "$ref": "#/$defs/SetProvidersRequest" + "$ref": "#/$defs/SetProviderRequest" } ], "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReplaces the configuration for a provider.", - "title": "SetProvidersRequest" + "title": "SetProviderRequest" }, { "allOf": [ { - "$ref": "#/$defs/DisableProvidersRequest" + "$ref": "#/$defs/DisableProviderRequest" } ], "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDisables a provider.", - "title": "DisableProvidersRequest" + "title": "DisableProviderRequest" }, { "allOf": [ @@ -1335,7 +1397,7 @@ "$ref": "#/$defs/LogoutRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLogs out of the current authenticated state.\n\nAfter a successful logout, all new sessions will require authentication.\nThere is no guarantee about the behavior of already running sessions.", + "description": "Logs out of the current authenticated state.\n\nAfter a successful logout, all new sessions will require authentication.\nThere is no guarantee about the behavior of already running sessions.", "title": "LogoutRequest" }, { @@ -1365,6 +1427,15 @@ "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", "title": "ListSessionsRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/DeleteSessionRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDeletes an existing session from `session/list`.\n\nThis method is only available if the agent advertises the `sessionCapabilities.delete` capability.", + "title": "DeleteSessionRequest" + }, { "allOf": [ { @@ -1455,6 +1526,15 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active NES session and frees up any resources associated with it.\n\nThe agent must cancel any ongoing work and then free up any resources\nassociated with the NES session.", "title": "CloseNesRequest" }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpRequest" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", + "title": "MessageMcpRequest" + }, { "allOf": [ { @@ -1465,7 +1545,7 @@ "title": "ExtMethodRequest" } ], - "description": "All possible requests that a client can send to an agent.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly - instead, use the methods on the [`Agent`] trait.\n\nThis enum encompasses all method calls from client to agent." + "description": "All possible requests that a client can send to an agent.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from client to agent." }, { "type": "null" @@ -1561,6 +1641,22 @@ ], "title": "CreateElicitationResponse" }, + { + "allOf": [ + { + "$ref": "#/$defs/ConnectMcpResponse" + } + ], + "title": "ConnectMcpResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/DisconnectMcpResponse" + } + ], + "title": "DisconnectMcpResponse" + }, { "allOf": [ { @@ -1568,6 +1664,14 @@ } ], "title": "ExtMethodResponse" + }, + { + "allOf": [ + { + "$ref": "#/$defs/MessageMcpResponse" + } + ], + "title": "MessageMcpResponse" } ], "description": "All possible responses that a client can send to an agent.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `AgentRequest` variants." @@ -1736,6 +1840,60 @@ ], "type": "object" }, + "ConnectMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/connect`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "acpId": { + "allOf": [ + { + "$ref": "#/$defs/McpServerAcpId" + } + ], + "description": "The ACP MCP server ID that was provided by the component declaring the MCP server." + } + }, + "required": [ + "acpId" + ], + "type": "object", + "x-method": "mcp/connect", + "x-side": "client" + }, + "ConnectMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/connect`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "connectionId": { + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ], + "description": "The unique identifier for this MCP-over-ACP connection." + } + }, + "required": [ + "connectionId" + ], + "type": "object", + "x-method": "mcp/connect", + "x-side": "client" + }, "Content": { "description": "Standard content block (text, images, resources).", "properties": { @@ -2149,6 +2307,49 @@ ], "type": "object" }, + "DeleteSessionRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for deleting an existing session from `session/list`.\n\nOnly available if the Agent supports the `sessionCapabilities.delete` capability.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "sessionId": { + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ], + "description": "The ID of the session to delete." + } + }, + "required": [ + "sessionId" + ], + "type": "object", + "x-method": "session/delete", + "x-side": "agent" + }, + "DeleteSessionResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from deleting a session.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "session/delete", + "x-side": "agent" + }, "DidChangeDocumentNotification": { "description": "Notification sent when a file is edited.", "properties": { @@ -2396,7 +2597,7 @@ ], "type": "object" }, - "DisableProvidersRequest": { + "DisableProviderRequest": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/disable`.", "properties": { "_meta": { @@ -2419,7 +2620,7 @@ "x-method": "providers/disable", "x-side": "agent" }, - "DisableProvidersResponse": { + "DisableProviderResponse": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/disable`.", "properties": { "_meta": { @@ -2435,6 +2636,49 @@ "x-method": "providers/disable", "x-side": "agent" }, + "DisconnectMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/disconnect`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "connectionId": { + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ], + "description": "The MCP-over-ACP connection to close." + } + }, + "required": [ + "connectionId" + ], + "type": "object", + "x-method": "mcp/disconnect", + "x-side": "client" + }, + "DisconnectMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/disconnect`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object", + "x-method": "mcp/disconnect", + "x-side": "client" + }, "ElicitationAcceptAction": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe user accepted the elicitation and provided content.", "properties": { @@ -3346,6 +3590,7 @@ "auth": {}, "loadSession": false, "mcpCapabilities": { + "acp": false, "http": false, "sse": false }, @@ -3538,13 +3783,6 @@ "null" ] }, - "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nFilter sessions by the exact ordered additional workspace roots. Each path must be absolute.\n\nThis filter applies only when the field is present and non-empty. When\nomitted or empty, no additional-root filter is applied.", - "items": { - "type": "string" - }, - "type": "array" - }, "cursor": { "description": "Opaque cursor token from a previous response's nextCursor field for cursor-based pagination", "type": [ @@ -3644,7 +3882,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", "items": { "type": "string" }, @@ -3728,7 +3966,7 @@ "x-side": "agent" }, "LogoutCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLogout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "description": "Logout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", "properties": { "_meta": { "additionalProperties": true, @@ -3742,7 +3980,7 @@ "type": "object" }, "LogoutRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for the logout method.\n\nTerminates the current authenticated session.", + "description": "Request parameters for the logout method.\n\nTerminates the current authenticated session.", "properties": { "_meta": { "additionalProperties": true, @@ -3758,7 +3996,7 @@ "x-side": "agent" }, "LogoutResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to the `logout` method.", + "description": "Response to the `logout` method.", "properties": { "_meta": { "additionalProperties": true, @@ -3784,6 +4022,11 @@ "null" ] }, + "acp": { + "default": false, + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`].", + "type": "boolean" + }, "http": { "default": false, "description": "Agent supports [`McpServer::Http`].", @@ -3797,6 +4040,10 @@ }, "type": "object" }, + "McpConnectionId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for an active MCP-over-ACP connection.", + "type": "string" + }, "McpServer": { "anyOf": [ { @@ -3835,6 +4082,24 @@ ], "type": "object" }, + { + "allOf": [ + { + "$ref": "#/$defs/McpServerAcp" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.acp` is `true`.\nThe MCP server is provided by an ACP component and communicates over the ACP channel.", + "properties": { + "type": { + "const": "acp", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, { "allOf": [ { @@ -3847,6 +4112,40 @@ ], "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)" }, + "McpServerAcp": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration for MCP.\n\nThe MCP server is provided by an ACP component and communicates over the ACP channel\nusing `mcp/connect`, `mcp/message`, and `mcp/disconnect`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/McpServerAcpId" + } + ], + "description": "Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." + }, + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" + } + }, + "required": [ + "name", + "id" + ], + "type": "object" + }, + "McpServerAcpId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an MCP server using the ACP transport.\n\nThe value is opaque and generated by the ACP component providing the MCP server. It is\nused by `mcp/connect` to route connection requests back to the component that declared the\nserver.", + "type": "string" + }, "McpServerHttp": { "description": "HTTP transport configuration for MCP.", "properties": { @@ -3957,6 +4256,91 @@ ], "type": "object" }, + "MessageMcpNotification": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification parameters for `mcp/message`.\n\nThis is used when the wrapped MCP message is a notification and the outer JSON-RPC\nenvelope has no `id`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "connectionId": { + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ], + "description": "The MCP-over-ACP connection this message is sent on." + }, + "method": { + "description": "The inner MCP method name.", + "type": "string" + }, + "params": { + "additionalProperties": true, + "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "type": [ + "object", + "null" + ] + } + }, + "required": [ + "connectionId", + "method" + ], + "type": "object", + "x-method": "mcp/message", + "x-side": "both" + }, + "MessageMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/message`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "connectionId": { + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ], + "description": "The MCP-over-ACP connection this message is sent on." + }, + "method": { + "description": "The inner MCP method name.", + "type": "string" + }, + "params": { + "additionalProperties": true, + "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "type": [ + "object", + "null" + ] + } + }, + "required": [ + "connectionId", + "method" + ], + "type": "object", + "x-method": "mcp/message", + "x-side": "both" + }, + "MessageMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/message`.\n\nThis is the inner MCP response result payload. Any JSON value is valid.", + "x-method": "mcp/message", + "x-side": "both" + }, "ModelId": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for a model.", "type": "string" @@ -5884,7 +6268,7 @@ "type": "string" } ], - "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." }, "RequestPermissionOutcome": { "description": "The outcome of a permission request.", @@ -6067,7 +6451,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", "items": { "type": "string" }, @@ -6183,7 +6567,7 @@ "type": "object" }, "SessionAdditionalDirectoriesCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories` field on\nsupported session lifecycle requests and `session/list`.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", "properties": { "_meta": { "additionalProperties": true, @@ -6216,7 +6600,7 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session." }, "close": { "anyOf": [ @@ -6229,6 +6613,17 @@ ], "description": "Whether the agent supports `session/close`." }, + "delete": { + "anyOf": [ + { + "$ref": "#/$defs/SessionDeleteCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." + }, "fork": { "anyOf": [ { @@ -6540,6 +6935,20 @@ "description": "Unique identifier for a session configuration option value.", "type": "string" }, + "SessionDeleteCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/delete` method.\n\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, "SessionForkCapabilities": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", "properties": { @@ -6570,7 +6979,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthoritative ordered additional workspace roots for this session. Each path must be absolute.\n\nWhen omitted or empty, there are no additional roots for the session.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", "items": { "type": "string" }, @@ -7007,7 +7416,7 @@ } ] }, - "SetProvidersRequest": { + "SetProviderRequest": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider id.", "properties": { "_meta": { @@ -7051,7 +7460,7 @@ "x-method": "providers/set", "x-side": "agent" }, - "SetProvidersResponse": { + "SetProviderResponse": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/set`.", "properties": { "_meta": { diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 9a78b26..3c9206e 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -49,6 +49,7 @@ "ContentBlock5": "EmbeddedResourceContentBlock", "McpServer1": "HttpMcpServer", "McpServer2": "SseMcpServer", + "McpServer3": "AcpMcpServer", "RequestPermissionOutcome1": "DeniedOutcome", "RequestPermissionOutcome2": "AllowedOutcome", "AuthMethod1": "EnvVarAuthMethod", diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 024884a..d46a717 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -8,6 +8,7 @@ from ..interfaces import Agent, Client from ..meta import AGENT_METHODS from ..schema import ( + AcpMcpServer, AudioContentBlock, AuthenticateRequest, AuthenticateResponse, @@ -101,7 +102,7 @@ async def new_session( self, cwd: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> NewSessionResponse: resolved_mcp_servers = mcp_servers or [] @@ -123,7 +124,7 @@ async def load_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> LoadSessionResponse: resolved_mcp_servers = mcp_servers or [] @@ -142,18 +143,12 @@ async def load_session( @param_model(ListSessionsRequest) async def list_sessions( - self, - additional_directories: list[str] | None = None, - cursor: str | None = None, - cwd: str | None = None, - **kwargs: Any, + self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any ) -> ListSessionsResponse: return await request_model_from_dict( self._conn, AGENT_METHODS["session_list"], - ListSessionsRequest( - additional_directories=additional_directories, cursor=cursor, cwd=cwd, field_meta=kwargs or None - ), + ListSessionsRequest(cursor=cursor, cwd=cwd, field_meta=kwargs or None), ListSessionsResponse, ) @@ -228,7 +223,7 @@ async def fork_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ForkSessionResponse: return await request_model( @@ -250,7 +245,7 @@ async def resume_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ResumeSessionResponse: return await request_model( diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 0568731..248db56 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -3,6 +3,7 @@ from typing import Any, Protocol from .schema import ( + AcpMcpServer, AgentMessageChunk, AgentPlanUpdate, AgentThoughtChunk, @@ -160,7 +161,7 @@ async def new_session( self, cwd: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> NewSessionResponse: ... @@ -170,17 +171,13 @@ async def load_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> LoadSessionResponse | None: ... @param_model(ListSessionsRequest) async def list_sessions( - self, - additional_directories: list[str] | None = None, - cursor: str | None = None, - cwd: str | None = None, - **kwargs: Any, + self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any ) -> ListSessionsResponse: ... @param_model(SetSessionModeRequest) @@ -220,7 +217,7 @@ async def fork_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ForkSessionResponse: ... @@ -230,7 +227,7 @@ async def resume_session( cwd: str, session_id: str, additional_directories: list[str] | None = None, - mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, ) -> ResumeSessionResponse: ... diff --git a/src/acp/meta.py b/src/acp/meta.py index ed9a25f..604d98e 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,5 +1,5 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.12.2 +# Schema ref: refs/tags/v0.13.3 AGENT_METHODS = { "authenticate": "authenticate", "document_did_change": "document/didChange", @@ -9,6 +9,7 @@ "document_did_save": "document/didSave", "initialize": "initialize", "logout": "logout", + "mcp_message": "mcp/message", "nes_accept": "nes/accept", "nes_close": "nes/close", "nes_reject": "nes/reject", @@ -19,6 +20,7 @@ "providers_set": "providers/set", "session_cancel": "session/cancel", "session_close": "session/close", + "session_delete": "session/delete", "session_fork": "session/fork", "session_list": "session/list", "session_load": "session/load", @@ -34,6 +36,9 @@ "elicitation_create": "elicitation/create", "fs_read_text_file": "fs/read_text_file", "fs_write_text_file": "fs/write_text_file", + "mcp_connect": "mcp/connect", + "mcp_disconnect": "mcp/disconnect", + "mcp_message": "mcp/message", "session_request_permission": "session/request_permission", "session_update": "session/update", "terminal_create": "terminal/create", diff --git a/src/acp/schema.py b/src/acp/schema.py index 614c7ed..1862a53 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,5 +1,5 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.12.2 +# Schema ref: refs/tags/v0.13.3 from __future__ import annotations @@ -346,6 +346,21 @@ class CreateTerminalResponse(BaseModel): ] +class DeleteSessionResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class Diff(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -370,7 +385,7 @@ class Diff(BaseModel): path: Annotated[str, Field(description="The file path being modified.")] -class DisableProvidersRequest(BaseModel): +class DisableProviderRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -387,7 +402,22 @@ class DisableProvidersRequest(BaseModel): id: Annotated[str, Field(description="Provider id to disable.")] -class DisableProvidersResponse(BaseModel): +class DisableProviderResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class DisconnectMcpResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -621,21 +651,6 @@ class ListSessionsRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Filter sessions by the exact ordered additional workspace roots. Each path must be absolute. - # - # This filter applies only when the field is present and non-empty. When - # omitted or empty, no additional-root filter is applied. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nFilter sessions by the exact ordered additional workspace roots. Each path must be absolute.\n\nThis filter applies only when the field is present and non-empty. When\nomitted or empty, no additional-root filter is applied.", - ), - ] = None # Opaque cursor token from a previous response's nextCursor field for cursor-based pagination cursor: Annotated[ Optional[str], @@ -708,6 +723,17 @@ class McpCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Agent supports [`McpServer::Acp`]. + acp: Annotated[ + Optional[bool], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`]." + ), + ] = False # Agent supports [`McpServer::Http`]. http: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Http`].")] = False # Agent supports [`McpServer::Sse`]. @@ -791,6 +817,74 @@ class McpServerStdio(BaseModel): name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] +class MessageMcpNotification(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The MCP-over-ACP connection this message is sent on. + connection_id: Annotated[ + str, + Field( + alias="connectionId", + description="The MCP-over-ACP connection this message is sent on.", + ), + ] + # The inner MCP method name. + method: Annotated[str, Field(description="The inner MCP method name.")] + # Optional inner MCP params. + # + # If omitted or set to `null`, the inner MCP message has no params. + params: Annotated[ + Optional[Dict[str, Any]], + Field( + description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." + ), + ] = None + + +class MessageMcpRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The MCP-over-ACP connection this message is sent on. + connection_id: Annotated[ + str, + Field( + alias="connectionId", + description="The MCP-over-ACP connection this message is sent on.", + ), + ] + # The inner MCP method name. + method: Annotated[str, Field(description="The inner MCP method name.")] + # Optional inner MCP params. + # + # If omitted or set to `null`, the inner MCP message has no params. + params: Annotated[ + Optional[Dict[str, Any]], + Field( + description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." + ), + ] = None + + class ModelInfo(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1331,6 +1425,21 @@ class SessionConfigBoolean(BaseModel): ] +class SessionDeleteCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + class SessionForkCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1363,14 +1472,16 @@ class SessionInfo(BaseModel): # # This capability is not part of the spec yet, and may be removed or changed at any point. # - # Authoritative ordered additional workspace roots for this session. Each path must be absolute. + # Additional workspace roots reported for this session. Each path must be absolute. # - # When omitted or empty, there are no additional roots for the session. + # When present, this is the complete ordered additional-root list reported + # by the Agent. Omitted and empty values are equivalent: the response + # reports no additional roots. additional_directories: Annotated[ Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthoritative ordered additional workspace roots for this session. Each path must be absolute.\n\nWhen omitted or empty, there are no additional roots for the session.", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", ), ] = None # The working directory for this session. Must be an absolute path. @@ -1479,7 +1590,7 @@ class SessionInfoUpdate(_SessionInfoUpdate): session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] -class SetProvidersRequest(BaseModel): +class SetProviderRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1514,7 +1625,7 @@ class SetProvidersRequest(BaseModel): id: Annotated[str, Field(description="Provider id to configure.")] -class SetProvidersResponse(BaseModel): +class SetProviderResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2295,6 +2406,52 @@ class CompleteElicitationNotification(BaseModel): ] +class ConnectMcpRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ACP MCP server ID that was provided by the component declaring the MCP server. + acp_id: Annotated[ + str, + Field( + alias="acpId", + description="The ACP MCP server ID that was provided by the component declaring the MCP server.", + ), + ] + + +class ConnectMcpResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The unique identifier for this MCP-over-ACP connection. + connection_id: Annotated[ + str, + Field( + alias="connectionId", + description="The unique identifier for this MCP-over-ACP connection.", + ), + ] + + class AudioContentBlock(AudioContent): type: Literal["audio"] @@ -2379,6 +2536,23 @@ class _CurrentModeUpdate(BaseModel): current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] +class DeleteSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The ID of the session to delete. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to delete.")] + + class DidChangeDocumentNotification(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2520,6 +2694,26 @@ class DidSaveDocumentNotification(BaseModel): uri: Annotated[str, Field(description="The URI of the saved document.")] +class DisconnectMcpRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The MCP-over-ACP connection to close. + connection_id: Annotated[ + str, + Field(alias="connectionId", description="The MCP-over-ACP connection to close."), + ] + + class ElicitationCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -2737,6 +2931,33 @@ class SseMcpServer(McpServerSse): type: Literal["sse"] +class McpServerAcp(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Unique identifier for this MCP server, generated by the component providing it. + # + # Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible + # on the same ACP connection. + id: Annotated[ + str, + Field( + description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." + ), + ] + # Human-readable name identifying this MCP server. + name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] + + class MultiSelectPropertySchema(BaseModel): # Default selected values. default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None @@ -3004,50 +3225,6 @@ class NesUserAction(BaseModel): uri: Annotated[str, Field(description="The URI of the file where the action occurred.")] -class NewSessionRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Additional workspace roots for this session. Each path must be absolute. - # - # These expand the session's filesystem scope without changing `cwd`, which - # remains the base for relative paths. When omitted or empty, no - # additional roots are activated for the new session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", - ), - ] = None - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # List of MCP (Model Context Protocol) servers the agent should connect to. - mcp_servers: Annotated[ - List[Union[HttpMcpServer, SseMcpServer, McpServerStdio]], - Field( - alias="mcpServers", - description="List of MCP (Model Context Protocol) servers the agent should connect to.", - ), - ] - - class PermissionOption(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3273,7 +3450,7 @@ class ResourceLink(BaseModel): uri: str -class ResumeSessionRequest(BaseModel): +class SessionCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3290,62 +3467,37 @@ class ResumeSessionRequest(BaseModel): # # This capability is not part of the spec yet, and may be removed or changed at any point. # - # Additional workspace roots to activate for this session. Each path must be absolute. + # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the resumed - # session. + # Agents that also support `session/list` may return + # `SessionInfo.additionalDirectories` to report the complete ordered + # additional-root list associated with a listed session. additional_directories: Annotated[ - Optional[List[str]], + Optional[SessionAdditionalDirectoriesCapabilities], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession.", - ), - ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. - mcp_servers: Annotated[ - Optional[List[Union[HttpMcpServer, SseMcpServer, McpServerStdio]]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", ), ] = None - # The ID of the session to resume. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] - - -class SessionCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + # Whether the agent supports `session/close`. + close: Annotated[ + Optional[SessionCloseCapabilities], + Field(description="Whether the agent supports `session/close`."), ] = None # **UNSTABLE** # # This capability is not part of the spec yet, and may be removed or changed at any point. # - # Whether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`. - additional_directories: Annotated[ - Optional[SessionAdditionalDirectoriesCapabilities], + # Whether the agent supports `session/delete`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports deleting sessions from `session/list`. + delete: Annotated[ + Optional[SessionDeleteCapabilities], Field( - alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests and `session/list`.", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." ), ] = None - # Whether the agent supports `session/close`. - close: Annotated[ - Optional[SessionCloseCapabilities], - Field(description="Whether the agent supports `session/close`."), - ] = None # **UNSTABLE** # # This capability is not part of the spec yet, and may be removed or changed at any point. @@ -3526,17 +3678,17 @@ class AgentErrorMessage(BaseModel): error: Error # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None @@ -3676,6 +3828,7 @@ class ClientNotification(BaseModel): DidFocusDocumentNotification, AcceptNesNotification, RejectNesNotification, + MessageMcpNotification, Any, ] ] = None @@ -3684,17 +3837,17 @@ class ClientNotification(BaseModel): class ClientResponseMessage(BaseModel): # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None # All possible responses that a client can send to an agent. @@ -3713,6 +3866,8 @@ class ClientResponseMessage(BaseModel): ReleaseTerminalResponse, WaitForTerminalExitResponse, KillTerminalResponse, + ConnectMcpResponse, + DisconnectMcpResponse, Union[ AcceptElicitationResponse, DeclineElicitationResponse, @@ -3730,17 +3885,17 @@ class ClientErrorMessage(BaseModel): error: Error # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None @@ -3837,49 +3992,6 @@ class EmbeddedResource(BaseModel): ] -class ForkSessionRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the forked - # session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", - ), - ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. - mcp_servers: Annotated[ - Optional[List[Union[HttpMcpServer, SseMcpServer, McpServerStdio]]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] = None - # The ID of the session to fork. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] - - class InitializeRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3937,47 +4049,8 @@ def _coerce_protocol_version(cls, value: Any) -> int: return 1 -class LoadSessionRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the loaded - # session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession.", - ), - ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. - mcp_servers: Annotated[ - List[Union[HttpMcpServer, SseMcpServer, McpServerStdio]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] - # The ID of the session to load. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] +class AcpMcpServer(McpServerAcp): + type: Literal["acp"] class NesCapabilities(BaseModel): @@ -4074,6 +4147,50 @@ class NesEditSuggestionVariant(NesEditSuggestion): kind: Literal["edit"] +class NewSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots for this session. Each path must be absolute. + # + # These expand the session's filesystem scope without changing `cwd`, which + # remains the base for relative paths. When omitted or empty, no + # additional roots are activated for the new session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + ), + ] = None + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] + # List of MCP (Model Context Protocol) servers the agent should connect to. + mcp_servers: Annotated[ + List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], + Field( + alias="mcpServers", + description="List of MCP (Model Context Protocol) servers the agent should connect to.", + ), + ] + + class Plan(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -4099,6 +4216,50 @@ class Plan(BaseModel): ] +class ResumeSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the resumed + # session. It may differ from any previously used or reported list as long as + # the request `cwd` matches the session's `cwd`. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + ), + ] = None + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], + Field( + alias="mcpServers", + description="List of MCP servers to connect to for this session.", + ), + ] = None + # The ID of the session to resume. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] + + class SessionConfigSelectGroup(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -4206,16 +4367,10 @@ class AgentCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Authentication-related capabilities supported by the agent. auth: Annotated[ Optional[AgentAuthCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication-related capabilities supported by the agent." - ), + Field(description="Authentication-related capabilities supported by the agent."), ] = {} # Whether the agent supports `session/load`. load_session: Annotated[ @@ -4360,6 +4515,49 @@ class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, Elicitatio ] +class ForkSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the forked + # session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + ), + ] = None + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], + Field( + alias="mcpServers", + description="List of MCP servers to connect to for this session.", + ), + ] = None + # The ID of the session to fork. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] + + class InitializeResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -4414,6 +4612,50 @@ class InitializeResponse(BaseModel): ] +class LoadSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the loaded + # session. It may differ from any previously used or reported list as long as + # the request `cwd` matches the session's `cwd`. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + ), + ] = None + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], + Field( + alias="mcpServers", + description="List of MCP servers to connect to for this session.", + ), + ] + # The ID of the session to load. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] + + class PromptRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -4505,17 +4747,17 @@ class AgentThoughtChunk(ContentChunk): class ClientRequest(BaseModel): # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None method: str @@ -4524,12 +4766,13 @@ class ClientRequest(BaseModel): InitializeRequest, AuthenticateRequest, ListProvidersRequest, - SetProvidersRequest, - DisableProvidersRequest, + SetProviderRequest, + DisableProviderRequest, LogoutRequest, NewSessionRequest, LoadSessionRequest, ListSessionsRequest, + DeleteSessionRequest, ForkSessionRequest, ResumeSessionRequest, CloseSessionRequest, @@ -4539,6 +4782,7 @@ class ClientRequest(BaseModel): StartNesRequest, SuggestNesRequest, CloseNesRequest, + MessageMcpRequest, Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], Any, ] @@ -4998,17 +5242,17 @@ class ToolCall(BaseModel): class AgentRequest(BaseModel): # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None method: str @@ -5022,6 +5266,9 @@ class AgentRequest(BaseModel): ReleaseTerminalRequest, WaitForTerminalExitRequest, KillTerminalRequest, + ConnectMcpRequest, + MessageMcpRequest, + DisconnectMcpRequest, Union[CreateFormElicitationRequest, CreateUrlElicitationRequest], Any, ] @@ -5031,17 +5278,17 @@ class AgentRequest(BaseModel): class AgentResponseMessage(BaseModel): # JSON RPC Request Id # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2] + # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] # # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. # - # [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. # - # [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. id: Annotated[ Optional[Union[int, str]], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n[1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n[2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." ), ] = None # All possible responses that an agent can send to a client. @@ -5055,12 +5302,13 @@ class AgentResponseMessage(BaseModel): InitializeResponse, AuthenticateResponse, ListProvidersResponse, - SetProvidersResponse, - DisableProvidersResponse, + SetProviderResponse, + DisableProviderResponse, LogoutResponse, NewSessionResponse, LoadSessionResponse, ListSessionsResponse, + DeleteSessionResponse, ForkSessionResponse, ResumeSessionResponse, CloseSessionResponse, @@ -5129,4 +5377,11 @@ class SessionNotification(BaseModel): class AgentNotification(BaseModel): method: str - params: Optional[Union[SessionNotification, CompleteElicitationNotification, Any]] = None + params: Optional[ + Union[ + SessionNotification, + CompleteElicitationNotification, + MessageMcpNotification, + Any, + ] + ] = None diff --git a/tests/test_rpc.py b/tests/test_rpc.py index be5e06c..528fb87 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -377,12 +377,11 @@ async def load_session( async def list_sessions( self, - additional_directories: list[str] | None = None, cursor: str | None = None, cwd: str | None = None, **kwargs: Any, ) -> ListSessionsResponse: - self.calls["list"] = additional_directories + self.calls["list"] = None return ListSessionsResponse(sessions=[]) async def fork_session( @@ -425,14 +424,14 @@ async def resume_session( await client_side.new_session(cwd="/workspace", additional_directories=directories) await client_side.load_session(cwd="/workspace", session_id="sess", additional_directories=directories) - await client_side.list_sessions(cwd="/workspace", additional_directories=directories) + await client_side.list_sessions(cwd="/workspace") await client_side.fork_session(cwd="/workspace", session_id="sess", additional_directories=directories) await client_side.resume_session(cwd="/workspace", session_id="sess", additional_directories=directories) assert agent.calls == { "new": directories, "load": directories, - "list": directories, + "list": None, "fork": directories, "resume": directories, } diff --git a/uv.lock b/uv.lock index cdc2105..4e813f0 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.10.1" +version = "0.11.0" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 3756c2866f07c86b6376c13dd6b39f566a198bfe Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Wed, 10 Jun 2026 08:53:59 -0700 Subject: [PATCH 33/52] feat: update ACP schema to v0.13.6 (#110) Signed-off-by: Chojan Shang --- docs/quickstart.md | 8 +- examples/agent.py | 3 +- examples/client.py | 6 +- examples/echo_agent.py | 3 +- examples/gemini.py | 8 + schema/VERSION | 2 +- schema/meta.json | 3 +- schema/schema.json | 834 ++++++++++++++++++++++------------- scripts/gen_schema.py | 16 +- scripts/gen_signature.py | 27 +- src/acp/__init__.py | 4 - src/acp/agent/connection.py | 4 + src/acp/agent/router.py | 9 - src/acp/client/connection.py | 14 +- src/acp/interfaces.py | 12 +- src/acp/meta.py | 3 +- src/acp/schema.py | 366 +++++++-------- tests/conftest.py | 2 - tests/test_compatibility.py | 5 - tests/test_rpc.py | 13 - tests/test_unstable.py | 12 - 21 files changed, 749 insertions(+), 605 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 79a5a0e..796c3dc 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -71,7 +71,7 @@ Or, if using `uv`: "args": [ "run", "/abs/path/to/agentclientprotocol/python-sdk/examples/echo_agent.py" - ], + ] } } } @@ -92,7 +92,6 @@ import asyncio import sys from pathlib import Path from typing import Any -from uuid import uuid4 from acp import PROTOCOL_VERSION, spawn_agent_process, text_block from acp.interfaces import Client @@ -116,7 +115,6 @@ async def main() -> None: await conn.prompt( session_id=session.session_id, prompt=[text_block("Hello from spawn!")], - message_id=str(uuid4()), ) asyncio.run(main()) @@ -135,9 +133,9 @@ from acp import Agent, PromptResponse class MyAgent(Agent): - async def prompt(self, prompt, session_id, message_id=None, **kwargs) -> PromptResponse: + async def prompt(self, prompt, session_id, **kwargs) -> PromptResponse: # inspect prompt, stream updates, then finish the turn - return PromptResponse(stop_reason="end_turn", user_message_id=message_id) + return PromptResponse(stop_reason="end_turn") ``` Run it with `run_agent()` inside an async entrypoint and wire it to your client. Refer to: diff --git a/examples/agent.py b/examples/agent.py index 6182580..8d64a9d 100644 --- a/examples/agent.py +++ b/examples/agent.py @@ -103,7 +103,6 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, - message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: logging.info("Received prompt request for session %s", session_id) @@ -113,7 +112,7 @@ async def prompt( await self._send_agent_message(session_id, text_block("Client sent:")) for block in prompt: await self._send_agent_message(session_id, block) - return PromptResponse(stop_reason="end_turn", user_message_id=message_id) + return PromptResponse(stop_reason="end_turn") async def cancel(self, session_id: str, **kwargs: Any) -> None: logging.info("Received cancel notification for session %s", session_id) diff --git a/examples/client.py b/examples/client.py index 138ab7f..c70de70 100644 --- a/examples/client.py +++ b/examples/client.py @@ -6,7 +6,6 @@ import sys from pathlib import Path from typing import Any -from uuid import uuid4 from acp import ( PROTOCOL_VERSION, @@ -18,6 +17,8 @@ from acp.core import ClientSideConnection from acp.schema import ( AgentMessageChunk, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, AgentPlanUpdate, AgentThoughtChunk, AudioContentBlock, @@ -102,6 +103,8 @@ async def session_update( | ToolCallStart | ToolCallProgress | AgentPlanUpdate + | AgentPlanContentUpdate + | AgentPlanRemovedUpdate | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate @@ -158,7 +161,6 @@ async def interactive_loop(conn: ClientSideConnection, session_id: str) -> None: await conn.prompt( session_id=session_id, prompt=[text_block(line)], - message_id=str(uuid4()), ) except Exception as exc: logging.error("Prompt failed: %s", exc) # noqa: TRY400 diff --git a/examples/echo_agent.py b/examples/echo_agent.py index 3eec09c..5218458 100644 --- a/examples/echo_agent.py +++ b/examples/echo_agent.py @@ -66,7 +66,6 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, - message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: for block in prompt: @@ -76,7 +75,7 @@ async def prompt( chunk.content.field_meta = {"echo": True} await self._conn.session_update(session_id=session_id, update=chunk, source="echo_agent") - return PromptResponse(stop_reason="end_turn", user_message_id=message_id) + return PromptResponse(stop_reason="end_turn") async def main() -> None: diff --git a/examples/gemini.py b/examples/gemini.py index 85c862f..71b6b44 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -22,6 +22,8 @@ from acp.core import ClientSideConnection from acp.schema import ( AgentMessageChunk, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, AgentPlanUpdate, AgentThoughtChunk, AllowedOutcome, @@ -124,6 +126,8 @@ async def session_update( # noqa: C901 | ToolCallStart | ToolCallProgress | AgentPlanUpdate + | AgentPlanContentUpdate + | AgentPlanRemovedUpdate | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate @@ -143,6 +147,10 @@ async def session_update( # noqa: C901 print("\n[plan]") for entry in update.entries: print(f" - {entry.status.upper():<10} {entry.content}") + elif isinstance(update, AgentPlanContentUpdate): + print(f"\n[plan update] {update.plan.id}") + elif isinstance(update, AgentPlanRemovedUpdate): + print(f"\n[plan removed] {update.id}") elif isinstance(update, ToolCallStart): print(f"\n🔧 {update.title} ({update.status or 'pending'})") elif isinstance(update, ToolCallProgress): diff --git a/schema/VERSION b/schema/VERSION index 2a50c94..131bb6e 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.13.3 +refs/tags/v0.13.6 diff --git a/schema/meta.json b/schema/meta.json index 5775e36..071a291 100644 --- a/schema/meta.json +++ b/schema/meta.json @@ -27,8 +27,7 @@ "session_prompt": "session/prompt", "session_resume": "session/resume", "session_set_config_option": "session/set_config_option", - "session_set_mode": "session/set_mode", - "session_set_model": "session/set_model" + "session_set_mode": "session/set_mode" }, "clientMethods": { "elicitation_complete": "elicitation/complete", diff --git a/schema/schema.json b/schema/schema.json index 80b2cbf..ca72e85 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -52,7 +52,8 @@ "type": "null" } ], - "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." + "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -104,7 +105,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.", + "x-deserialize-default-on-error": true }, "positionEncoding": { "anyOf": [ @@ -115,7 +117,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", + "x-deserialize-default-on-error": true }, "promptCapabilities": { "allOf": [ @@ -139,7 +142,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "x-deserialize-default-on-error": true }, "sessionCapabilities": { "allOf": [ @@ -494,14 +498,6 @@ ], "title": "PromptResponse" }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionModelResponse" - } - ], - "title": "SetSessionModelResponse" - }, { "allOf": [ { @@ -590,7 +586,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "lastModified": { "type": [ @@ -627,7 +625,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "data": { "type": "string" @@ -940,7 +939,8 @@ "type": "null" } ], - "description": "Input for the command if required" + "description": "Input for the command if required", + "x-deserialize-default-on-error": true }, "name": { "description": "Command name (e.g., `create_plan`, `research_codebase`).", @@ -983,7 +983,9 @@ "items": { "$ref": "#/$defs/AvailableCommand" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -1133,7 +1135,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.", + "x-deserialize-default-on-error": true }, "fs": { "allOf": [ @@ -1156,14 +1159,29 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.", + "x-deserialize-default-on-error": true + }, + "plan": { + "anyOf": [ + { + "$ref": "#/$defs/PlanCapabilities" + }, + { + "type": "null" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types.", + "x-deserialize-default-on-error": true }, "positionEncodings": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", "items": { "$ref": "#/$defs/PositionEncodingKind" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "terminal": { "default": false, @@ -1193,7 +1211,8 @@ "type": "null" } ], - "description": "Whether the client supports the `jump` suggestion kind." + "description": "Whether the client supports the `jump` suggestion kind.", + "x-deserialize-default-on-error": true }, "rename": { "anyOf": [ @@ -1204,7 +1223,8 @@ "type": "null" } ], - "description": "Whether the client supports the `rename` suggestion kind." + "description": "Whether the client supports the `rename` suggestion kind.", + "x-deserialize-default-on-error": true }, "searchAndReplace": { "anyOf": [ @@ -1215,7 +1235,8 @@ "type": "null" } ], - "description": "Whether the client supports the `searchAndReplace` suggestion kind." + "description": "Whether the client supports the `searchAndReplace` suggestion kind.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -1433,7 +1454,7 @@ "$ref": "#/$defs/DeleteSessionRequest" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDeletes an existing session from `session/list`.\n\nThis method is only available if the agent advertises the `sessionCapabilities.delete` capability.", + "description": "Deletes an existing session from `session/list`.\n\nThis method is only available if the agent advertises the `sessionCapabilities.delete` capability.", "title": "DeleteSessionRequest" }, { @@ -1490,15 +1511,6 @@ "description": "Processes a user prompt within a session.\n\nThis method handles the whole lifecycle of a prompt:\n- Receives user messages with optional context (files, images, etc.)\n- Processes the prompt using language models\n- Reports language model content and tool calls to the Clients\n- Requests permission to run tools\n- Executes any requested tool calls\n- Returns when the turn is complete with a stop reason\n\nSee protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)", "title": "PromptRequest" }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionModelRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSelect a model for a given session.", - "title": "SetSessionModelRequest" - }, { "allOf": [ { @@ -1832,7 +1844,9 @@ "items": { "$ref": "#/$defs/SessionConfigOption" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -2037,11 +2051,15 @@ "description": "A single item of content" }, "messageId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.\nBoth clients and agents MUST use UUID format for message IDs.", - "type": [ - "string", - "null" - ] + "anyOf": [ + { + "$ref": "#/$defs/MessageId" + }, + { + "type": "null" + } + ], + "description": "A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started." } }, "required": [ @@ -2050,7 +2068,7 @@ "type": "object" }, "Cost": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCost information for a session.", + "description": "Cost information for a session.", "properties": { "amount": { "description": "Total cumulative cost for session.", @@ -2308,7 +2326,7 @@ "type": "object" }, "DeleteSessionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for deleting an existing session from `session/list`.\n\nOnly available if the Agent supports the `sessionCapabilities.delete` capability.", + "description": "Request parameters for deleting an existing session from `session/list`.\n\nOnly available if the Agent supports the `sessionCapabilities.delete` capability.", "properties": { "_meta": { "additionalProperties": true, @@ -2335,7 +2353,7 @@ "x-side": "agent" }, "DeleteSessionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from deleting a session.", + "description": "Response from deleting a session.", "properties": { "_meta": { "additionalProperties": true, @@ -2715,7 +2733,8 @@ "type": "null" } ], - "description": "Whether the client supports form-based elicitation." + "description": "Whether the client supports form-based elicitation.", + "x-deserialize-default-on-error": true }, "url": { "anyOf": [ @@ -2726,7 +2745,8 @@ "type": "null" } ], - "description": "Whether the client supports URL-based elicitation." + "description": "Whether the client supports URL-based elicitation.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -3101,7 +3121,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "resource": { "$ref": "#/$defs/EmbeddedResourceResource" @@ -3321,7 +3342,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", "items": { "type": "string" }, @@ -3374,18 +3395,9 @@ "type": [ "array", "null" - ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, - { - "type": "null" - } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "modes": { "anyOf": [ @@ -3396,7 +3408,8 @@ "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "x-deserialize-default-on-error": true }, "sessionId": { "allOf": [ @@ -3459,7 +3472,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "data": { "type": "string" @@ -3551,7 +3565,8 @@ "type": "null" } ], - "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required." + "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", + "x-deserialize-default-on-error": true }, "protocolVersion": { "allOf": [ @@ -3612,7 +3627,8 @@ "type": "null" } ], - "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required." + "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", + "x-deserialize-default-on-error": true }, "authMethods": { "default": [], @@ -3620,7 +3636,9 @@ "items": { "$ref": "#/$defs/AuthMethod" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "protocolVersion": { "allOf": [ @@ -3762,7 +3780,9 @@ "items": { "$ref": "#/$defs/ProviderInfo" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -3825,7 +3845,9 @@ "items": { "$ref": "#/$defs/SessionInfo" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -3882,7 +3904,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", "items": { "type": "string" }, @@ -3936,18 +3958,9 @@ "type": [ "array", "null" - ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, - { - "type": "null" - } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "modes": { "anyOf": [ @@ -3958,7 +3971,8 @@ "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "x-deserialize-default-on-error": true } }, "type": "object", @@ -4256,6 +4270,10 @@ ], "type": "object" }, + "MessageId": { + "description": "Unique identifier for a message within a session.", + "type": "string" + }, "MessageMcpNotification": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification parameters for `mcp/message`.\n\nThis is used when the wrapped MCP message is a notification and the outer JSON-RPC\nenvelope has no `id`.", "properties": { @@ -4341,47 +4359,6 @@ "x-method": "mcp/message", "x-side": "both" }, - "ModelId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for a model.", - "type": "string" - }, - "ModelInfo": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a selectable model.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "description": { - "description": "Optional description of the model.", - "type": [ - "string", - "null" - ] - }, - "modelId": { - "allOf": [ - { - "$ref": "#/$defs/ModelId" - } - ], - "description": "Unique identifier for the model." - }, - "name": { - "description": "Human-readable name of the model.", - "type": "string" - } - }, - "required": [ - "modelId", - "name" - ], - "type": "object" - }, "MultiSelectItems": { "anyOf": [ { @@ -4484,7 +4461,8 @@ "type": "null" } ], - "description": "Context the agent wants attached to each suggestion request." + "description": "Context the agent wants attached to each suggestion request.", + "x-deserialize-default-on-error": true }, "events": { "anyOf": [ @@ -4495,7 +4473,8 @@ "type": "null" } ], - "description": "Events the agent wants to receive." + "description": "Events the agent wants to receive.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -4520,7 +4499,8 @@ "type": "null" } ], - "description": "Whether the agent wants diagnostics context." + "description": "Whether the agent wants diagnostics context.", + "x-deserialize-default-on-error": true }, "editHistory": { "anyOf": [ @@ -4531,7 +4511,8 @@ "type": "null" } ], - "description": "Whether the agent wants edit history context." + "description": "Whether the agent wants edit history context.", + "x-deserialize-default-on-error": true }, "openFiles": { "anyOf": [ @@ -4542,7 +4523,8 @@ "type": "null" } ], - "description": "Whether the agent wants open files context." + "description": "Whether the agent wants open files context.", + "x-deserialize-default-on-error": true }, "recentFiles": { "anyOf": [ @@ -4553,7 +4535,8 @@ "type": "null" } ], - "description": "Whether the agent wants recent files context." + "description": "Whether the agent wants recent files context.", + "x-deserialize-default-on-error": true }, "relatedSnippets": { "anyOf": [ @@ -4564,7 +4547,8 @@ "type": "null" } ], - "description": "Whether the agent wants related snippets context." + "description": "Whether the agent wants related snippets context.", + "x-deserialize-default-on-error": true }, "userActions": { "anyOf": [ @@ -4575,7 +4559,8 @@ "type": "null" } ], - "description": "Whether the agent wants user actions context." + "description": "Whether the agent wants user actions context.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -4756,7 +4741,8 @@ "type": "null" } ], - "description": "Whether the agent wants `document/didChange` events, and the sync kind." + "description": "Whether the agent wants `document/didChange` events, and the sync kind.", + "x-deserialize-default-on-error": true }, "didClose": { "anyOf": [ @@ -4767,7 +4753,8 @@ "type": "null" } ], - "description": "Whether the agent wants `document/didClose` events." + "description": "Whether the agent wants `document/didClose` events.", + "x-deserialize-default-on-error": true }, "didFocus": { "anyOf": [ @@ -4778,7 +4765,8 @@ "type": "null" } ], - "description": "Whether the agent wants `document/didFocus` events." + "description": "Whether the agent wants `document/didFocus` events.", + "x-deserialize-default-on-error": true }, "didOpen": { "anyOf": [ @@ -4789,7 +4777,8 @@ "type": "null" } ], - "description": "Whether the agent wants `document/didOpen` events." + "description": "Whether the agent wants `document/didOpen` events.", + "x-deserialize-default-on-error": true }, "didSave": { "anyOf": [ @@ -4800,7 +4789,8 @@ "type": "null" } ], - "description": "Whether the agent wants `document/didSave` events." + "description": "Whether the agent wants `document/didSave` events.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -4858,7 +4848,8 @@ "type": "null" } ], - "description": "Optional suggested cursor position after applying edits." + "description": "Optional suggested cursor position after applying edits.", + "x-deserialize-default-on-error": true }, "edits": { "description": "The text edits to apply.", @@ -4903,7 +4894,8 @@ "type": "null" } ], - "description": "Document event capabilities." + "description": "Document event capabilities.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -4990,7 +4982,8 @@ "type": [ "integer", "null" - ] + ], + "x-deserialize-default-on-error": true }, "uri": { "description": "The URI of the file.", @@ -5005,7 +4998,8 @@ "type": "null" } ], - "description": "The visible range in the editor, if any." + "description": "The visible range in the editor, if any.", + "x-deserialize-default-on-error": true } }, "required": [ @@ -5271,7 +5265,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "editHistory": { "description": "Recent edit history.", @@ -5281,7 +5277,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "openFiles": { "description": "Currently open files in the editor.", @@ -5291,7 +5289,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "recentFiles": { "description": "Recently accessed files.", @@ -5301,7 +5301,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "relatedSnippets": { "description": "Related code snippets.", @@ -5311,7 +5313,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "userActions": { "description": "Recent user actions (typing, navigation, etc.).", @@ -5321,7 +5325,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "type": "object" @@ -5517,7 +5523,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + "description": "Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", "items": { "type": "string" }, @@ -5562,18 +5568,9 @@ "type": [ "array", "null" - ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, - { - "type": "null" - } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "modes": { "anyOf": [ @@ -5584,7 +5581,8 @@ "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "x-deserialize-default-on-error": true }, "sessionId": { "allOf": [ @@ -5730,7 +5728,9 @@ "items": { "$ref": "#/$defs/PlanEntry" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -5738,6 +5738,20 @@ ], "type": "object" }, + "PlanCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for receiving `plan_update` and `plan_removed` session updates.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, "PlanEntry": { "description": "A single entry in the execution plan.\n\nRepresents a task or goal that the assistant intends to accomplish\nas part of fulfilling the user's request.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", "properties": { @@ -5817,6 +5831,217 @@ } ] }, + "PlanFile": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented by a file URI.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ], + "description": "The plan ID to update." + }, + "uri": { + "description": "The URI of the file containing the plan.", + "type": "string" + } + }, + "required": [ + "id", + "uri" + ], + "type": "object" + }, + "PlanId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a plan within a session.", + "type": "string" + }, + "PlanItems": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as structured entries.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "entries": { + "description": "The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update.", + "items": { + "$ref": "#/$defs/PlanEntry" + }, + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ], + "description": "The plan ID to update." + } + }, + "required": [ + "id", + "entries" + ], + "type": "object" + }, + "PlanMarkdown": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as raw markdown content.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "content": { + "description": "Markdown content for the plan.", + "type": "string" + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ], + "description": "The plan ID to update." + } + }, + "required": [ + "id", + "content" + ], + "type": "object" + }, + "PlanRemoved": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "id": { + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ], + "description": "The plan ID to remove." + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "PlanUpdate": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", + "properties": { + "_meta": { + "additionalProperties": true, + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ] + }, + "plan": { + "allOf": [ + { + "$ref": "#/$defs/PlanUpdateContent" + } + ], + "description": "The updated plan content." + } + }, + "required": [ + "plan" + ], + "type": "object" + }, + "PlanUpdateContent": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUpdated content for a plan.", + "discriminator": { + "propertyName": "type" + }, + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/PlanItems" + } + ], + "description": "Structured plan entries.", + "properties": { + "type": { + "const": "items", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/PlanFile" + } + ], + "description": "A URI pointing to a file containing the plan.", + "properties": { + "type": { + "const": "file", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/PlanMarkdown" + } + ], + "description": "Raw markdown content for the plan.", + "properties": { + "type": { + "const": "markdown", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + }, "Position": { "description": "A zero-based position in a text document.\n\nThe meaning of `character` depends on the negotiated position encoding.", "properties": { @@ -5899,13 +6124,6 @@ "null" ] }, - "messageId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", - "type": [ - "string", - "null" - ] - }, "prompt": { "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", "items": { @@ -5958,14 +6176,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." - }, - "userMessageId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", - "type": [ - "string", - "null" - ] + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional).", + "x-deserialize-default-on-error": true } }, "required": [ @@ -6039,7 +6251,9 @@ "items": { "$ref": "#/$defs/LlmProtocol" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -6185,7 +6399,8 @@ "type": "null" } ], - "description": "The reason for rejection." + "description": "The reason for rejection.", + "x-deserialize-default-on-error": true }, "sessionId": { "allOf": [ @@ -6399,7 +6614,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "description": { "type": [ @@ -6451,7 +6667,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", "items": { "type": "string" }, @@ -6504,18 +6720,9 @@ "type": [ "array", "null" - ] - }, - "models": { - "anyOf": [ - { - "$ref": "#/$defs/SessionModelState" - }, - { - "type": "null" - } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "modes": { "anyOf": [ @@ -6526,7 +6733,8 @@ "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "x-deserialize-default-on-error": true } }, "type": "object", @@ -6567,7 +6775,7 @@ "type": "object" }, "SessionAdditionalDirectoriesCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", + "description": "Capabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", "properties": { "_meta": { "additionalProperties": true, @@ -6600,7 +6808,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session." + "description": "Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + "x-deserialize-default-on-error": true }, "close": { "anyOf": [ @@ -6611,7 +6820,8 @@ "type": "null" } ], - "description": "Whether the agent supports `session/close`." + "description": "Whether the agent supports `session/close`.", + "x-deserialize-default-on-error": true }, "delete": { "anyOf": [ @@ -6622,7 +6832,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." + "description": "Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", + "x-deserialize-default-on-error": true }, "fork": { "anyOf": [ @@ -6633,7 +6844,8 @@ "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.", + "x-deserialize-default-on-error": true }, "list": { "anyOf": [ @@ -6644,7 +6856,8 @@ "type": "null" } ], - "description": "Whether the agent supports `session/list`." + "description": "Whether the agent supports `session/list`.", + "x-deserialize-default-on-error": true }, "resume": { "anyOf": [ @@ -6655,7 +6868,8 @@ "type": "null" } ], - "description": "Whether the agent supports `session/resume`." + "description": "Whether the agent supports `session/resume`.", + "x-deserialize-default-on-error": true } }, "type": "object" @@ -6756,7 +6970,8 @@ "type": "null" } ], - "description": "Optional semantic category for this option (UX only)." + "description": "Optional semantic category for this option (UX only).", + "x-deserialize-default-on-error": true }, "description": { "description": "Optional description for the Client to display to the user.", @@ -6936,7 +7151,7 @@ "type": "string" }, "SessionDeleteCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/delete` method.\n\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", + "description": "Capabilities for the `session/delete` method.\n\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", "properties": { "_meta": { "additionalProperties": true, @@ -6979,7 +7194,7 @@ ] }, "additionalDirectories": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", + "description": "Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", "items": { "type": "string" }, @@ -7002,14 +7217,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "updatedAt": { "description": "ISO 8601 timestamp of last activity", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true } }, "required": [ @@ -7110,7 +7327,9 @@ "items": { "$ref": "#/$defs/SessionMode" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "currentModeId": { "allOf": [ @@ -7127,39 +7346,6 @@ ], "type": "object" }, - "SessionModelState": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe set of models and the one currently active.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "availableModels": { - "description": "The set of models that the Agent can use", - "items": { - "$ref": "#/$defs/ModelInfo" - }, - "type": "array" - }, - "currentModelId": { - "allOf": [ - { - "$ref": "#/$defs/ModelId" - } - ], - "description": "The current model the Agent is in." - } - }, - "required": [ - "currentModelId", - "availableModels" - ], - "type": "object" - }, "SessionNotification": { "description": "Notification containing a session update from the agent.\n\nUsed to stream real-time progress and results during prompt processing.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", "properties": { @@ -7324,6 +7510,42 @@ ], "type": "object" }, + { + "allOf": [ + { + "$ref": "#/$defs/PlanUpdate" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", + "properties": { + "sessionUpdate": { + "const": "plan_update", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, + { + "allOf": [ + { + "$ref": "#/$defs/PlanRemoved" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", + "properties": { + "sessionUpdate": { + "const": "plan_removed", + "type": "string" + } + }, + "required": [ + "sessionUpdate" + ], + "type": "object" + }, { "allOf": [ { @@ -7402,7 +7624,7 @@ "$ref": "#/$defs/UsageUpdate" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for the session.", + "description": "Context window and cost update for the session.", "properties": { "sessionUpdate": { "const": "usage_update", @@ -7566,7 +7788,9 @@ "items": { "$ref": "#/$defs/SessionConfigOption" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -7628,58 +7852,6 @@ "x-method": "session/set_mode", "x-side": "agent" }, - "SetSessionModelRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for setting a session model.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "modelId": { - "allOf": [ - { - "$ref": "#/$defs/ModelId" - } - ], - "description": "The ID of the model to set." - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The ID of the session to set the model for." - } - }, - "required": [ - "sessionId", - "modelId" - ], - "type": "object", - "x-method": "session/set_model", - "x-side": "agent" - }, - "SetSessionModelResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `session/set_model` method.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - } - }, - "type": "object", - "x-method": "session/set_model", - "x-side": "agent" - }, "StartNesRequest": { "description": "Request to start an NES session.", "properties": { @@ -7700,7 +7872,8 @@ "type": "null" } ], - "description": "Repository metadata, if the workspace is a git repository." + "description": "Repository metadata, if the workspace is a git repository.", + "x-deserialize-default-on-error": true }, "workspaceFolders": { "description": "The workspace folders.", @@ -7710,7 +7883,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "workspaceUri": { "description": "The root URI of the workspace.", @@ -7909,7 +8084,8 @@ "type": "null" } ], - "description": "Context for the suggestion, included based on agent capabilities." + "description": "Context for the suggestion, included based on agent capabilities.", + "x-deserialize-default-on-error": true }, "position": { "allOf": [ @@ -7928,7 +8104,8 @@ "type": "null" } ], - "description": "The current text selection range, if any." + "description": "The current text selection range, if any.", + "x-deserialize-default-on-error": true }, "sessionId": { "allOf": [ @@ -7983,7 +8160,9 @@ "items": { "$ref": "#/$defs/NesSuggestion" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true } }, "required": [ @@ -8133,7 +8312,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "text": { "type": "string" @@ -8245,7 +8425,9 @@ "items": { "$ref": "#/$defs/ToolCallContent" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "kind": { "allOf": [ @@ -8260,7 +8442,9 @@ "items": { "$ref": "#/$defs/ToolCallLocation" }, - "type": "array" + "type": "array", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "rawInput": { "description": "Raw input parameters sent to the tool." @@ -8435,7 +8619,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "kind": { "anyOf": [ @@ -8446,7 +8632,8 @@ "type": "null" } ], - "description": "Update the tool kind." + "description": "Update the tool kind.", + "x-deserialize-default-on-error": true }, "locations": { "description": "Replace the locations collection.", @@ -8456,7 +8643,9 @@ "type": [ "array", "null" - ] + ], + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "rawInput": { "description": "Update the raw input." @@ -8473,7 +8662,8 @@ "type": "null" } ], - "description": "Update the execution status." + "description": "Update the execution status.", + "x-deserialize-default-on-error": true }, "title": { "description": "Update the human-readable title.", @@ -8654,7 +8844,7 @@ "type": "object" }, "UsageUpdate": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nContext window and cost update for a session.", + "description": "Context window and cost update for a session.", "properties": { "_meta": { "additionalProperties": true, @@ -8673,7 +8863,8 @@ "type": "null" } ], - "description": "Cumulative session cost (optional)." + "description": "Cumulative session cost (optional).", + "x-deserialize-default-on-error": true }, "size": { "description": "Total context window size in tokens.", @@ -8917,19 +9108,46 @@ "type": "object" }, { - "anyOf": [ - { - "allOf": [ + "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", + "properties": { + "jsonrpc": { + "enum": [ + "2.0" + ], + "type": "string" + }, + "method": { + "type": "string" + }, + "params": { + "anyOf": [ { - "$ref": "#/$defs/CancelRequestNotification" + "anyOf": [ + { + "allOf": [ + { + "$ref": "#/$defs/CancelRequestNotification" + } + ], + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "title": "CancelRequestNotification" + } + ], + "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response." + }, + { + "type": "null" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", - "title": "CancelRequestNotification" + ] } + }, + "required": [ + "jsonrpc", + "method" ], - "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response.", - "title": "ProtocolLevel" + "title": "ProtocolLevel", + "type": "object", + "x-docs-ignore": true } ], "title": "Agent Client Protocol" diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 3c9206e..ce26db4 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -33,6 +33,7 @@ "AgentClientProtocol4", "AgentClientProtocol5", "AgentClientProtocol6", + "AgentClientProtocol7", ] # Map of numbered classes produced by datamodel-code-generator to descriptive names. @@ -64,11 +65,16 @@ "SessionUpdate4": "ToolCallStart", "SessionUpdate5": "ToolCallProgress", "SessionUpdate6": "AgentPlanUpdate", - "SessionUpdate7": "AvailableCommandsUpdate", - "SessionUpdate8": "CurrentModeUpdate", - "SessionUpdate9": "ConfigOptionUpdate", - "SessionUpdate10": "SessionInfoUpdate", - "SessionUpdate11": "UsageUpdate", + "SessionUpdate7": "AgentPlanContentUpdate", + "SessionUpdate8": "AgentPlanRemovedUpdate", + "SessionUpdate9": "AvailableCommandsUpdate", + "SessionUpdate10": "CurrentModeUpdate", + "SessionUpdate11": "ConfigOptionUpdate", + "SessionUpdate12": "SessionInfoUpdate", + "SessionUpdate13": "UsageUpdate", + "PlanUpdateContent1": "PlanUpdateItems", + "PlanUpdateContent2": "PlanUpdateFile", + "PlanUpdateContent3": "PlanUpdateMarkdown", "ToolCallContent1": "ContentToolCallContent", "ToolCallContent2": "FileEditToolCallContent", "ToolCallContent3": "TerminalToolCallContent", diff --git a/scripts/gen_signature.py b/scripts/gen_signature.py index b435e2c..412071b 100644 --- a/scripts/gen_signature.py +++ b/scripts/gen_signature.py @@ -1,5 +1,7 @@ import ast +import importlib.util import inspect +import sys import typing as t from pathlib import Path @@ -7,7 +9,21 @@ from pydantic.fields import FieldInfo from pydantic_core import PydanticUndefined -from acp import schema +ROOT = Path(__file__).resolve().parents[1] +SCHEMA_MODULE_PATH = ROOT / "src" / "acp" / "schema.py" + + +def _load_schema_module() -> t.Any: + spec = importlib.util.spec_from_file_location("acp_schema_for_signature", SCHEMA_MODULE_PATH) + if spec is None or spec.loader is None: + raise RuntimeError(f"Unable to load schema module from {SCHEMA_MODULE_PATH}") + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + +schema = _load_schema_module() SIGNATURE_OPTIONAL_FIELDS: set[tuple[str, str]] = { ("LoadSessionRequest", "mcp_servers"), @@ -116,7 +132,9 @@ def _format_annotation(self, annotation: t.Any) -> ast.expr: self._add_schema_import(name) return ast.Name(id=name) elif ( - inspect.isclass(annotation) and issubclass(annotation, BaseModel) and annotation.__module__ == "acp.schema" + inspect.isclass(annotation) + and issubclass(annotation, BaseModel) + and annotation.__module__ == schema.__name__ ): self._add_schema_import(annotation.__name__) return ast.Name(id=annotation.__name__) @@ -144,9 +162,8 @@ def _format_annotation(self, annotation: t.Any) -> ast.expr: def gen_signature(source_dir: Path) -> None: - import importlib - - importlib.reload(schema) # Ensure schema is up to date + global schema + schema = _load_schema_module() for source_file in source_dir.rglob("*.py"): transformer = NodeTransformer() transformer.transform(source_file) diff --git a/src/acp/__init__.py b/src/acp/__init__.py index c49b187..87afc16 100644 --- a/src/acp/__init__.py +++ b/src/acp/__init__.py @@ -62,8 +62,6 @@ SessionNotification, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, - SetSessionModelRequest, - SetSessionModelResponse, SetSessionModeRequest, SetSessionModeResponse, TerminalOutputRequest, @@ -115,8 +113,6 @@ "SessionNotification", "SetSessionModeRequest", "SetSessionModeResponse", - "SetSessionModelRequest", - "SetSessionModelResponse", "SetSessionConfigOptionSelectRequest", "SetSessionConfigOptionResponse", # terminal types diff --git a/src/acp/agent/connection.py b/src/acp/agent/connection.py index 64c96d9..f775900 100644 --- a/src/acp/agent/connection.py +++ b/src/acp/agent/connection.py @@ -9,6 +9,8 @@ from ..meta import CLIENT_METHODS from ..schema import ( AgentMessageChunk, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, AgentPlanUpdate, AgentThoughtChunk, AvailableCommandsUpdate, @@ -86,6 +88,8 @@ async def session_update( | ToolCallStart | ToolCallProgress | AgentPlanUpdate + | AgentPlanContentUpdate + | AgentPlanRemovedUpdate | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate diff --git a/src/acp/agent/router.py b/src/acp/agent/router.py index 2a27bcd..7dd58a5 100644 --- a/src/acp/agent/router.py +++ b/src/acp/agent/router.py @@ -21,7 +21,6 @@ ResumeSessionRequest, SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest, - SetSessionModelRequest, SetSessionModeRequest, ) from ..utils import model_to_kwargs, normalize_result @@ -83,14 +82,6 @@ def build_agent_router(agent: Agent, use_unstable_protocol: bool = False) -> Mes adapt_result=normalize_result, ) router.route_request(AGENT_METHODS["session_prompt"], PromptRequest, agent, "prompt") - router.route_request( - AGENT_METHODS["session_set_model"], - SetSessionModelRequest, - agent, - "set_session_model", - adapt_result=normalize_result, - unstable=True, - ) router.add_route( Route( method=AGENT_METHODS["session_set_config_option"], diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index d46a717..7e50a88 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -39,8 +39,6 @@ SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, - SetSessionModelRequest, - SetSessionModelResponse, SetSessionModeRequest, SetSessionModeResponse, SseMcpServer, @@ -161,15 +159,6 @@ async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) - SetSessionModeResponse, ) - @param_model(SetSessionModelRequest) - async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) -> SetSessionModelResponse: - return await request_model_from_dict( - self._conn, - AGENT_METHODS["session_set_model"], - SetSessionModelRequest(model_id=model_id, session_id=session_id, field_meta=kwargs or None), - SetSessionModelResponse, - ) - @param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) async def set_config_option( self, config_id: str, session_id: str, value: str | bool, **kwargs: Any @@ -207,13 +196,12 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, - message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: return await request_model( self._conn, AGENT_METHODS["session_prompt"], - PromptRequest(prompt=prompt, session_id=session_id, message_id=message_id, field_meta=kwargs or None), + PromptRequest(prompt=prompt, session_id=session_id, field_meta=kwargs or None), PromptResponse, ) diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 248db56..245cedc 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -5,6 +5,8 @@ from .schema import ( AcpMcpServer, AgentMessageChunk, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, AgentPlanUpdate, AgentThoughtChunk, AudioContentBlock, @@ -54,8 +56,6 @@ SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, - SetSessionModelRequest, - SetSessionModelResponse, SetSessionModeRequest, SetSessionModeResponse, SseMcpServer, @@ -93,6 +93,8 @@ async def session_update( | ToolCallStart | ToolCallProgress | AgentPlanUpdate + | AgentPlanContentUpdate + | AgentPlanRemovedUpdate | AvailableCommandsUpdate | CurrentModeUpdate | ConfigOptionUpdate @@ -183,11 +185,6 @@ async def list_sessions( @param_model(SetSessionModeRequest) async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: ... - @param_model(SetSessionModelRequest) - async def set_session_model( - self, model_id: str, session_id: str, **kwargs: Any - ) -> SetSessionModelResponse | None: ... - @param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) async def set_config_option( self, config_id: str, session_id: str, value: str | bool, **kwargs: Any @@ -207,7 +204,6 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, - message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: ... diff --git a/src/acp/meta.py b/src/acp/meta.py index 604d98e..c82dcb8 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,5 +1,5 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.13.3 +# Schema ref: refs/tags/v0.13.6 AGENT_METHODS = { "authenticate": "authenticate", "document_did_change": "document/didChange", @@ -29,7 +29,6 @@ "session_resume": "session/resume", "session_set_config_option": "session/set_config_option", "session_set_mode": "session/set_mode", - "session_set_model": "session/set_model", } CLIENT_METHODS = { "elicitation_complete": "elicitation/complete", diff --git a/src/acp/schema.py b/src/acp/schema.py index 1862a53..644e1d4 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,5 +1,5 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.13.3 +# Schema ref: refs/tags/v0.13.6 from __future__ import annotations @@ -885,27 +885,6 @@ class MessageMcpRequest(BaseModel): ] = None -class ModelInfo(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # Optional description of the model. - description: Annotated[Optional[str], Field(description="Optional description of the model.")] = None - # Unique identifier for the model. - model_id: Annotated[str, Field(alias="modelId", description="Unique identifier for the model.")] - # Human-readable name of the model. - name: Annotated[str, Field(description="Human-readable name of the model.")] - - class NesDiagnosticsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -1219,6 +1198,61 @@ class NumberPropertySchema(BaseModel): title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None +class PlanCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class PlanMarkdown(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Markdown content for the plan. + content: Annotated[str, Field(description="Markdown content for the plan.")] + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + + +class PlanRemoved(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The plan ID to remove. + id: Annotated[str, Field(description="The plan ID to remove.")] + + +class PlanUpdateMarkdown(PlanMarkdown): + type: Literal["markdown"] + + class Position(BaseModel): # Zero-based character offset (encoding-dependent). character: Annotated[ @@ -1468,10 +1502,6 @@ class SessionInfo(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Additional workspace roots reported for this session. Each path must be absolute. # # When present, this is the complete ordered additional-root list reported @@ -1481,7 +1511,7 @@ class SessionInfo(BaseModel): Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", + description="Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", ), ] = None # The working directory for this session. Must be an absolute path. @@ -1543,7 +1573,7 @@ class SessionListCapabilities(BaseModel): ] = None -class SessionModelState(BaseModel): +class SessionResumeCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1556,34 +1586,10 @@ class SessionModelState(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The set of models that the Agent can use - available_models: Annotated[ - List[ModelInfo], - Field( - alias="availableModels", - description="The set of models that the Agent can use", - ), - ] - # The current model the Agent is in. - current_model_id: Annotated[ - str, - Field(alias="currentModelId", description="The current model the Agent is in."), - ] -class SessionResumeCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None +class AgentPlanRemovedUpdate(PlanRemoved): + session_update: Annotated[Literal["plan_removed"], Field(alias="sessionUpdate")] class SessionInfoUpdate(_SessionInfoUpdate): @@ -1738,43 +1744,6 @@ class SetSessionModeResponse(BaseModel): ] = None -class SetSessionModelRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # The ID of the model to set. - model_id: Annotated[str, Field(alias="modelId", description="The ID of the model to set.")] - # The ID of the session to set the model for. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The ID of the session to set the model for."), - ] - - -class SetSessionModelResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - - class StartNesResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3282,6 +3251,60 @@ class PlanEntry(BaseModel): status: Annotated[PlanEntryStatus, Field(description="Current execution status of this task.")] +class PlanFile(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + # The URI of the file containing the plan. + uri: Annotated[str, Field(description="The URI of the file containing the plan.")] + + +class PlanItems(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # The list of tasks to be accomplished. + # + # When updating an item-based plan, the agent must send a complete list of all entries + # with their current status. The client replaces that plan with each update. + entries: Annotated[ + List[PlanEntry], + Field( + description="The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update." + ), + ] + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + + +class PlanUpdateItems(PlanItems): + type: Literal["items"] + + +class PlanUpdateFile(PlanFile): + type: Literal["file"] + + class PromptResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3314,22 +3337,6 @@ class PromptResponse(BaseModel): description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # The acknowledged user message ID. - # - # If the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here - # to confirm it was recorded. If the client did not provide one, the agent MAY assign one - # and return it here. Absence of this field indicates the agent did not record a message ID. - user_message_id: Annotated[ - Optional[str], - Field( - alias="userMessageId", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe acknowledged user message ID.\n\nIf the client provided a `messageId` in the [`PromptRequest`], the agent echoes it here\nto confirm it was recorded. If the client did not provide one, the agent MAY assign one\nand return it here. Absence of this field indicates the agent did not record a message ID.", - ), - ] = None class ReadTextFileRequest(BaseModel): @@ -3463,10 +3470,6 @@ class SessionCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. # # Agents that also support `session/list` may return @@ -3476,7 +3479,7 @@ class SessionCapabilities(BaseModel): Optional[SessionAdditionalDirectoriesCapabilities], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", ), ] = None # Whether the agent supports `session/close`. @@ -3484,10 +3487,6 @@ class SessionCapabilities(BaseModel): Optional[SessionCloseCapabilities], Field(description="Whether the agent supports `session/close`."), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Whether the agent supports `session/delete`. # # Optional. Omitted or `null` both mean the agent does not advertise support. @@ -3495,7 +3494,7 @@ class SessionCapabilities(BaseModel): delete: Annotated[ Optional[SessionDeleteCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." + description="Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." ), ] = None # **UNSTABLE** @@ -3801,6 +3800,20 @@ class ClientCapabilities(BaseModel): # # This capability is not part of the spec yet, and may be removed or changed at any point. # + # Whether the client supports `plan_update` and `plan_removed` session updates. + # + # Optional. Omitted means the client does not advertise support. + # Supplying `{}` means the client can receive both update types. + plan: Annotated[ + Optional[PlanCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # # The position encodings supported by the client, in order of preference. position_encodings: Annotated[ Optional[List[str]], @@ -4160,10 +4173,6 @@ class NewSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Additional workspace roots for this session. Each path must be absolute. # # These expand the session's filesystem scope without changing `cwd`, which @@ -4173,7 +4182,7 @@ class NewSessionRequest(BaseModel): Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + description="Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", ), ] = None # The working directory for this session. Must be an absolute path. @@ -4216,7 +4225,7 @@ class Plan(BaseModel): ] -class ResumeSessionRequest(BaseModel): +class PlanUpdate(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4229,10 +4238,26 @@ class ResumeSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + # The updated plan content. + plan: Annotated[ + Union[PlanUpdateItems, PlanUpdateFile, PlanUpdateMarkdown], + Field(description="The updated plan content.", discriminator="type"), + ] + + +class ResumeSessionRequest(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -4243,7 +4268,7 @@ class ResumeSessionRequest(BaseModel): Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", ), ] = None # The working directory for this session. @@ -4288,6 +4313,10 @@ class AgentPlanUpdate(Plan): session_update: Annotated[Literal["plan"], Field(alias="sessionUpdate")] +class AgentPlanContentUpdate(PlanUpdate): + session_update: Annotated[Literal["plan_update"], Field(alias="sessionUpdate")] + + class AvailableCommandsUpdate(_AvailableCommandsUpdate): session_update: Annotated[Literal["available_commands_update"], Field(alias="sessionUpdate")] @@ -4461,20 +4490,15 @@ class ContentChunk(BaseModel): ], Field(description="A single item of content", discriminator="type"), ] - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # A unique identifier for the message this chunk belongs to. # # All chunks belonging to the same message share the same `messageId`. # A change in `messageId` indicates a new message has started. - # Both clients and agents MUST use UUID format for message IDs. message_id: Annotated[ Optional[str], Field( alias="messageId", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.\nBoth clients and agents MUST use UUID format for message IDs.", + description="A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.", ), ] = None @@ -4528,10 +4552,6 @@ class ForkSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -4541,7 +4561,7 @@ class ForkSessionRequest(BaseModel): Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", ), ] = None # The working directory for this session. @@ -4625,10 +4645,6 @@ class LoadSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -4639,7 +4655,7 @@ class LoadSessionRequest(BaseModel): Optional[List[str]], Field( alias="additionalDirectories", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAdditional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", ), ] = None # The working directory for this session. @@ -4669,22 +4685,6 @@ class PromptRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # A client-generated unique identifier for this user message. - # - # If provided, the Agent SHOULD echo this value as `userMessageId` in the - # [`PromptResponse`] to confirm it was recorded. - # Both clients and agents MUST use UUID format for message IDs. - message_id: Annotated[ - Optional[str], - Field( - alias="messageId", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA client-generated unique identifier for this user message.\n\nIf provided, the Agent SHOULD echo this value as `userMessageId` in the\n[`PromptResponse`] to confirm it was recorded.\nBoth clients and agents MUST use UUID format for message IDs.", - ), - ] = None # The blocks of content that compose the user's message. # # As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], @@ -4778,7 +4778,6 @@ class ClientRequest(BaseModel): CloseSessionRequest, SetSessionModeRequest, PromptRequest, - SetSessionModelRequest, StartNesRequest, SuggestNesRequest, CloseNesRequest, @@ -4973,17 +4972,6 @@ class ForkSessionResponse(BaseModel): description="Initial session configuration options if supported by the Agent.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Initial model state if supported by the Agent - models: Annotated[ - Optional[SessionModelState], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" - ), - ] = None # Initial mode state if supported by the Agent # # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) @@ -5024,17 +5012,6 @@ class LoadSessionResponse(BaseModel): description="Initial session configuration options if supported by the Agent.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Initial model state if supported by the Agent - models: Annotated[ - Optional[SessionModelState], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" - ), - ] = None # Initial mode state if supported by the Agent # # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) @@ -5067,17 +5044,6 @@ class NewSessionResponse(BaseModel): description="Initial session configuration options if supported by the Agent.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Initial model state if supported by the Agent - models: Annotated[ - Optional[SessionModelState], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" - ), - ] = None # Initial mode state if supported by the Agent # # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) @@ -5150,17 +5116,6 @@ class ResumeSessionResponse(BaseModel): description="Initial session configuration options if supported by the Agent.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Initial model state if supported by the Agent - models: Annotated[ - Optional[SessionModelState], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInitial model state if supported by the Agent" - ), - ] = None # Initial mode state if supported by the Agent # # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) @@ -5315,7 +5270,6 @@ class AgentResponseMessage(BaseModel): SetSessionModeResponse, SetSessionConfigOptionResponse, PromptResponse, - SetSessionModelResponse, StartNesResponse, SuggestNesResponse, CloseNesResponse, @@ -5365,6 +5319,8 @@ class SessionNotification(BaseModel): ToolCallStart, ToolCallProgress, AgentPlanUpdate, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, AvailableCommandsUpdate, CurrentModeUpdate, ConfigOptionUpdate, diff --git a/tests/conftest.py b/tests/conftest.py index f154167..b4990c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -268,14 +268,12 @@ async def prompt( | EmbeddedResourceContentBlock ], session_id: str, - message_id: str | None = None, **kwargs: Any, ) -> PromptResponse: self.prompts.append( PromptRequest( prompt=prompt, session_id=session_id, - message_id=message_id, field_meta=kwargs or None, ) ) diff --git a/tests/test_compatibility.py b/tests/test_compatibility.py index cdca9ad..effc088 100644 --- a/tests/test_compatibility.py +++ b/tests/test_compatibility.py @@ -12,7 +12,6 @@ RequestPermissionResponse, SessionNotification, SetSessionConfigOptionResponse, - SetSessionModelResponse, SetSessionModeResponse, WriteTextFileResponse, ) @@ -28,7 +27,6 @@ RequestPermissionRequest, SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest, - SetSessionModelRequest, SetSessionModeRequest, WriteTextFileRequest, ) @@ -67,9 +65,6 @@ async def cancel(self, params: CancelNotification) -> None: async def setSessionMode(self, params: SetSessionModeRequest) -> SetSessionModeResponse | None: return SetSessionModeResponse() - async def setSessionModel(self, params: SetSessionModelRequest) -> SetSessionModelResponse | None: - return SetSessionModelResponse() - async def setConfigOption( self, params: SetSessionConfigOptionBooleanRequest | SetSessionConfigOptionSelectRequest ) -> SetSessionConfigOptionResponse | None: diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 528fb87..6720076 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -323,19 +323,6 @@ async def test_set_config_option_boolean(connect, agent, client): assert agent.config_option_calls == [("brave_mode", "sess", True)] -@pytest.mark.asyncio -async def test_prompt_message_id_roundtrip(connect, agent, client): - _, agent_conn = connect() - - resp = await agent_conn.prompt( - session_id="sess", - prompt=[TextContentBlock(type="text", text="hello")], - message_id="123e4567-e89b-12d3-a456-426614174000", - ) - assert isinstance(resp, PromptResponse) - assert agent.prompts[-1].message_id == "123e4567-e89b-12d3-a456-426614174000" - - @pytest.mark.asyncio async def test_list_sessions_stable(connect, agent, client): _, agent_conn = connect() diff --git a/tests/test_unstable.py b/tests/test_unstable.py index 0a25e47..7f519fc 100644 --- a/tests/test_unstable.py +++ b/tests/test_unstable.py @@ -10,7 +10,6 @@ ListSessionsResponse, McpServerStdio, ResumeSessionResponse, - SetSessionModelResponse, SseMcpServer, ) from tests.conftest import TestAgent @@ -23,9 +22,6 @@ async def list_sessions(self, cursor: str | None = None, cwd: str | None = None, async def close_session(self, session_id: str, **kwargs) -> CloseSessionResponse | None: return CloseSessionResponse() - async def set_session_model(self, model_id: str, session_id: str, **kwargs: Any) -> SetSessionModelResponse | None: - return SetSessionModelResponse() - async def fork_session( self, cwd: str, @@ -53,9 +49,6 @@ async def test_call_unstable_protocol(connect): resp = await agent_conn.list_sessions() assert isinstance(resp, ListSessionsResponse) - resp = await agent_conn.set_session_model(session_id="sess", model_id="gpt-4o-mini") - assert isinstance(resp, SetSessionModelResponse) - resp = await agent_conn.fork_session(cwd="/workspace", session_id="sess") assert isinstance(resp, ForkSessionResponse) @@ -71,11 +64,6 @@ async def test_call_unstable_protocol(connect): async def test_call_unstable_protocol_warning(connect): _, agent_conn = connect(use_unstable_protocol=False) - with pytest.warns(UserWarning) as record: - with pytest.raises(RequestError): - await agent_conn.set_session_model(session_id="sess", model_id="gpt-4o-mini") - assert len(record) == 1 - with pytest.warns(UserWarning) as record: with pytest.raises(RequestError): await agent_conn.close_session(session_id="sess") From 6bcf11ad6e4d4a8281d9bda0bfc2b5c7e74edd2b Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Tue, 30 Jun 2026 01:07:04 +0800 Subject: [PATCH 34/52] fix: recover from oversized JSON-RPC frames (#111) * fix: recover from oversized JSON-RPC frames * fix: read oversized frames in chunks --- src/acp/connection.py | 20 ++++- tests/real_user/test_stdio_limits.py | 78 ++++++++++------- tests/test_connection_recovery.py | 123 +++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 31 deletions(-) create mode 100644 tests/test_connection_recovery.py diff --git a/src/acp/connection.py b/src/acp/connection.py index ff1cb19..09e5a0e 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -153,7 +153,7 @@ async def send_notification(self, method: str, params: JsonValue | None = None) async def _receive_loop(self) -> None: try: while True: - line = await asyncio.wait_for(self._reader.readline(), timeout=self._receive_timeout) + line = await self._read_line() if not line: break line = line.strip() @@ -172,6 +172,24 @@ async def _receive_loop(self) -> None: raise RequestError.internal_error({"details": "Agent timeout"}) from None self._disconnect() + async def _read_line(self) -> bytes: + chunks: list[bytes] = [] + try: + while True: + try: + line = await self._wait_for_reader(self._reader.readuntil(b"\n")) + except asyncio.LimitOverrunError as exc: + chunks.append(await self._wait_for_reader(self._reader.readexactly(exc.consumed))) + else: + chunks.append(line) + return b"".join(chunks) + except asyncio.IncompleteReadError as exc: + chunks.append(exc.partial) + return b"".join(chunks) + + async def _wait_for_reader(self, awaitable: Awaitable[bytes]) -> bytes: + return await asyncio.wait_for(awaitable, timeout=self._receive_timeout) + async def _process_message(self, message: dict[str, Any]) -> None: method = message.get("method") has_id = "id" in message diff --git a/tests/real_user/test_stdio_limits.py b/tests/real_user/test_stdio_limits.py index f972a8f..88c2095 100644 --- a/tests/real_user/test_stdio_limits.py +++ b/tests/real_user/test_stdio_limits.py @@ -48,46 +48,62 @@ async def test_spawn_stdio_transport_custom_limit_handles_large_line() -> None: async def test_run_agent_stdio_buffer_limit() -> None: """Test that run_agent with different buffer limits can handle appropriately sized messages.""" with tempfile.TemporaryDirectory() as tmpdir: - # Test 1: Small buffer (1KB) fails with large message (70KB) + # Test 1: Small buffer (1KB) reads a large message (70KB) in chunks small_agent = os.path.join(tmpdir, "small_agent.py") with open(small_agent, "w") as f: - f.write(""" -import asyncio -from acp.core import run_agent -from acp.interfaces import Agent - -class TestAgent(Agent): - async def list_capabilities(self): - return {"capabilities": {}} - -asyncio.run(run_agent(TestAgent(), stdio_buffer_limit_bytes=1024)) -""") - - # Send a 70KB message - should fail with 1KB buffer - large_msg = '{"jsonrpc":"2.0","method":"test","params":{"data":"' + "X" * LARGE_LINE_SIZE + '"}}\n' + f.write( + textwrap.dedent( + """ + import asyncio + from acp.core import run_agent + from acp.interfaces import Agent + from acp.schema import InitializeResponse + + class TestAgent(Agent): + async def initialize(self, protocol_version, client_capabilities=None, client_info=None, **kwargs): + return InitializeResponse(protocol_version=protocol_version) + + asyncio.run(run_agent(TestAgent(), stdio_buffer_limit_bytes=1024)) + """ + ).strip() + ) + + # Send a 70KB message - should be read in chunks despite the 1KB buffer + large_msg = ( + '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"_meta":{"data":"' + + "X" * LARGE_LINE_SIZE + + '"}}}\n' + ) result = subprocess.run( # noqa: S603 [sys.executable, small_agent], input=large_msg, capture_output=True, text=True, timeout=2 ) - # Should have errors in stderr about the buffer limit - assert "Error" in result.stderr or result.returncode != 0, ( - f"Expected error with small buffer, got: {result.stderr}" - ) + assert result.returncode == 0 + assert "LimitOverrunError" not in result.stderr + assert "Separator is found, but chunk is longer than limit" not in result.stderr + assert "oversized JSON-RPC frame" not in result.stderr + assert '"id":1' in result.stdout + assert '"protocolVersion":1' in result.stdout # Test 2: Large buffer (200KB) succeeds with large message (70KB) large_agent = os.path.join(tmpdir, "large_agent.py") with open(large_agent, "w") as f: - f.write(f""" -import asyncio -from acp.core import run_agent -from acp.interfaces import Agent - -class TestAgent(Agent): - async def list_capabilities(self): - return {{"capabilities": {{}}}} - -asyncio.run(run_agent(TestAgent(), stdio_buffer_limit_bytes={LARGE_LINE_SIZE * 3})) -""") + f.write( + textwrap.dedent( + f""" + import asyncio + from acp.core import run_agent + from acp.interfaces import Agent + from acp.schema import InitializeResponse + + class TestAgent(Agent): + async def initialize(self, protocol_version, client_capabilities=None, client_info=None, **kwargs): + return InitializeResponse(protocol_version=protocol_version) + + asyncio.run(run_agent(TestAgent(), stdio_buffer_limit_bytes={LARGE_LINE_SIZE * 3})) + """ + ).strip() + ) # Same message, but with a buffer 3x the size - should handle it result = subprocess.run( # noqa: S603 @@ -98,3 +114,5 @@ async def list_capabilities(self): # (it may have other errors from invalid JSON-RPC, but not buffer overrun) if "LimitOverrunError" in result.stderr or "buffer" in result.stderr.lower(): pytest.fail(f"Large buffer still hit limit error: {result.stderr}") + assert '"id":1' in result.stdout + assert '"protocolVersion":1' in result.stdout diff --git a/tests/test_connection_recovery.py b/tests/test_connection_recovery.py new file mode 100644 index 0000000..95769f6 --- /dev/null +++ b/tests/test_connection_recovery.py @@ -0,0 +1,123 @@ +from __future__ import annotations + +import asyncio +import json +from typing import Any +from unittest.mock import AsyncMock, MagicMock + +import pytest + +from acp.connection import Connection +from acp.exceptions import RequestError + + +async def _noop_handler(method: str, params: Any, is_notification: bool) -> Any: + return None + + +def _make_connection( + *, + limit: int = 128, + receive_timeout: float | None = None, +) -> tuple[Connection, asyncio.StreamReader]: + reader = asyncio.StreamReader(limit=limit) + transport = MagicMock() + transport.is_closing.return_value = False + protocol = AsyncMock() + writer = asyncio.StreamWriter(transport, protocol, reader, asyncio.get_running_loop()) + conn = Connection(_noop_handler, writer, reader, listening=False, receive_timeout=receive_timeout) + return conn, reader + + +@pytest.mark.asyncio +async def test_receive_loop_handles_oversized_frame(caplog: pytest.LogCaptureFixture) -> None: + conn, reader = _make_connection(limit=128) + processed: list[str] = [] + + async def tracking_process(message: dict[str, Any]) -> None: + processed.append(message["method"]) + + conn._process_message = tracking_process # type: ignore[method-assign] + oversized = {"jsonrpc": "2.0", "method": "too-large", "params": {"data": "X" * 256}} + survivor = {"jsonrpc": "2.0", "method": "survivor"} + reader.feed_data(json.dumps(oversized).encode() + b"\n" + json.dumps(survivor).encode() + b"\n") + reader.feed_eof() + + with caplog.at_level("WARNING"): + await conn._receive_loop() + await conn.close() + + assert processed == ["too-large", "survivor"] + assert "oversized JSON-RPC frame" not in caplog.text + + +@pytest.mark.asyncio +async def test_receive_loop_handles_consecutive_oversized_frames() -> None: + conn, reader = _make_connection(limit=128) + processed: list[str] = [] + + async def tracking_process(message: dict[str, Any]) -> None: + processed.append(message["method"]) + + conn._process_message = tracking_process # type: ignore[method-assign] + for index in range(2): + oversized = {"jsonrpc": "2.0", "method": f"too-large-{index}", "params": {"data": "Y" * 256}} + reader.feed_data(json.dumps(oversized).encode() + b"\n") + survivor = {"jsonrpc": "2.0", "method": "survivor"} + reader.feed_data(json.dumps(survivor).encode() + b"\n") + reader.feed_eof() + + await conn._receive_loop() + await conn.close() + + assert processed == ["too-large-0", "too-large-1", "survivor"] + + +@pytest.mark.asyncio +async def test_receive_loop_handles_eof_during_oversized_frame() -> None: + conn, reader = _make_connection(limit=64) + reader.feed_data(b"X" * 256) + reader.feed_eof() + + await conn._receive_loop() + await conn.close() + + assert conn._disconnected is True + + +@pytest.mark.asyncio +async def test_receive_loop_keeps_timeout_semantics() -> None: + conn, _reader = _make_connection(receive_timeout=0.01) + + with pytest.raises(RequestError) as exc_info: + await conn._receive_loop() + await conn.close() + + exc = exc_info.value + assert isinstance(exc, RequestError) + assert str(exc) == "Internal error" + assert exc.data == {"details": "Agent timeout"} + + +@pytest.mark.asyncio +async def test_receive_loop_keeps_timeout_semantics_while_reading_oversized_frame() -> None: + conn, reader = _make_connection(limit=64, receive_timeout=0.01) + reader.feed_data(b"X" * 256) + + with pytest.raises(RequestError) as exc_info: + await conn._receive_loop() + await conn.close() + + exc = exc_info.value + assert isinstance(exc, RequestError) + assert exc.data == {"details": "Agent timeout"} + + +@pytest.mark.asyncio +async def test_receive_loop_does_not_swallow_unrelated_reader_error() -> None: + conn, reader = _make_connection() + reader.set_exception(ValueError("reader failed")) + + with pytest.raises(ValueError, match="reader failed"): + await conn._receive_loop() + await conn.close() From fe643ab0e3be122e64e78416fef8e071dc8463e8 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Tue, 30 Jun 2026 01:32:24 +0800 Subject: [PATCH 35/52] fix: close run_agent connection on cancellation (#113) --- src/acp/core.py | 6 ++++- tests/test_core.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/test_core.py diff --git a/src/acp/core.py b/src/acp/core.py index 75ab987..2d280c6 100644 --- a/src/acp/core.py +++ b/src/acp/core.py @@ -7,6 +7,7 @@ from __future__ import annotations +import asyncio from typing import Any from .agent.connection import AgentSideConnection @@ -69,7 +70,10 @@ async def run_agent( use_unstable_protocol=use_unstable_protocol, **connection_kwargs, ) - await conn.listen() + try: + await conn.listen() + finally: + await asyncio.shield(conn.close()) def connect_to_agent( diff --git a/tests/test_core.py b/tests/test_core.py new file mode 100644 index 0000000..571dd7f --- /dev/null +++ b/tests/test_core.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import asyncio +import contextlib +from typing import Any + +import pytest + +from acp.core import run_agent + + +@pytest.mark.asyncio +async def test_run_agent_closes_connection_when_cancelled(server, agent) -> None: + sender_created = asyncio.Event() + sender_closed = asyncio.Event() + dispatcher_started = asyncio.Event() + dispatcher_stopped = asyncio.Event() + + class TrackingSender: + def __init__(self, writer: asyncio.StreamWriter, supervisor: Any) -> None: + sender_created.set() + + async def send(self, payload: dict[str, Any]) -> None: + msg = "test does not send messages" + raise AssertionError(msg) + + async def close(self) -> None: + sender_closed.set() + + class TrackingDispatcher: + def start(self) -> None: + dispatcher_started.set() + + async def stop(self) -> None: + dispatcher_stopped.set() + + task = asyncio.create_task( + run_agent( + agent, + server.server_writer, + server.server_reader, + sender_factory=TrackingSender, + dispatcher_factory=lambda *args: TrackingDispatcher(), + ) + ) + + await asyncio.wait_for(sender_created.wait(), timeout=1) + await asyncio.wait_for(dispatcher_started.wait(), timeout=1) + + task.cancel() + with contextlib.suppress(asyncio.CancelledError): + await asyncio.wait_for(task, timeout=1) + + await asyncio.wait_for(dispatcher_stopped.wait(), timeout=1) + await asyncio.wait_for(sender_closed.wait(), timeout=1) From f8431a9a42fcf5fe5b25f654dd52936dfe8d4648 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sun, 5 Jul 2026 19:18:00 +0800 Subject: [PATCH 36/52] feat(schema): bump ACP schema to v1.16.0 (#114) * feat(schema): bump ACP schema to v1.16.0 * fix: generate elicitation request variants * test: sync examples with generated interfaces --- docs/releasing.md | 4 +- examples/agent.py | 4 +- examples/client.py | 20 +- examples/echo_agent.py | 2 +- examples/gemini.py | 20 +- schema/VERSION | 2 +- schema/meta.json | 64 +- schema/schema.json | 13592 +++++++++++----------- scripts/gen_all.py | 50 +- scripts/gen_schema.py | 273 +- src/acp/__init__.py | 53 + src/acp/agent/connection.py | 61 +- src/acp/client/connection.py | 12 +- src/acp/client/router.py | 88 +- src/acp/interfaces.py | 32 +- src/acp/meta.py | 60 +- src/acp/schema.py | 6149 +++++----- src/acp/utils.py | 2 +- tests/conftest.py | 47 +- tests/real_user/test_permission_flow.py | 4 +- tests/test_gen_all.py | 119 + tests/test_rpc.py | 92 +- 22 files changed, 11290 insertions(+), 9460 deletions(-) create mode 100644 tests/test_gen_all.py diff --git a/docs/releasing.md b/docs/releasing.md index 0e3c42a..68fd50e 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -4,9 +4,9 @@ Every package release tracks an upstream ACP schema tag from [`agentclientprotoc ## Prep checklist -1. **Choose the schema tag** (e.g. `v0.4.5`) and regenerate artifacts: +1. **Choose the schema tag** (e.g. `schema-v1.16.0`) and regenerate artifacts: ```bash - ACP_SCHEMA_VERSION=v0.4.5 make gen-all + ACP_SCHEMA_VERSION=schema-v1.16.0 make gen-all ``` This refreshes `schema/` and the generated `src/acp/schema.py`. 2. **Bump the SDK version** in `pyproject.toml` using a PEP 440 version string (for example `0.9.0a1` for an alpha release), and sync `uv.lock` if the lockfile is tracked. diff --git a/examples/agent.py b/examples/agent.py index 8d64a9d..9ee0272 100644 --- a/examples/agent.py +++ b/examples/agent.py @@ -89,12 +89,13 @@ async def load_session( self._sessions.add(session_id) return LoadSessionResponse() - async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: + async def set_session_mode(self, session_id: str, mode_id: str, **kwargs: Any) -> SetSessionModeResponse | None: logging.info("Received set session mode request %s -> %s", session_id, mode_id) return SetSessionModeResponse() async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -102,7 +103,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: logging.info("Received prompt request for session %s", session_id) diff --git a/examples/client.py b/examples/client.py index c70de70..653aaad 100644 --- a/examples/client.py +++ b/examples/client.py @@ -25,8 +25,11 @@ AvailableCommandsUpdate, ClientCapabilities, ConfigOptionUpdate, + CreateElicitationResponse, CreateTerminalResponse, CurrentModeUpdate, + DeclineElicitationResponse, + ElicitationMode, EmbeddedResourceContentBlock, EnvVariable, ImageContentBlock, @@ -52,27 +55,27 @@ class ExampleClient(Client): async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any + self, session_id: str, tool_call: ToolCallUpdate, options: list[PermissionOption], **kwargs: Any ) -> RequestPermissionResponse: raise RequestError.method_not_found("session/request_permission") async def write_text_file( - self, content: str, path: str, session_id: str, **kwargs: Any + self, session_id: str, path: str, content: str, **kwargs: Any ) -> WriteTextFileResponse | None: raise RequestError.method_not_found("fs/write_text_file") async def read_text_file( - self, path: str, session_id: str, limit: int | None = None, line: int | None = None, **kwargs: Any + self, session_id: str, path: str, line: int | None = None, limit: int | None = None, **kwargs: Any ) -> ReadTextFileResponse: raise RequestError.method_not_found("fs/read_text_file") async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: @@ -94,6 +97,13 @@ async def wait_for_terminal_exit( async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: raise RequestError.method_not_found("terminal/kill") + async def create_elicitation(self, message: str, mode: ElicitationMode, **kwargs: Any) -> CreateElicitationResponse: + print(f"| Agent requested input: {message} ({type(mode).__name__})") + return DeclineElicitationResponse(action="decline") + + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: + print(f"| Agent completed elicitation: {elicitation_id}") + async def session_update( self, session_id: str, diff --git a/examples/echo_agent.py b/examples/echo_agent.py index 5218458..ffb84bc 100644 --- a/examples/echo_agent.py +++ b/examples/echo_agent.py @@ -58,6 +58,7 @@ async def new_session( async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -65,7 +66,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: for block in prompt: diff --git a/examples/gemini.py b/examples/gemini.py index 71b6b44..ebbb244 100644 --- a/examples/gemini.py +++ b/examples/gemini.py @@ -30,9 +30,12 @@ AvailableCommandsUpdate, ClientCapabilities, ConfigOptionUpdate, + CreateElicitationResponse, CreateTerminalResponse, CurrentModeUpdate, + DeclineElicitationResponse, DeniedOutcome, + ElicitationMode, EmbeddedResourceContentBlock, EnvVariable, FileEditToolCallContent, @@ -64,7 +67,7 @@ def __init__(self, auto_approve: bool) -> None: self._auto_approve = auto_approve async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any + self, session_id: str, tool_call: ToolCallUpdate, options: list[PermissionOption], **kwargs: Any ) -> RequestPermissionResponse: if self._auto_approve: option = _pick_preferred_option(options) @@ -95,7 +98,7 @@ async def request_permission( print("Invalid selection, try again.") async def write_text_file( - self, content: str, path: str, session_id: str, **kwargs: Any + self, session_id: str, path: str, content: str, **kwargs: Any ) -> WriteTextFileResponse | None: pathlib_path = Path(path) if not pathlib_path.is_absolute(): @@ -106,7 +109,7 @@ async def write_text_file( return WriteTextFileResponse() async def read_text_file( - self, path: str, session_id: str, limit: int | None = None, line: int | None = None, **kwargs: Any + self, session_id: str, path: str, line: int | None = None, limit: int | None = None, **kwargs: Any ) -> ReadTextFileResponse: pathlib_path = Path(path) if not pathlib_path.is_absolute(): @@ -170,17 +173,24 @@ async def session_update( # noqa: C901 # Optional / terminal-related methods --------------------------------- async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: print(f"[Client] createTerminal: {command} {args or []} (cwd={cwd})") return CreateTerminalResponse(terminal_id="term-1") + async def create_elicitation(self, message: str, mode: ElicitationMode, **kwargs: Any) -> CreateElicitationResponse: + print(f"\n[elicitation] {message} ({type(mode).__name__})") + return DeclineElicitationResponse(action="decline") + + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: + print(f"\n[elicitation complete] {elicitation_id}") + async def terminal_output(self, session_id: str, terminal_id: str, **kwargs: Any) -> TerminalOutputResponse: print(f"[Client] terminalOutput: {session_id} {terminal_id}") return TerminalOutputResponse(output="", truncated=False) diff --git a/schema/VERSION b/schema/VERSION index 131bb6e..994766d 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/v0.13.6 +refs/tags/schema-v1.16.0 diff --git a/schema/meta.json b/schema/meta.json index 071a291..d8937f3 100644 --- a/schema/meta.json +++ b/schema/meta.json @@ -1,52 +1,52 @@ { + "version": 1, "agentMethods": { - "authenticate": "authenticate", - "document_did_change": "document/didChange", - "document_did_close": "document/didClose", - "document_did_focus": "document/didFocus", - "document_did_open": "document/didOpen", - "document_did_save": "document/didSave", "initialize": "initialize", - "logout": "logout", - "mcp_message": "mcp/message", - "nes_accept": "nes/accept", - "nes_close": "nes/close", - "nes_reject": "nes/reject", - "nes_start": "nes/start", - "nes_suggest": "nes/suggest", - "providers_disable": "providers/disable", + "authenticate": "authenticate", "providers_list": "providers/list", "providers_set": "providers/set", + "providers_disable": "providers/disable", + "session_new": "session/new", + "session_load": "session/load", + "session_set_mode": "session/set_mode", + "session_set_config_option": "session/set_config_option", + "session_prompt": "session/prompt", "session_cancel": "session/cancel", - "session_close": "session/close", + "mcp_message": "mcp/message", + "session_list": "session/list", "session_delete": "session/delete", "session_fork": "session/fork", - "session_list": "session/list", - "session_load": "session/load", - "session_new": "session/new", - "session_prompt": "session/prompt", "session_resume": "session/resume", - "session_set_config_option": "session/set_config_option", - "session_set_mode": "session/set_mode" + "session_close": "session/close", + "logout": "logout", + "nes_start": "nes/start", + "nes_suggest": "nes/suggest", + "nes_accept": "nes/accept", + "nes_reject": "nes/reject", + "nes_close": "nes/close", + "document_did_open": "document/didOpen", + "document_did_change": "document/didChange", + "document_did_close": "document/didClose", + "document_did_save": "document/didSave", + "document_did_focus": "document/didFocus" }, "clientMethods": { - "elicitation_complete": "elicitation/complete", - "elicitation_create": "elicitation/create", - "fs_read_text_file": "fs/read_text_file", - "fs_write_text_file": "fs/write_text_file", - "mcp_connect": "mcp/connect", - "mcp_disconnect": "mcp/disconnect", - "mcp_message": "mcp/message", "session_request_permission": "session/request_permission", "session_update": "session/update", + "fs_write_text_file": "fs/write_text_file", + "fs_read_text_file": "fs/read_text_file", "terminal_create": "terminal/create", - "terminal_kill": "terminal/kill", "terminal_output": "terminal/output", "terminal_release": "terminal/release", - "terminal_wait_for_exit": "terminal/wait_for_exit" + "terminal_wait_for_exit": "terminal/wait_for_exit", + "terminal_kill": "terminal/kill", + "mcp_connect": "mcp/connect", + "mcp_message": "mcp/message", + "mcp_disconnect": "mcp/disconnect", + "elicitation_create": "elicitation/create", + "elicitation_complete": "elicitation/complete" }, "protocolMethods": { "cancel_request": "$/cancel_request" - }, - "version": 1 + } } diff --git a/schema/schema.json b/schema/schema.json index ca72e85..a117ee8 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -1,208 +1,122 @@ { - "$defs": { - "AcceptNesNotification": { - "description": "Notification sent when a suggestion is accepted.", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Agent Client Protocol", + "anyOf": [ + { + "title": "Agent", + "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "jsonrpc": { + "type": "string", + "enum": [ + "2.0" ] - }, - "id": { - "description": "The ID of the accepted suggestion.", - "type": "string" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The session ID for this notification." } }, "required": [ - "sessionId", - "id" + "jsonrpc" ], - "type": "object", - "x-method": "nes/accept", - "x-side": "agent" - }, - "AgentAuthCapabilities": { - "description": "Authentication-related capabilities supported by the agent.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "logout": { - "anyOf": [ - { - "$ref": "#/$defs/LogoutCapabilities" - }, + "anyOf": [ + { + "title": "Request", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/AgentRequest" } - ], - "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method.", - "x-deserialize-default-on-error": true - } - }, - "type": "object" - }, - "AgentCapabilities": { - "description": "Capabilities supported by the agent.\n\nAdvertised during initialization to inform the client about\navailable features and content types.\n\nSee protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] }, - "auth": { + { + "title": "Response", "allOf": [ { - "$ref": "#/$defs/AgentAuthCapabilities" + "$ref": "#/$defs/AgentResponse" } - ], - "default": {}, - "description": "Authentication-related capabilities supported by the agent." - }, - "loadSession": { - "default": false, - "description": "Whether the agent supports `session/load`.", - "type": "boolean" + ] }, - "mcpCapabilities": { + { + "title": "Notification", "allOf": [ { - "$ref": "#/$defs/McpCapabilities" - } - ], - "default": { - "acp": false, - "http": false, - "sse": false - }, - "description": "MCP capabilities supported by the agent." - }, - "nes": { - "anyOf": [ - { - "$ref": "#/$defs/NesCapabilities" - }, - { - "type": "null" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.", - "x-deserialize-default-on-error": true - }, - "positionEncoding": { - "anyOf": [ - { - "$ref": "#/$defs/PositionEncodingKind" - }, - { - "type": "null" + "$ref": "#/$defs/AgentNotification" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", - "x-deserialize-default-on-error": true - }, - "promptCapabilities": { + ] + } + ] + }, + { + "title": "Client", + "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", + "type": "object", + "properties": { + "jsonrpc": { + "type": "string", + "enum": [ + "2.0" + ] + } + }, + "required": [ + "jsonrpc" + ], + "anyOf": [ + { + "title": "Request", "allOf": [ { - "$ref": "#/$defs/PromptCapabilities" + "$ref": "#/$defs/ClientRequest" } - ], - "default": { - "audio": false, - "embeddedContext": false, - "image": false - }, - "description": "Prompt capabilities supported by the agent." + ] }, - "providers": { - "anyOf": [ - { - "$ref": "#/$defs/ProvidersCapabilities" - }, + { + "title": "Response", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/ClientResponse" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", - "x-deserialize-default-on-error": true + ] }, - "sessionCapabilities": { + { + "title": "Notification", "allOf": [ { - "$ref": "#/$defs/SessionCapabilities" + "$ref": "#/$defs/ClientNotification" } - ], - "default": {} + ] } - }, - "type": "object" + ] }, - "AgentNotification": { + { + "title": "ProtocolLevel", + "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", + "type": "object", "properties": { + "jsonrpc": { + "type": "string", + "enum": [ + "2.0" + ] + }, "method": { + "description": "The notification method name.", "type": "string" }, "params": { + "description": "Method-specific notification parameters.", "anyOf": [ { + "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response.", "anyOf": [ { + "title": "CancelRequestNotification", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", "allOf": [ { - "$ref": "#/$defs/SessionNotification" - } - ], - "description": "Handles session update notifications from the agent.\n\nThis is a notification endpoint (no response expected) that receives\nreal-time updates about session progress, including message chunks,\ntool calls, and execution plans.\n\nNote: Clients SHOULD continue accepting tool call updates even after\nsending a `session/cancel` notification, as the agent may send final\nupdates before responding with the cancelled stop reason.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", - "title": "SessionNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CompleteElicitationNotification" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification that a URL-based elicitation has completed.", - "title": "CompleteElicitationNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/MessageMcpNotification" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReceives an MCP-over-ACP notification.", - "title": "MessageMcpNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ExtNotification" + "$ref": "#/$defs/CancelRequestNotification" } - ], - "description": "Handles extension notifications from the agent.\n\nAllows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "title": "ExtNotification" + ] } - ], - "description": "All possible notifications that an agent can send to a client.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response." + ] }, { "type": "null" @@ -211,142 +125,153 @@ } }, "required": [ + "jsonrpc", "method" ], - "type": "object", "x-docs-ignore": true - }, + } + ], + "$defs": { "AgentRequest": { + "description": "A JSON-RPC request object.", + "type": "object", "properties": { "id": { - "$ref": "#/$defs/RequestId" + "description": "The request id used to correlate the matching response.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] }, "method": { + "description": "The method name to invoke.", "type": "string" }, "params": { + "description": "Method-specific request parameters.", "anyOf": [ { + "description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from agent to client.", "anyOf": [ { + "title": "WriteTextFileRequest", + "description": "Writes content to a text file in the client's file system.\n\nOnly available if the client advertises the `fs.writeTextFile` capability.\nAllows the agent to create or modify files within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", "allOf": [ { "$ref": "#/$defs/WriteTextFileRequest" } - ], - "description": "Writes content to a text file in the client's file system.\n\nOnly available if the client advertises the `fs.writeTextFile` capability.\nAllows the agent to create or modify files within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", - "title": "WriteTextFileRequest" + ] }, { + "title": "ReadTextFileRequest", + "description": "Reads content from a text file in the client's file system.\n\nOnly available if the client advertises the `fs.readTextFile` capability.\nAllows the agent to access file contents within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", "allOf": [ { "$ref": "#/$defs/ReadTextFileRequest" } - ], - "description": "Reads content from a text file in the client's file system.\n\nOnly available if the client advertises the `fs.readTextFile` capability.\nAllows the agent to access file contents within the client's environment.\n\nSee protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client)", - "title": "ReadTextFileRequest" + ] }, { + "title": "RequestPermissionRequest", + "description": "Requests permission from the user for a tool call operation.\n\nCalled by the agent when it needs user authorization before executing\na potentially sensitive operation. The client should present the options\nto the user and return their decision.\n\nIf the client cancels the prompt turn via `session/cancel`, it MUST\nrespond to this request with `RequestPermissionOutcome::Cancelled`.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", "allOf": [ { "$ref": "#/$defs/RequestPermissionRequest" } - ], - "description": "Requests permission from the user for a tool call operation.\n\nCalled by the agent when it needs user authorization before executing\na potentially sensitive operation. The client should present the options\nto the user and return their decision.\n\nIf the client cancels the prompt turn via `session/cancel`, it MUST\nrespond to this request with `RequestPermissionOutcome::Cancelled`.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", - "title": "RequestPermissionRequest" + ] }, { + "title": "CreateTerminalRequest", + "description": "Executes a command in a new terminal\n\nOnly available if the `terminal` Client capability is set to `true`.\n\nReturns a `TerminalId` that can be used with other terminal methods\nto get the current output, wait for exit, and kill the command.\n\nThe `TerminalId` can also be used to embed the terminal in a tool call\nby using the `ToolCallContent::Terminal` variant.\n\nThe Agent is responsible for releasing the terminal by using the `terminal/release`\nmethod.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "allOf": [ { "$ref": "#/$defs/CreateTerminalRequest" } - ], - "description": "Executes a command in a new terminal\n\nOnly available if the `terminal` Client capability is set to `true`.\n\nReturns a `TerminalId` that can be used with other terminal methods\nto get the current output, wait for exit, and kill the command.\n\nThe `TerminalId` can also be used to embed the terminal in a tool call\nby using the `ToolCallContent::Terminal` variant.\n\nThe Agent is responsible for releasing the terminal by using the `terminal/release`\nmethod.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "CreateTerminalRequest" + ] }, { + "title": "TerminalOutputRequest", + "description": "Gets the terminal output and exit status\n\nReturns the current content in the terminal without waiting for the command to exit.\nIf the command has already exited, the exit status is included.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "allOf": [ { "$ref": "#/$defs/TerminalOutputRequest" } - ], - "description": "Gets the terminal output and exit status\n\nReturns the current content in the terminal without waiting for the command to exit.\nIf the command has already exited, the exit status is included.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "TerminalOutputRequest" + ] }, { + "title": "ReleaseTerminalRequest", + "description": "Releases a terminal\n\nThe command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`\nto wait for the command to exit before releasing the terminal.\n\nAfter release, the `TerminalId` can no longer be used with other `terminal/*` methods,\nbut tool calls that already contain it, continue to display its output.\n\nThe `terminal/kill` method can be used to terminate the command without releasing\nthe terminal, allowing the Agent to call `terminal/output` and other methods.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "allOf": [ { "$ref": "#/$defs/ReleaseTerminalRequest" } - ], - "description": "Releases a terminal\n\nThe command is killed if it hasn't exited yet. Use `terminal/wait_for_exit`\nto wait for the command to exit before releasing the terminal.\n\nAfter release, the `TerminalId` can no longer be used with other `terminal/*` methods,\nbut tool calls that already contain it, continue to display its output.\n\nThe `terminal/kill` method can be used to terminate the command without releasing\nthe terminal, allowing the Agent to call `terminal/output` and other methods.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "ReleaseTerminalRequest" + ] }, { + "title": "WaitForTerminalExitRequest", + "description": "Waits for the terminal command to exit and return its exit status\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "allOf": [ { "$ref": "#/$defs/WaitForTerminalExitRequest" } - ], - "description": "Waits for the terminal command to exit and return its exit status\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "WaitForTerminalExitRequest" + ] }, { + "title": "KillTerminalRequest", + "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: Call `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", "allOf": [ { "$ref": "#/$defs/KillTerminalRequest" } - ], - "description": "Kills the terminal command without releasing the terminal\n\nWhile `terminal/release` will also kill the command, this method will keep\nthe `TerminalId` valid so it can be used with other methods.\n\nThis method can be helpful when implementing command timeouts which terminate\nthe command as soon as elapsed, and then get the final output so it can be sent\nto the model.\n\nNote: Call `terminal/release` when `TerminalId` is no longer needed.\n\nSee protocol docs: [Terminals](https://agentclientprotocol.com/protocol/terminals)", - "title": "KillTerminalRequest" + ] }, { + "title": "CreateElicitationRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests structured user input via a form or URL.", "allOf": [ { "$ref": "#/$defs/CreateElicitationRequest" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests structured user input via a form or URL.", - "title": "CreateElicitationRequest" + ] }, { + "title": "ConnectMcpRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nOpens an MCP-over-ACP connection.", "allOf": [ { "$ref": "#/$defs/ConnectMcpRequest" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nOpens an MCP-over-ACP connection.", - "title": "ConnectMcpRequest" + ] }, { + "title": "MessageMcpRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", "allOf": [ { "$ref": "#/$defs/MessageMcpRequest" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", - "title": "MessageMcpRequest" + ] }, { + "title": "DisconnectMcpRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an MCP-over-ACP connection.", "allOf": [ { "$ref": "#/$defs/DisconnectMcpRequest" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an MCP-over-ACP connection.", - "title": "DisconnectMcpRequest" + ] }, { + "title": "ExtMethodRequest", + "description": "Handles extension method requests from the agent.\n\nAllows the Agent to send an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "allOf": [ { "$ref": "#/$defs/ExtRequest" } - ], - "description": "Handles extension method requests from the agent.\n\nAllows the Agent to send an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "title": "ExtMethodRequest" + ] } - ], - "description": "All possible requests that an agent can send to a client.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from agent to client." + ] }, { "type": "null" @@ -358,3116 +283,2570 @@ "id", "method" ], - "type": "object", "x-docs-ignore": true }, - "AgentResponse": { + "RequestId": { + "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions.", "anyOf": [ { - "properties": { - "id": { - "$ref": "#/$defs/RequestId" - }, - "result": { - "anyOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/InitializeResponse" - } - ], - "title": "InitializeResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/AuthenticateResponse" - } - ], - "title": "AuthenticateResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ListProvidersResponse" - } - ], - "title": "ListProvidersResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetProviderResponse" - } - ], - "title": "SetProviderResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DisableProviderResponse" - } - ], - "title": "DisableProviderResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/LogoutResponse" - } - ], - "title": "LogoutResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/NewSessionResponse" - } - ], - "title": "NewSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/LoadSessionResponse" - } - ], - "title": "LoadSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ListSessionsResponse" - } - ], - "title": "ListSessionsResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DeleteSessionResponse" - } - ], - "title": "DeleteSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ForkSessionResponse" - } - ], - "title": "ForkSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ResumeSessionResponse" - } - ], - "title": "ResumeSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CloseSessionResponse" - } - ], - "title": "CloseSessionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionModeResponse" - } - ], - "title": "SetSessionModeResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionConfigOptionResponse" - } - ], - "title": "SetSessionConfigOptionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/PromptResponse" - } - ], - "title": "PromptResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/StartNesResponse" - } - ], - "title": "StartNesResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SuggestNesResponse" - } - ], - "title": "SuggestNesResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CloseNesResponse" - } - ], - "title": "CloseNesResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ExtResponse" - } - ], - "title": "ExtMethodResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/MessageMcpResponse" - } - ], - "title": "MessageMcpResponse" - } - ], - "description": "All possible responses that an agent can send to a client.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `ClientRequest` variants." - } - }, - "required": [ - "id", - "result" - ], - "title": "Result", - "type": "object" + "title": "Null", + "description": "The JSON-RPC `null` request id.", + "type": "null" }, { - "properties": { - "error": { - "$ref": "#/$defs/Error" - }, - "id": { - "$ref": "#/$defs/RequestId" - } - }, - "required": [ - "id", - "error" - ], - "title": "Error", - "type": "object" + "title": "Number", + "description": "A numeric JSON-RPC request id.", + "type": "integer", + "format": "int64" + }, + { + "title": "Str", + "description": "A string JSON-RPC request id.", + "type": "string" } - ], - "x-docs-ignore": true + ] }, - "Annotations": { - "description": "Optional annotations for the client. The client can use annotations to inform how objects are used or displayed", + "WriteTextFileRequest": { + "description": "Request to write content to a text file.\n\nOnly available if the client supports the `fs.writeTextFile` capability.", + "type": "object", "properties": { + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, + "path": { + "description": "Absolute path to the file to write.", + "type": "string" + }, + "content": { + "description": "The text content to write to the file.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "sessionId", + "path", + "content" + ], + "x-side": "client", + "x-method": "fs/write_text_file" + }, + "SessionId": { + "description": "A unique identifier for a conversation session between a client and agent.\n\nSessions maintain their own context, conversation history, and state,\nallowing multiple independent interactions with the same agent.\n\nSee protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)", + "type": "string" + }, + "ReadTextFileRequest": { + "description": "Request to read content from a text file.\n\nOnly available if the client supports the `fs.readTextFile` capability.", + "type": "object", + "properties": { + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "audience": { - "items": { - "$ref": "#/$defs/Role" - }, + "path": { + "description": "Absolute path to the file to read.", + "type": "string" + }, + "line": { + "description": "Line number to start reading from (1-based).", "type": [ - "array", + "integer", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "format": "uint32", + "minimum": 0 }, - "lastModified": { + "limit": { + "description": "Maximum number of lines to read.", "type": [ - "string", + "integer", "null" - ] + ], + "format": "uint32", + "minimum": 0 }, - "priority": { - "format": "double", - "type": [ - "number", - "null" - ] - } - }, - "type": "object" - }, - "AudioContent": { - "description": "Audio provided to or from an LLM.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/$defs/Annotations" - }, - { - "type": "null" - } ], - "x-deserialize-default-on-error": true - }, - "data": { - "type": "string" - }, - "mimeType": { - "type": "string" + "additionalProperties": true } }, "required": [ - "data", - "mimeType" + "sessionId", + "path" ], - "type": "object" + "x-side": "client", + "x-method": "fs/read_text_file" }, - "AuthCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\n\nAdvertised during initialization to inform the agent which authentication\nmethod types the client can handle. This governs opt-in types that require\nadditional client-side support.", + "RequestPermissionRequest": { + "description": "Request for user permission to execute a tool call.\n\nSent when the agent needs authorization before performing a sensitive operation.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "terminal": { - "default": false, - "description": "Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods.", - "type": "boolean" - } - }, - "type": "object" - }, - "AuthEnvVar": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDescribes a single environment variable for an [`AuthMethodEnvVar`] authentication method.", - "properties": { + "toolCall": { + "description": "Details about the tool call requiring permission.", + "allOf": [ + { + "$ref": "#/$defs/ToolCallUpdate" + } + ] + }, + "options": { + "description": "Available permission options for the user to choose from.", + "type": "array", + "items": { + "$ref": "#/$defs/PermissionOption" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "label": { - "description": "Human-readable label for this variable, displayed in client UI.", - "type": [ - "string", - "null" - ] - }, - "name": { - "description": "The environment variable name (e.g. `\"OPENAI_API_KEY\"`).", - "type": "string" - }, - "optional": { - "default": false, - "description": "Whether this variable is optional.\n\nDefaults to `false`.", - "type": "boolean" - }, - "secret": { - "default": true, - "description": "Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`.", - "type": "boolean" + ], + "additionalProperties": true } }, "required": [ - "name" + "sessionId", + "toolCall", + "options" ], - "type": "object" + "x-side": "client", + "x-method": "session/request_permission" }, - "AuthMethod": { - "anyOf": [ - { + "ToolCallUpdate": { + "description": "An update to an existing tool call.\n\nUsed to report progress and results as tools execute. All fields except\nthe tool call ID are optional - only changed fields need to be included.\n\nSee protocol docs: [Updating](https://agentclientprotocol.com/protocol/tool-calls#updating)", + "type": "object", + "properties": { + "toolCallId": { + "description": "The ID of the tool call being updated.", "allOf": [ { - "$ref": "#/$defs/AuthMethodEnvVar" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUser provides a key that the client passes to the agent as an environment variable.", - "properties": { - "type": { - "const": "env_var", - "type": "string" + "$ref": "#/$defs/ToolCallId" } - }, - "required": [ - "type" - ], - "type": "object" + ] }, - { - "allOf": [ + "kind": { + "description": "Update the tool kind.", + "anyOf": [ { - "$ref": "#/$defs/AuthMethodTerminal" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nClient runs an interactive terminal for the user to authenticate via a TUI.", - "properties": { - "type": { - "const": "terminal", - "type": "string" + "$ref": "#/$defs/ToolKind" + }, + { + "type": "null" } - }, - "required": [ - "type" ], - "type": "object" + "x-deserialize-default-on-error": true }, - { - "allOf": [ + "status": { + "description": "Update the execution status.", + "anyOf": [ { - "$ref": "#/$defs/AuthMethodAgent" + "$ref": "#/$defs/ToolCallStatus" + }, + { + "type": "null" } ], - "description": "Agent handles authentication itself.\n\nThis is the default when no `type` is specified.", - "title": "agent" - } - ], - "description": "Describes an available authentication method.\n\nThe `type` field acts as the discriminator in the serialized JSON form.\nWhen no `type` is present, the method is treated as `agent`." - }, - "AuthMethodAgent": { - "description": "Agent handles authentication itself.\n\nThis is the default authentication method type.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "description": { - "description": "Optional description providing more details about this authentication method.", - "type": [ - "string", - "null" - ] - }, - "id": { - "description": "Unique identifier for this authentication method.", - "type": "string" - }, - "name": { - "description": "Human-readable name of the authentication method.", - "type": "string" - } - }, - "required": [ - "id", - "name" - ], - "type": "object" - }, - "AuthMethodEnvVar": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nEnvironment variable authentication method.\n\nThe user provides credentials that the client passes to the agent as environment variables.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "x-deserialize-default-on-error": true }, - "description": { - "description": "Optional description providing more details about this authentication method.", + "title": { + "description": "Update the human-readable title.", "type": [ "string", "null" ] }, - "id": { - "description": "Unique identifier for this authentication method.", - "type": "string" - }, - "link": { - "description": "Optional link to a page where the user can obtain their credentials.", + "content": { + "description": "Replace the content collection.", "type": [ - "string", + "array", "null" - ] - }, - "name": { - "description": "Human-readable name of the authentication method.", - "type": "string" - }, - "vars": { - "description": "The environment variables the client should set.", + ], "items": { - "$ref": "#/$defs/AuthEnvVar" + "$ref": "#/$defs/ToolCallContent" }, - "type": "array" - } - }, - "required": [ - "id", - "name", - "vars" - ], - "type": "object" - }, - "AuthMethodTerminal": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nTerminal-based authentication method.\n\nThe client runs an interactive terminal for the user to authenticate via a TUI.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "locations": { + "description": "Replace the locations collection.", "type": [ - "object", + "array", "null" - ] - }, - "args": { - "description": "Additional arguments to pass when running the agent binary for terminal auth.", + ], "items": { - "type": "string" + "$ref": "#/$defs/ToolCallLocation" }, - "type": "array" - }, - "description": { - "description": "Optional description providing more details about this authentication method.", - "type": [ - "string", - "null" - ] + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "env": { - "additionalProperties": { - "type": "string" - }, - "description": "Additional environment variables to set when running the agent binary for terminal auth.", - "type": "object" + "rawInput": { + "description": "Update the raw input." }, - "id": { - "description": "Unique identifier for this authentication method.", - "type": "string" + "rawOutput": { + "description": "Update the raw output." }, - "name": { - "description": "Human-readable name of the authentication method.", - "type": "string" - } - }, - "required": [ - "id", - "name" - ], - "type": "object" - }, - "AuthenticateRequest": { - "description": "Request parameters for the authenticate method.\n\nSpecifies which authentication method to use.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "methodId": { - "description": "The ID of the authentication method to use.\nMust be one of the methods advertised in the initialize response.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "methodId" - ], - "type": "object", - "x-method": "authenticate", - "x-side": "agent" + "toolCallId" + ] }, - "AuthenticateResponse": { - "description": "Response to the `authenticate` method.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - } - }, - "type": "object", - "x-method": "authenticate", - "x-side": "agent" + "ToolCallId": { + "description": "Unique identifier for a tool call within a session.", + "type": "string" }, - "AvailableCommand": { - "description": "Information about a command.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "ToolKind": { + "description": "Categories of tools that can be invoked.\n\nTool kinds help clients choose appropriate icons and optimize how they\ndisplay tool execution progress.\n\nSee protocol docs: [Creating](https://agentclientprotocol.com/protocol/tool-calls#creating)", + "oneOf": [ + { + "description": "Reading files or data.", + "type": "string", + "const": "read" }, - "description": { - "description": "Human-readable description of what the command does.", - "type": "string" + { + "description": "Modifying files or content.", + "type": "string", + "const": "edit" }, - "input": { - "anyOf": [ - { - "$ref": "#/$defs/AvailableCommandInput" - }, - { - "type": "null" - } - ], - "description": "Input for the command if required", - "x-deserialize-default-on-error": true + { + "description": "Removing files or data.", + "type": "string", + "const": "delete" }, - "name": { - "description": "Command name (e.g., `create_plan`, `research_codebase`).", - "type": "string" - } - }, - "required": [ - "name", - "description" - ], - "type": "object" - }, - "AvailableCommandInput": { - "anyOf": [ { - "allOf": [ - { - "$ref": "#/$defs/UnstructuredCommandInput" - } - ], - "description": "All text that was typed after the command name is provided as input.", - "title": "unstructured" - } - ], - "description": "The input specification for a command." - }, - "AvailableCommandsUpdate": { - "description": "Available commands are ready or have changed", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "description": "Moving or renaming files.", + "type": "string", + "const": "move" }, - "availableCommands": { - "description": "Commands the agent can execute", - "items": { - "$ref": "#/$defs/AvailableCommand" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - } - }, - "required": [ - "availableCommands" - ], - "type": "object" - }, - "BlobResourceContents": { - "description": "Binary resource contents.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + { + "description": "Searching for information.", + "type": "string", + "const": "search" }, - "blob": { - "type": "string" + { + "description": "Running commands or code.", + "type": "string", + "const": "execute" }, - "mimeType": { - "type": [ - "string", - "null" - ] + { + "description": "Internal reasoning or planning.", + "type": "string", + "const": "think" }, - "uri": { - "type": "string" + { + "description": "Retrieving external data.", + "type": "string", + "const": "fetch" + }, + { + "description": "Switching the current session mode.", + "type": "string", + "const": "switch_mode" + }, + { + "description": "Other tool types (default).", + "type": "string", + "const": "other" } - }, - "required": [ - "blob", - "uri" - ], - "type": "object" + ] }, - "BooleanPropertySchema": { - "description": "Schema for boolean properties in an elicitation form.", - "properties": { - "default": { - "description": "Default value.", - "type": [ - "boolean", - "null" - ] + "ToolCallStatus": { + "description": "Execution status of a tool call.\n\nTool calls progress through different statuses during their lifecycle.\n\nSee protocol docs: [Status](https://agentclientprotocol.com/protocol/tool-calls#status)", + "oneOf": [ + { + "description": "The tool call hasn't started running yet because the input is either\nstreaming or we're awaiting approval.", + "type": "string", + "const": "pending" }, - "description": { - "description": "Human-readable description.", - "type": [ - "string", - "null" - ] + { + "description": "The tool call is currently running.", + "type": "string", + "const": "in_progress" }, - "title": { - "description": "Optional title for the property.", - "type": [ - "string", - "null" - ] + { + "description": "The tool call completed successfully.", + "type": "string", + "const": "completed" + }, + { + "description": "The tool call failed with an error.", + "type": "string", + "const": "failed" } - }, - "type": "object" + ] }, - "CancelNotification": { - "description": "Notification to cancel ongoing operations for a session.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "ToolCallContent": { + "description": "Content produced by a tool call.\n\nTool calls can produce different types of content including\nstandard content blocks (text, images) or file diffs.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", + "oneOf": [ + { + "description": "Standard content block (text, images, resources).", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "content" + } + }, + "required": [ + "type" + ], + "allOf": [ + { + "$ref": "#/$defs/Content" + } ] }, - "sessionId": { + { + "description": "File modification shown as a diff.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "diff" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/Diff" } - ], - "description": "The ID of the session to cancel operations for." - } - }, - "required": [ - "sessionId" - ], - "type": "object", - "x-method": "session/cancel", - "x-side": "agent" - }, - "CancelRequestNotification": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification to cancel an ongoing request.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] }, - "requestId": { + { + "description": "Embed a terminal created with `terminal/create` by its id.\n\nThe terminal must be added before calling `terminal/release`.\n\nSee protocol docs: [Terminal](https://agentclientprotocol.com/protocol/terminals)", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "terminal" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/RequestId" + "$ref": "#/$defs/Terminal" } - ], - "description": "The ID of the request to cancel." + ] } - }, - "required": [ - "requestId" ], - "type": "object", - "x-method": "$/cancel_request", - "x-side": "protocol" + "discriminator": { + "propertyName": "type" + } }, - "ClientCapabilities": { - "description": "Capabilities supported by the client.\n\nAdvertised during initialization to inform the agent about\navailable features and methods.\n\nSee protocol docs: [Client Capabilities](https://agentclientprotocol.com/protocol/initialization#client-capabilities)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "auth": { - "allOf": [ - { - "$ref": "#/$defs/AuthCapabilities" + "ContentBlock": { + "description": "Content blocks represent displayable information in the Agent Client Protocol.\n\nThey provide a structured way to handle various types of user-facing content\u2014whether\nit's text from language models, images for analysis, or embedded resources for context.\n\nContent blocks appear in:\n- User prompts sent via `session/prompt`\n- Language model output streamed through `session/update` notifications\n- Progress updates and results from tool calls\n\nThis structure is compatible with the Model Context Protocol (MCP), enabling\nagents to seamlessly forward content from MCP tool outputs without transformation.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/content)", + "oneOf": [ + { + "description": "Text content. May be plain text or formatted with Markdown.\n\nAll agents MUST support text content blocks in prompts.\nClients SHOULD render this text as Markdown.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "text" } - ], - "default": { - "terminal": false }, - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." - }, - "elicitation": { - "anyOf": [ - { - "$ref": "#/$defs/ElicitationCapabilities" - }, - { - "type": "null" - } + "required": [ + "type" ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.", - "x-deserialize-default-on-error": true - }, - "fs": { "allOf": [ - { - "$ref": "#/$defs/FileSystemCapabilities" - } - ], - "default": { - "readTextFile": false, - "writeTextFile": false - }, - "description": "File system capabilities supported by the client.\nDetermines which file operations the agent can request." - }, - "nes": { - "anyOf": [ - { - "$ref": "#/$defs/ClientNesCapabilities" - }, - { - "type": "null" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.", - "x-deserialize-default-on-error": true - }, - "plan": { - "anyOf": [ - { - "$ref": "#/$defs/PlanCapabilities" - }, - { - "type": "null" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types.", - "x-deserialize-default-on-error": true - }, - "positionEncodings": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", - "items": { - "$ref": "#/$defs/PositionEncodingKind" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "terminal": { - "default": false, - "description": "Whether the Client support all `terminal/*` methods.", - "type": "boolean" - } - }, - "type": "object" - }, - "ClientNesCapabilities": { - "description": "NES capabilities advertised by the client during initialization.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "jump": { - "anyOf": [ - { - "$ref": "#/$defs/NesJumpCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the client supports the `jump` suggestion kind.", - "x-deserialize-default-on-error": true - }, - "rename": { - "anyOf": [ - { - "$ref": "#/$defs/NesRenameCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the client supports the `rename` suggestion kind.", - "x-deserialize-default-on-error": true - }, - "searchAndReplace": { - "anyOf": [ - { - "$ref": "#/$defs/NesSearchAndReplaceCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the client supports the `searchAndReplace` suggestion kind.", - "x-deserialize-default-on-error": true - } - }, - "type": "object" - }, - "ClientNotification": { - "properties": { - "method": { - "type": "string" - }, - "params": { - "anyOf": [ - { - "anyOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/CancelNotification" - } - ], - "description": "Cancels ongoing operations for a session.\n\nThis is a notification sent by the client to cancel an ongoing prompt turn.\n\nUpon receiving this notification, the Agent SHOULD:\n- Stop all language model requests as soon as possible\n- Abort all tool call invocations in progress\n- Send any pending `session/update` notifications\n- Respond to the original `session/prompt` request with `StopReason::Cancelled`\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", - "title": "CancelNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DidOpenDocumentNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a file is opened in the editor.", - "title": "DidOpenDocumentNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DidChangeDocumentNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a file is edited.", - "title": "DidChangeDocumentNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DidCloseDocumentNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a file is closed.", - "title": "DidCloseDocumentNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DidSaveDocumentNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a file is saved.", - "title": "DidSaveDocumentNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DidFocusDocumentNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a file becomes the active editor tab.", - "title": "DidFocusDocumentNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/AcceptNesNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a suggestion is accepted.", - "title": "AcceptNesNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/RejectNesNotification" - } - ], - "description": "**UNSTABLE**\n\nNotification sent when a suggestion is rejected.", - "title": "RejectNesNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/MessageMcpNotification" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSends an MCP-over-ACP notification.", - "title": "MessageMcpNotification" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ExtNotification" - } - ], - "description": "Handles extension notifications from the client.\n\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "title": "ExtNotification" - } - ], - "description": "All possible notifications that a client can send to an agent.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response." - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "method" - ], - "type": "object", - "x-docs-ignore": true - }, - "ClientRequest": { - "properties": { - "id": { - "$ref": "#/$defs/RequestId" - }, - "method": { - "type": "string" - }, - "params": { - "anyOf": [ - { - "anyOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/InitializeRequest" - } - ], - "description": "Establishes the connection with a client and negotiates protocol capabilities.\n\nThis method is called once at the beginning of the connection to:\n- Negotiate the protocol version to use\n- Exchange capability information between client and agent\n- Determine available authentication methods\n\nThe agent should respond with its supported protocol version and capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", - "title": "InitializeRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/AuthenticateRequest" - } - ], - "description": "Authenticates the client using the specified authentication method.\n\nCalled when the agent requires authentication before allowing session creation.\nThe client provides the authentication method ID that was advertised during initialization.\n\nAfter successful authentication, the client can proceed to create sessions with\n`new_session` without receiving an `auth_required` error.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", - "title": "AuthenticateRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ListProvidersRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists providers that can be configured by the client.", - "title": "ListProvidersRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetProviderRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReplaces the configuration for a provider.", - "title": "SetProviderRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DisableProviderRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDisables a provider.", - "title": "DisableProviderRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/LogoutRequest" - } - ], - "description": "Logs out of the current authenticated state.\n\nAfter a successful logout, all new sessions will require authentication.\nThere is no guarantee about the behavior of already running sessions.", - "title": "LogoutRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/NewSessionRequest" - } - ], - "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)", - "title": "NewSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/LoadSessionRequest" - } - ], - "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", - "title": "LoadSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ListSessionsRequest" - } - ], - "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", - "title": "ListSessionsRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DeleteSessionRequest" - } - ], - "description": "Deletes an existing session from `session/list`.\n\nThis method is only available if the agent advertises the `sessionCapabilities.delete` capability.", - "title": "DeleteSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ForkSessionRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForks an existing session to create a new independent session.\n\nThis method is only available if the agent advertises the `session.fork` capability.\n\nThe agent should create a new session with the same conversation context as the\noriginal, allowing operations like generating summaries without affecting the\noriginal session's history.", - "title": "ForkSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ResumeSessionRequest" - } - ], - "description": "Resumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `sessionCapabilities.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", - "title": "ResumeSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CloseSessionRequest" - } - ], - "description": "Closes an active session and frees up any resources associated with it.\n\nThis method is only available if the agent advertises the `sessionCapabilities.close` capability.\n\nThe agent must cancel any ongoing work (as if `session/cancel` was called)\nand then free up any resources associated with the session.", - "title": "CloseSessionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionModeRequest" - } - ], - "description": "Sets the current mode for a session.\n\nAllows switching between different agent modes (e.g., \"ask\", \"architect\", \"code\")\nthat affect system prompts, tool availability, and permission behaviors.\n\nThe mode must be one of the modes advertised in `availableModes` during session\ncreation or loading. Agents may also change modes autonomously and notify the\nclient via `current_mode_update` notifications.\n\nThis method can be called at any time during a session, whether the Agent is\nidle or actively generating a response.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", - "title": "SetSessionModeRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SetSessionConfigOptionRequest" - } - ], - "description": "Sets the current value for a session configuration option.", - "title": "SetSessionConfigOptionRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/PromptRequest" - } - ], - "description": "Processes a user prompt within a session.\n\nThis method handles the whole lifecycle of a prompt:\n- Receives user messages with optional context (files, images, etc.)\n- Processes the prompt using language models\n- Reports language model content and tool calls to the Clients\n- Requests permission to run tools\n- Executes any requested tool calls\n- Returns when the turn is complete with a stop reason\n\nSee protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)", - "title": "PromptRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/StartNesRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nStarts an NES session.", - "title": "StartNesRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SuggestNesRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests a code suggestion.", - "title": "SuggestNesRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CloseNesRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active NES session and frees up any resources associated with it.\n\nThe agent must cancel any ongoing work and then free up any resources\nassociated with the NES session.", - "title": "CloseNesRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/MessageMcpRequest" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", - "title": "MessageMcpRequest" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ExtRequest" - } - ], - "description": "Handles extension method requests from the client.\n\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "title": "ExtMethodRequest" - } - ], - "description": "All possible requests that a client can send to an agent.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from client to agent." - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id", - "method" - ], - "type": "object", - "x-docs-ignore": true - }, - "ClientResponse": { - "anyOf": [ - { - "properties": { - "id": { - "$ref": "#/$defs/RequestId" - }, - "result": { - "anyOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/WriteTextFileResponse" - } - ], - "title": "WriteTextFileResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ReadTextFileResponse" - } - ], - "title": "ReadTextFileResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/RequestPermissionResponse" - } - ], - "title": "RequestPermissionResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CreateTerminalResponse" - } - ], - "title": "CreateTerminalResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/TerminalOutputResponse" - } - ], - "title": "TerminalOutputResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ReleaseTerminalResponse" - } - ], - "title": "ReleaseTerminalResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/WaitForTerminalExitResponse" - } - ], - "title": "WaitForTerminalExitResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/KillTerminalResponse" - } - ], - "title": "KillTerminalResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/CreateElicitationResponse" - } - ], - "title": "CreateElicitationResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ConnectMcpResponse" - } - ], - "title": "ConnectMcpResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/DisconnectMcpResponse" - } - ], - "title": "DisconnectMcpResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ExtResponse" - } - ], - "title": "ExtMethodResponse" - }, - { - "allOf": [ - { - "$ref": "#/$defs/MessageMcpResponse" - } - ], - "title": "MessageMcpResponse" - } - ], - "description": "All possible responses that a client can send to an agent.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `AgentRequest` variants." + { + "$ref": "#/$defs/TextContent" + } + ] + }, + { + "description": "Images for visual context or analysis.\n\nRequires the `image` prompt capability when included in prompts.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "image" } }, "required": [ - "id", - "result" + "type" ], - "title": "Result", - "type": "object" + "allOf": [ + { + "$ref": "#/$defs/ImageContent" + } + ] }, { + "description": "Audio data for transcription or analysis.\n\nRequires the `audio` prompt capability when included in prompts.", + "type": "object", "properties": { - "error": { - "$ref": "#/$defs/Error" - }, - "id": { - "$ref": "#/$defs/RequestId" + "type": { + "type": "string", + "const": "audio" } }, "required": [ - "id", - "error" + "type" ], - "title": "Error", - "type": "object" - } - ], - "x-docs-ignore": true - }, - "CloseNesRequest": { - "description": "Request to close an NES session.\n\nThe agent **must** cancel any ongoing work related to the NES session\nand then free up any resources associated with the session.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "allOf": [ + { + "$ref": "#/$defs/AudioContent" + } ] }, - "sessionId": { + { + "description": "References to resources that the agent can access.\n\nAll agents MUST support resource links in prompts.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "resource_link" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/ResourceLink" } + ] + }, + { + "description": "Complete resource contents embedded directly in the message.\n\nPreferred for including context as it avoids extra round-trips.\n\nRequires the `embeddedContext` prompt capability when included in prompts.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "resource" + } + }, + "required": [ + "type" ], - "description": "The ID of the NES session to close." + "allOf": [ + { + "$ref": "#/$defs/EmbeddedResource" + } + ] } - }, - "required": [ - "sessionId" ], - "type": "object", - "x-method": "nes/close", - "x-side": "agent" + "discriminator": { + "propertyName": "type" + } }, - "CloseNesResponse": { - "description": "Response from closing an NES session.", + "Annotations": { + "description": "Optional annotations for the client. The client can use annotations to inform how objects are used or displayed", + "type": "object", "properties": { + "audience": { + "description": "Intended recipients for this content, such as the user or assistant.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/$defs/Role" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "lastModified": { + "description": "Timestamp indicating when the underlying resource was last modified.", + "type": [ + "string", + "null" + ] + }, + "priority": { + "description": "Relative importance of this content when clients choose what to surface.", + "type": [ + "number", + "null" + ], + "format": "double" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "nes/close", - "x-side": "agent" + } }, - "CloseSessionRequest": { - "description": "Request parameters for closing an active session.\n\nIf supported, the agent **must** cancel any ongoing work related to the session\n(treat it as if `session/cancel` was called) and then free up any resources\nassociated with the session.\n\nOnly available if the Agent supports the `sessionCapabilities.close` capability.", + "Role": { + "description": "The sender or recipient of messages and data in a conversation.", + "oneOf": [ + { + "description": "The assistant side of a conversation.", + "type": "string", + "const": "assistant" + }, + { + "description": "The user side of a conversation.", + "type": "string", + "const": "user" + } + ] + }, + "TextContent": { + "description": "Text provided to or from an LLM.", + "type": "object", "properties": { + "annotations": { + "description": "Optional annotations that help clients decide how to display or route this content.", + "anyOf": [ + { + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "text": { + "description": "Text payload carried by this content block.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The ID of the session to close." + "additionalProperties": true } }, "required": [ - "sessionId" - ], - "type": "object", - "x-method": "session/close", - "x-side": "agent" + "text" + ] }, - "CloseSessionResponse": { - "description": "Response from closing a session.", + "ImageContent": { + "description": "An image provided to or from an LLM.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "annotations": { + "description": "Optional annotations that help clients decide how to display or route this content.", + "anyOf": [ + { + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "data": { + "description": "Base64-encoded media payload.", + "type": "string" + }, + "mimeType": { + "description": "MIME type describing the encoded media payload.", + "type": "string" + }, + "uri": { + "description": "URI associated with this resource or media payload.", "type": [ - "object", + "string", "null" ] - } - }, - "type": "object", - "x-method": "session/close", - "x-side": "agent" - }, - "CompleteElicitationNotification": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification sent by the agent when a URL-based elicitation is complete.", - "properties": { + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "elicitationId": { - "allOf": [ - { - "$ref": "#/$defs/ElicitationId" - } ], - "description": "The ID of the elicitation that completed." + "additionalProperties": true } }, "required": [ - "elicitationId" - ], - "type": "object", - "x-method": "elicitation/complete", - "x-side": "client" + "data", + "mimeType" + ] }, - "ConfigOptionUpdate": { - "description": "Session configuration options have been updated.", + "AudioContent": { + "description": "Audio provided to or from an LLM.", + "type": "object", "properties": { + "annotations": { + "description": "Optional annotations that help clients decide how to display or route this content.", + "anyOf": [ + { + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "data": { + "description": "Base64-encoded media payload.", + "type": "string" + }, + "mimeType": { + "description": "MIME type describing the encoded media payload.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "configOptions": { - "description": "The full set of configuration options and their current values.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + ], + "additionalProperties": true } }, "required": [ - "configOptions" - ], - "type": "object" + "data", + "mimeType" + ] }, - "ConnectMcpRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/connect`.", + "ResourceLink": { + "description": "A resource that the server is capable of reading, included in a prompt or tool call result.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "annotations": { + "description": "Optional annotations that help clients decide how to display or route this content.", + "anyOf": [ + { + "$ref": "#/$defs/Annotations" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "description": { + "description": "Optional human-readable details shown with this protocol object.", + "type": [ + "string", + "null" + ] + }, + "mimeType": { + "description": "MIME type describing the encoded media payload.", "type": [ - "object", + "string", "null" ] }, - "acpId": { - "allOf": [ - { - "$ref": "#/$defs/McpServerAcpId" - } + "name": { + "description": "Human-readable name shown for this protocol object.", + "type": "string" + }, + "size": { + "description": "Optional size of the linked resource in bytes, if known.", + "type": [ + "integer", + "null" ], - "description": "The ACP MCP server ID that was provided by the component declaring the MCP server." - } - }, - "required": [ - "acpId" - ], - "type": "object", - "x-method": "mcp/connect", - "x-side": "client" - }, - "ConnectMcpResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/connect`.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "format": "int64" + }, + "title": { + "description": "Optional display title for end-user UI.", "type": [ - "object", + "string", "null" ] }, - "connectionId": { - "allOf": [ - { - "$ref": "#/$defs/McpConnectionId" - } - ], - "description": "The unique identifier for this MCP-over-ACP connection." - } - }, - "required": [ - "connectionId" - ], - "type": "object", - "x-method": "mcp/connect", - "x-side": "client" - }, - "Content": { - "description": "Standard content block (text, images, resources).", - "properties": { + "uri": { + "description": "URI associated with this resource or media payload.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "content": { - "allOf": [ - { - "$ref": "#/$defs/ContentBlock" - } ], - "description": "The actual content block." + "additionalProperties": true } }, "required": [ - "content" - ], - "type": "object" + "name", + "uri" + ] }, - "ContentBlock": { - "description": "Content blocks represent displayable information in the Agent Client Protocol.\n\nThey provide a structured way to handle various types of user-facing content\u2014whether\nit's text from language models, images for analysis, or embedded resources for context.\n\nContent blocks appear in:\n- User prompts sent via `session/prompt`\n- Language model output streamed through `session/update` notifications\n- Progress updates and results from tool calls\n\nThis structure is compatible with the Model Context Protocol (MCP), enabling\nagents to seamlessly forward content from MCP tool outputs without transformation.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/content)", - "discriminator": { - "propertyName": "type" - }, - "oneOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/TextContent" - } - ], - "description": "Text content. May be plain text or formatted with Markdown.\n\nAll agents MUST support text content blocks in prompts.\nClients SHOULD render this text as Markdown.", - "properties": { - "type": { - "const": "text", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ImageContent" - } - ], - "description": "Images for visual context or analysis.\n\nRequires the `image` prompt capability when included in prompts.", - "properties": { - "type": { - "const": "image", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/AudioContent" - } - ], - "description": "Audio data for transcription or analysis.\n\nRequires the `audio` prompt capability when included in prompts.", - "properties": { - "type": { - "const": "audio", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, + "EmbeddedResourceResource": { + "description": "Resource content that can be embedded in a message.", + "anyOf": [ { + "title": "TextResourceContents", + "description": "Text resource contents embedded directly in the message.", "allOf": [ { - "$ref": "#/$defs/ResourceLink" - } - ], - "description": "References to resources that the agent can access.\n\nAll agents MUST support resource links in prompts.", - "properties": { - "type": { - "const": "resource_link", - "type": "string" + "$ref": "#/$defs/TextResourceContents" } - }, - "required": [ - "type" - ], - "type": "object" + ] }, { + "title": "BlobResourceContents", + "description": "Binary resource contents embedded directly in the message.", "allOf": [ { - "$ref": "#/$defs/EmbeddedResource" - } - ], - "description": "Complete resource contents embedded directly in the message.\n\nPreferred for including context as it avoids extra round-trips.\n\nRequires the `embeddedContext` prompt capability when included in prompts.", - "properties": { - "type": { - "const": "resource", - "type": "string" + "$ref": "#/$defs/BlobResourceContents" } - }, - "required": [ - "type" - ], - "type": "object" + ] } ] }, - "ContentChunk": { - "description": "A streamed item of content", + "TextResourceContents": { + "description": "Text-based resource contents.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "mimeType": { + "description": "MIME type describing the encoded media payload.", "type": [ - "object", + "string", "null" ] }, - "content": { - "allOf": [ - { - "$ref": "#/$defs/ContentBlock" - } - ], - "description": "A single item of content" + "text": { + "description": "Text payload carried by this content block.", + "type": "string" }, - "messageId": { - "anyOf": [ - { - "$ref": "#/$defs/MessageId" - }, - { - "type": "null" - } + "uri": { + "description": "URI associated with this resource or media payload.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started." + "additionalProperties": true } }, "required": [ - "content" - ], - "type": "object" + "text", + "uri" + ] }, - "Cost": { - "description": "Cost information for a session.", + "BlobResourceContents": { + "description": "Binary resource contents.", + "type": "object", "properties": { - "amount": { - "description": "Total cumulative cost for session.", - "format": "double", - "type": "number" + "blob": { + "description": "Base64-encoded bytes for a binary resource payload.", + "type": "string" }, - "currency": { - "description": "ISO 4217 currency code (e.g., \"USD\", \"EUR\").", + "mimeType": { + "description": "MIME type describing the encoded media payload.", + "type": [ + "string", + "null" + ] + }, + "uri": { + "description": "URI associated with this resource or media payload.", "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "amount", - "currency" - ], - "type": "object" + "blob", + "uri" + ] }, - "CreateElicitationRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest from the agent to elicit structured user input.\n\nThe agent sends this to the client to request information from the user,\neither via a form or by directing them to a URL.\nElicitations are tied to a session (optionally a tool call) or a request.", - "discriminator": { - "propertyName": "mode" - }, - "oneOf": [ - { - "allOf": [ + "EmbeddedResource": { + "description": "The contents of a resource, embedded into a prompt or tool call result.", + "type": "object", + "properties": { + "annotations": { + "description": "Optional annotations that help clients decide how to display or route this content.", + "anyOf": [ { - "$ref": "#/$defs/ElicitationFormMode" - } - ], - "description": "Form-based elicitation where the client renders a form from the provided schema.", - "properties": { - "mode": { - "const": "form", - "type": "string" - } - }, - "required": [ - "mode" - ], - "type": "object" - }, - { - "allOf": [ + "$ref": "#/$defs/Annotations" + }, { - "$ref": "#/$defs/ElicitationUrlMode" - } - ], - "description": "URL-based elicitation where the client directs the user to a URL.", - "properties": { - "mode": { - "const": "url", - "type": "string" + "type": "null" } - }, - "required": [ - "mode" ], - "type": "object" - } - ], - "properties": { + "x-deserialize-default-on-error": true + }, + "resource": { + "description": "Embedded resource payload, either text or binary data.", + "allOf": [ + { + "$ref": "#/$defs/EmbeddedResourceResource" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "message": { - "description": "A human-readable message describing what input is needed.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "message" - ], - "type": "object", - "x-method": "elicitation/create", - "x-side": "client" + "resource" + ] }, - "CreateElicitationResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from the client to an elicitation request.", - "discriminator": { - "propertyName": "action" - }, - "oneOf": [ - { + "Content": { + "description": "Standard content block (text, images, resources).", + "type": "object", + "properties": { + "content": { + "description": "The actual content block.", "allOf": [ { - "$ref": "#/$defs/ElicitationAcceptAction" - } - ], - "description": "The user accepted and provided content.", - "properties": { - "action": { - "const": "accept", - "type": "string" - } - }, - "required": [ - "action" - ], - "type": "object" - }, - { - "description": "The user declined the elicitation.", - "properties": { - "action": { - "const": "decline", - "type": "string" + "$ref": "#/$defs/ContentBlock" } - }, - "required": [ - "action" - ], - "type": "object" + ] }, - { - "description": "The elicitation was cancelled.", - "properties": { - "action": { - "const": "cancel", - "type": "string" - } - }, - "required": [ - "action" - ], - "type": "object" - } - ], - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "elicitation/create", - "x-side": "client" + "required": [ + "content" + ] }, - "CreateTerminalRequest": { - "description": "Request to create a new terminal and execute a command.", + "Diff": { + "description": "A diff representing file modifications.\n\nShows changes to files in a format suitable for display in the client UI.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "args": { - "description": "Array of command arguments.", - "items": { - "type": "string" - }, - "type": "array" - }, - "command": { - "description": "The command to execute.", + "path": { + "description": "The file path being modified.", "type": "string" }, - "cwd": { - "description": "Working directory for the command (absolute path).", + "oldText": { + "description": "The original content (None for new files).", "type": [ "string", "null" ] }, - "env": { - "description": "Environment variables for the command.", - "items": { - "$ref": "#/$defs/EnvVariable" - }, - "type": "array" + "newText": { + "description": "The new content after modification.", + "type": "string" }, - "outputByteLimit": { - "description": "Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", - "format": "uint64", - "minimum": 0, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for this request." + "additionalProperties": true } }, "required": [ - "sessionId", - "command" - ], - "type": "object", - "x-method": "terminal/create", - "x-side": "client" + "path", + "newText" + ] }, - "CreateTerminalResponse": { - "description": "Response containing the ID of the created terminal.", + "TerminalId": { + "description": "Typed identifier used for terminal values on the wire.", + "type": "string" + }, + "Terminal": { + "description": "Embed a terminal created with `terminal/create` by its id.\n\nThe terminal must be added before calling `terminal/release`.\n\nSee protocol docs: [Terminal](https://agentclientprotocol.com/protocol/terminals)", + "type": "object", "properties": { + "terminalId": { + "description": "Identifier of the terminal instance to embed in the content stream.", + "allOf": [ + { + "$ref": "#/$defs/TerminalId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "terminalId": { - "description": "The unique identifier for the created terminal.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ "terminalId" - ], - "type": "object", - "x-method": "terminal/create", - "x-side": "client" + ] }, - "CurrentModeUpdate": { - "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "ToolCallLocation": { + "description": "A file location being accessed or modified by a tool.\n\nEnables clients to implement \"follow-along\" features that track\nwhich files the agent is working with in real-time.\n\nSee protocol docs: [Following the Agent](https://agentclientprotocol.com/protocol/tool-calls#following-the-agent)", + "type": "object", "properties": { + "path": { + "description": "The file path being accessed or modified.", + "type": "string" + }, + "line": { + "description": "Optional line number within the file.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "path" + ] + }, + "PermissionOption": { + "description": "An option presented to the user when requesting permission.", + "type": "object", + "properties": { + "optionId": { + "description": "Unique identifier for this permission option.", + "allOf": [ + { + "$ref": "#/$defs/PermissionOptionId" + } ] }, - "currentModeId": { + "name": { + "description": "Human-readable label to display to the user.", + "type": "string" + }, + "kind": { + "description": "Hint about the nature of this permission option.", "allOf": [ { - "$ref": "#/$defs/SessionModeId" + "$ref": "#/$defs/PermissionOptionKind" } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the current mode" + "additionalProperties": true } }, "required": [ - "currentModeId" - ], - "type": "object" + "optionId", + "name", + "kind" + ] }, - "DeleteSessionRequest": { - "description": "Request parameters for deleting an existing session from `session/list`.\n\nOnly available if the Agent supports the `sessionCapabilities.delete` capability.", + "PermissionOptionId": { + "description": "Unique identifier for a permission option.", + "type": "string" + }, + "PermissionOptionKind": { + "description": "The type of permission option being presented to the user.\n\nHelps clients choose appropriate icons and UI treatment.", + "oneOf": [ + { + "description": "Allow this operation only this time.", + "type": "string", + "const": "allow_once" + }, + { + "description": "Allow this operation and remember the choice.", + "type": "string", + "const": "allow_always" + }, + { + "description": "Reject this operation only this time.", + "type": "string", + "const": "reject_once" + }, + { + "description": "Reject this operation and remember the choice.", + "type": "string", + "const": "reject_always" + } + ] + }, + "CreateTerminalRequest": { + "description": "Request to create a new terminal and execute a command.", + "type": "object", "properties": { + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, + "command": { + "description": "The command to execute.", + "type": "string" + }, + "args": { + "description": "Array of command arguments.", + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "description": "Environment variables for the command.", + "type": "array", + "items": { + "$ref": "#/$defs/EnvVariable" + } + }, + "cwd": { + "description": "Working directory for the command (absolute path).", + "type": [ + "string", + "null" + ] + }, + "outputByteLimit": { + "description": "Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0 + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The ID of the session to delete." + "additionalProperties": true } }, "required": [ - "sessionId" + "sessionId", + "command" ], - "type": "object", - "x-method": "session/delete", - "x-side": "agent" + "x-side": "client", + "x-method": "terminal/create" }, - "DeleteSessionResponse": { - "description": "Response from deleting a session.", + "EnvVariable": { + "description": "An environment variable to set when launching an MCP server.", + "type": "object", "properties": { + "name": { + "description": "The name of the environment variable.", + "type": "string" + }, + "value": { + "description": "The value to set for the environment variable.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "session/delete", - "x-side": "agent" + "required": [ + "name", + "value" + ] }, - "DidChangeDocumentNotification": { - "description": "Notification sent when a file is edited.", + "TerminalOutputRequest": { + "description": "Request to get the current output and status of a terminal.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "contentChanges": { - "description": "The content changes.", - "items": { - "$ref": "#/$defs/TextDocumentContentChangeEvent" - }, - "type": "array" - }, "sessionId": { + "description": "The session ID for this request.", "allOf": [ { "$ref": "#/$defs/SessionId" } - ], - "description": "The session ID for this notification." + ] }, - "uri": { - "description": "The URI of the changed document.", - "type": "string" + "terminalId": { + "description": "The ID of the terminal to get output from.", + "allOf": [ + { + "$ref": "#/$defs/TerminalId" + } + ] }, - "version": { - "description": "The new version number of the document.", - "format": "int64", - "type": "integer" - } - }, - "required": [ - "sessionId", - "uri", - "version", - "contentChanges" - ], - "type": "object", - "x-method": "document/didChange", - "x-side": "agent" - }, - "DidCloseDocumentNotification": { - "description": "Notification sent when a file is closed.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for this notification." - }, - "uri": { - "description": "The URI of the closed document.", - "type": "string" + "additionalProperties": true } }, "required": [ "sessionId", - "uri" + "terminalId" ], - "type": "object", - "x-method": "document/didClose", - "x-side": "agent" + "x-side": "client", + "x-method": "terminal/output" }, - "DidFocusDocumentNotification": { - "description": "Notification sent when a file becomes the active editor tab.", + "ReleaseTerminalRequest": { + "description": "Request to release a terminal and free its resources.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "position": { - "allOf": [ - { - "$ref": "#/$defs/Position" - } - ], - "description": "The current cursor position." - }, "sessionId": { + "description": "The session ID for this request.", "allOf": [ { "$ref": "#/$defs/SessionId" } - ], - "description": "The session ID for this notification." - }, - "uri": { - "description": "The URI of the focused document.", - "type": "string" - }, - "version": { - "description": "The version number of the document.", - "format": "int64", - "type": "integer" + ] }, - "visibleRange": { + "terminalId": { + "description": "The ID of the terminal to release.", "allOf": [ { - "$ref": "#/$defs/Range" + "$ref": "#/$defs/TerminalId" } - ], - "description": "The portion of the file currently visible in the editor viewport." - } - }, - "required": [ - "sessionId", - "uri", - "version", - "position", - "visibleRange" - ], - "type": "object", - "x-method": "document/didFocus", - "x-side": "agent" - }, - "DidOpenDocumentNotification": { - "description": "Notification sent when a file is opened in the editor.", - "properties": { + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "languageId": { - "description": "The language identifier of the document (e.g., \"rust\", \"python\").", - "type": "string" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for this notification." - }, - "text": { - "description": "The full text content of the document.", - "type": "string" - }, - "uri": { - "description": "The URI of the opened document.", - "type": "string" - }, - "version": { - "description": "The version number of the document.", - "format": "int64", - "type": "integer" + "additionalProperties": true } }, "required": [ "sessionId", - "uri", - "languageId", - "version", - "text" + "terminalId" ], - "type": "object", - "x-method": "document/didOpen", - "x-side": "agent" + "x-side": "client", + "x-method": "terminal/release" }, - "DidSaveDocumentNotification": { - "description": "Notification sent when a file is saved.", + "WaitForTerminalExitRequest": { + "description": "Request to wait for a terminal command to exit.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, "sessionId": { + "description": "The session ID for this request.", "allOf": [ { "$ref": "#/$defs/SessionId" } - ], - "description": "The session ID for this notification." - }, - "uri": { - "description": "The URI of the saved document.", - "type": "string" - } - }, - "required": [ - "sessionId", - "uri" - ], - "type": "object", - "x-method": "document/didSave", - "x-side": "agent" - }, - "Diff": { - "description": "A diff representing file modifications.\n\nShows changes to files in a format suitable for display in the client UI.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "newText": { - "description": "The new content after modification.", - "type": "string" - }, - "oldText": { - "description": "The original content (None for new files).", - "type": [ - "string", - "null" ] }, - "path": { - "description": "The file path being modified.", - "type": "string" - } - }, - "required": [ - "path", - "newText" - ], - "type": "object" - }, - "DisableProviderRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/disable`.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "terminalId": { + "description": "The ID of the terminal to wait for.", + "allOf": [ + { + "$ref": "#/$defs/TerminalId" + } ] }, - "id": { - "description": "Provider id to disable.", - "type": "string" - } - }, - "required": [ - "id" - ], - "type": "object", - "x-method": "providers/disable", - "x-side": "agent" - }, - "DisableProviderResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/disable`.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "providers/disable", - "x-side": "agent" + "required": [ + "sessionId", + "terminalId" + ], + "x-side": "client", + "x-method": "terminal/wait_for_exit" }, - "DisconnectMcpRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/disconnect`.", + "KillTerminalRequest": { + "description": "Request to kill a terminal without releasing it.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "connectionId": { + "terminalId": { + "description": "The ID of the terminal to kill.", "allOf": [ { - "$ref": "#/$defs/McpConnectionId" + "$ref": "#/$defs/TerminalId" } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The MCP-over-ACP connection to close." + "additionalProperties": true } }, "required": [ - "connectionId" + "sessionId", + "terminalId" ], - "type": "object", - "x-method": "mcp/disconnect", - "x-side": "client" + "x-side": "client", + "x-method": "terminal/kill" }, - "DisconnectMcpResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/disconnect`.", + "CreateElicitationRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest from the agent to elicit structured user input.\n\nThe agent sends this to the client to request information from the user,\neither via a form or by directing them to a URL.\nElicitations are tied to a session (optionally a tool call) or a request.", + "type": "object", "properties": { + "message": { + "description": "A human-readable message describing what input is needed.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "mcp/disconnect", - "x-side": "client" - }, - "ElicitationAcceptAction": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe user accepted the elicitation and provided content.", - "properties": { - "content": { - "additionalProperties": { - "$ref": "#/$defs/ElicitationContentValue" + "oneOf": [ + { + "description": "Form-based elicitation where the client renders a form from the provided schema.", + "type": "object", + "properties": { + "mode": { + "type": "string", + "const": "form" + } }, - "description": "The user-provided content, if any, as an object matching the requested schema.", - "type": [ - "object", - "null" + "required": [ + "mode" + ], + "allOf": [ + { + "$ref": "#/$defs/ElicitationFormMode" + } + ] + }, + { + "description": "URL-based elicitation where the client directs the user to a URL.", + "type": "object", + "properties": { + "mode": { + "type": "string", + "const": "url" + } + }, + "required": [ + "mode" + ], + "allOf": [ + { + "$ref": "#/$defs/ElicitationUrlMode" + } ] } + ], + "discriminator": { + "propertyName": "mode" }, - "type": "object" + "required": [ + "message" + ], + "x-side": "client", + "x-method": "elicitation/create" }, - "ElicitationCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.", + "ElicitationSessionScope": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-scoped elicitation, optionally tied to a specific tool call.\n\nWhen `tool_call_id` is set, the elicitation is tied to a specific tool call.\nThis is useful when an agent receives an elicitation from an MCP server\nduring a tool call and needs to redirect it to the user.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "form": { - "anyOf": [ - { - "$ref": "#/$defs/ElicitationFormCapabilities" - }, + "sessionId": { + "description": "The session this elicitation is tied to.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionId" } - ], - "description": "Whether the client supports form-based elicitation.", - "x-deserialize-default-on-error": true + ] }, - "url": { + "toolCallId": { + "description": "Optional tool call within the session.", "anyOf": [ { - "$ref": "#/$defs/ElicitationUrlCapabilities" + "$ref": "#/$defs/ToolCallId" }, { "type": "null" } - ], - "description": "Whether the client supports URL-based elicitation.", - "x-deserialize-default-on-error": true + ] } }, - "type": "object" - }, - "ElicitationContentValue": { - "anyOf": [ - { - "title": "String", - "type": "string" - }, - { - "format": "int64", - "title": "Integer", - "type": "integer" - }, - { - "format": "double", - "title": "Number", - "type": "number" - }, - { - "title": "Boolean", - "type": "boolean" - }, - { - "items": { - "type": "string" - }, - "title": "StringArray", - "type": "array" - } + "required": [ + "sessionId" ] }, - "ElicitationFormCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation capabilities.", + "ElicitationRequestScope": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest-scoped elicitation, tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "requestId": { + "description": "The request this elicitation is tied to.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } ] } }, - "type": "object" + "required": [ + "requestId" + ] }, - "ElicitationFormMode": { - "anyOf": [ - { + "ElicitationSchema": { + "description": "Type-safe elicitation schema for requesting structured user input.\n\nThis represents a JSON Schema object with primitive-typed properties,\nas required by the elicitation specification.", + "type": "object", + "properties": { + "type": { + "description": "Type discriminator. Always `\"object\"`.", + "default": "object", "allOf": [ { - "$ref": "#/$defs/ElicitationSessionScope" + "$ref": "#/$defs/ElicitationSchemaType" } - ], - "description": "Tied to a session, optionally to a specific tool call within that session.", - "title": "Session" + ] }, - { - "allOf": [ - { - "$ref": "#/$defs/ElicitationRequestScope" - } + "title": { + "description": "Optional title for the schema.", + "type": [ + "string", + "null" + ] + }, + "properties": { + "description": "Property definitions (must be primitive types).", + "type": "object", + "default": {}, + "additionalProperties": { + "$ref": "#/$defs/ElicitationPropertySchema" + } + }, + "required": { + "description": "List of required property names.", + "type": [ + "array", + "null" ], - "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", - "title": "Request" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema.", - "properties": { - "requestedSchema": { - "allOf": [ - { - "$ref": "#/$defs/ElicitationSchema" - } + "items": { + "type": "string" + } + }, + "description": { + "description": "Optional description of what this schema represents.", + "type": [ + "string", + "null" + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "A JSON Schema describing the form fields to present to the user." + "additionalProperties": true } - }, - "required": [ - "requestedSchema" - ], - "type": "object" - }, - "ElicitationId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an elicitation.", - "type": "string" + } }, - "ElicitationPropertySchema": { - "description": "Property schema for elicitation form fields.\n\nEach variant corresponds to a JSON Schema `\"type\"` value.\nSingle-select enums use the `String` variant with `enum` or `oneOf` set.\nMulti-select enums use the `Array` variant.", - "discriminator": { - "propertyName": "type" - }, + "ElicitationSchemaType": { + "description": "Type discriminator for elicitation schemas.", + "oneOf": [ + { + "description": "Object schema type.", + "type": "string", + "const": "object" + } + ] + }, + "ElicitationPropertySchema": { + "description": "Property schema for elicitation form fields.\n\nEach variant corresponds to a JSON Schema `\"type\"` value.\nSingle-select enums use the `String` variant with `enum` or `oneOf` set.\nMulti-select enums use the `Array` variant.", "oneOf": [ { - "allOf": [ - { - "$ref": "#/$defs/StringPropertySchema" - } - ], "description": "String property (or single-select enum when `enum`/`oneOf` is set).", + "type": "object", "properties": { "type": { - "const": "string", - "type": "string" + "type": "string", + "const": "string" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/NumberPropertySchema" + "$ref": "#/$defs/StringPropertySchema" } - ], + ] + }, + { "description": "Number (floating-point) property.", + "type": "object", "properties": { "type": { - "const": "number", - "type": "string" + "type": "string", + "const": "number" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/IntegerPropertySchema" + "$ref": "#/$defs/NumberPropertySchema" } - ], + ] + }, + { "description": "Integer property.", + "type": "object", "properties": { "type": { - "const": "integer", - "type": "string" + "type": "string", + "const": "integer" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/BooleanPropertySchema" + "$ref": "#/$defs/IntegerPropertySchema" } - ], + ] + }, + { "description": "Boolean property.", + "type": "object", "properties": { "type": { - "const": "boolean", - "type": "string" + "type": "string", + "const": "boolean" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/MultiSelectPropertySchema" + "$ref": "#/$defs/BooleanPropertySchema" } - ], + ] + }, + { "description": "Multi-select array property.", + "type": "object", "properties": { "type": { - "const": "array", - "type": "string" + "type": "string", + "const": "array" } }, "required": [ "type" ], - "type": "object" + "allOf": [ + { + "$ref": "#/$defs/MultiSelectPropertySchema" + } + ] + } + ], + "discriminator": { + "propertyName": "type" + } + }, + "StringFormat": { + "description": "String format types for string properties in elicitation schemas.", + "oneOf": [ + { + "description": "Email address format.", + "type": "string", + "const": "email" + }, + { + "description": "URI format.", + "type": "string", + "const": "uri" + }, + { + "description": "Date format (YYYY-MM-DD).", + "type": "string", + "const": "date" + }, + { + "description": "Date-time format (ISO 8601).", + "type": "string", + "const": "date-time" } ] }, - "ElicitationRequestScope": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest-scoped elicitation, tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", + "EnumOption": { + "description": "A titled enum option with a const value and human-readable title.", + "type": "object", "properties": { - "requestId": { - "allOf": [ + "const": { + "description": "The constant value for this option.", + "type": "string" + }, + "title": { + "description": "Human-readable title for this option.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "const", + "title" + ] + }, + "StringPropertySchema": { + "description": "Schema for string properties in an elicitation form.\n\nWhen `enum` or `oneOf` is set, this represents a single-select enum\nwith `\"type\": \"string\"`.", + "type": "object", + "properties": { + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "minLength": { + "description": "Minimum string length.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, + "maxLength": { + "description": "Maximum string length.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, + "pattern": { + "description": "Pattern the string must match.", + "type": [ + "string", + "null" + ] + }, + "format": { + "description": "String format.", + "anyOf": [ { - "$ref": "#/$defs/RequestId" + "$ref": "#/$defs/StringFormat" + }, + { + "type": "null" } + ] + }, + "default": { + "description": "Default value.", + "type": [ + "string", + "null" + ] + }, + "enum": { + "description": "Enum values for untitled single-select enums.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "oneOf": { + "description": "Titled enum options for titled single-select enums.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/$defs/EnumOption" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "NumberPropertySchema": { + "description": "Schema for number (floating-point) properties in an elicitation form.", + "type": "object", + "properties": { + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "minimum": { + "description": "Minimum value (inclusive).", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "maximum": { + "description": "Maximum value (inclusive).", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "default": { + "description": "Default value.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "IntegerPropertySchema": { + "description": "Schema for integer properties in an elicitation form.", + "type": "object", + "properties": { + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "minimum": { + "description": "Minimum value (inclusive).", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "maximum": { + "description": "Maximum value (inclusive).", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "default": { + "description": "Default value.", + "type": [ + "integer", + "null" + ], + "format": "int64" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The request this elicitation is tied to." + "additionalProperties": true } - }, - "required": [ - "requestId" - ], - "type": "object" + } }, - "ElicitationSchema": { - "description": "Type-safe elicitation schema for requesting structured user input.\n\nThis represents a JSON Schema object with primitive-typed properties,\nas required by the elicitation specification.", + "BooleanPropertySchema": { + "description": "Schema for boolean properties in an elicitation form.", + "type": "object", "properties": { - "description": { - "description": "Optional description of what this schema represents.", + "title": { + "description": "Optional title for the property.", "type": [ "string", "null" ] }, - "properties": { - "additionalProperties": { - "$ref": "#/$defs/ElicitationPropertySchema" - }, - "default": {}, - "description": "Property definitions (must be primitive types).", - "type": "object" - }, - "required": { - "description": "List of required property names.", - "items": { - "type": "string" - }, + "description": { + "description": "Human-readable description.", "type": [ - "array", + "string", "null" ] }, - "title": { - "description": "Optional title for the schema.", + "default": { + "description": "Default value.", "type": [ - "string", + "boolean", "null" ] }, - "type": { - "allOf": [ - { - "$ref": "#/$defs/ElicitationSchemaType" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "default": "object", - "description": "Type discriminator. Always `\"object\"`." + "additionalProperties": true } - }, - "type": "object" + } }, - "ElicitationSchemaType": { - "description": "Type discriminator for elicitation schemas.", - "oneOf": [ + "MultiSelectItems": { + "description": "Items for a multi-select (array) property schema.", + "anyOf": [ { - "const": "object", - "description": "Object schema type.", - "type": "string" + "title": "Untitled", + "description": "Untitled multi-select items with plain string values.", + "allOf": [ + { + "$ref": "#/$defs/UntitledMultiSelectItems" + } + ] + }, + { + "title": "Titled", + "description": "Titled multi-select items with human-readable labels.", + "allOf": [ + { + "$ref": "#/$defs/TitledMultiSelectItems" + } + ] } ] }, - "ElicitationSessionScope": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-scoped elicitation, optionally tied to a specific tool call.\n\nWhen `tool_call_id` is set, the elicitation is tied to a specific tool call.\nThis is useful when an agent receives an elicitation from an MCP server\nduring a tool call and needs to redirect it to the user.", + "UntitledMultiSelectItems": { + "description": "Items definition for untitled multi-select enum properties.", + "type": "object", "properties": { - "sessionId": { + "type": { + "description": "Item type discriminator. Must be `\"string\"`.", "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/ElicitationStringType" } - ], - "description": "The session this elicitation is tied to." + ] }, - "toolCallId": { - "anyOf": [ - { - "$ref": "#/$defs/ToolCallId" - }, - { - "type": "null" - } + "enum": { + "description": "Allowed enum values.", + "type": "array", + "items": { + "type": "string" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Optional tool call within the session." + "additionalProperties": true } }, "required": [ - "sessionId" - ], - "type": "object" + "type", + "enum" + ] }, "ElicitationStringType": { "description": "Items definition for untitled multi-select enum properties.", "oneOf": [ { - "const": "string", "description": "String schema type.", - "type": "string" + "type": "string", + "const": "string" } ] }, - "ElicitationUrlCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation capabilities.", + "TitledMultiSelectItems": { + "description": "Items definition for titled multi-select enum properties.", + "type": "object", "properties": { + "anyOf": { + "description": "Titled enum options.", + "type": "array", + "items": { + "$ref": "#/$defs/EnumOption" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "anyOf" + ] + }, + "MultiSelectPropertySchema": { + "description": "Schema for multi-select (array) properties in an elicitation form.", + "type": "object", + "properties": { + "title": { + "description": "Optional title for the property.", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ] + }, + "minItems": { + "description": "Minimum number of items to select.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0 + }, + "maxItems": { + "description": "Maximum number of items to select.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0 + }, + "items": { + "description": "The items definition describing allowed values.", + "allOf": [ + { + "$ref": "#/$defs/MultiSelectItems" + } ] + }, + "default": { + "description": "Default selected values.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "items" + ] }, - "ElicitationUrlMode": { + "ElicitationFormMode": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema.", + "type": "object", + "properties": { + "requestedSchema": { + "description": "A JSON Schema describing the form fields to present to the user.", + "allOf": [ + { + "$ref": "#/$defs/ElicitationSchema" + } + ] + } + }, "anyOf": [ { + "title": "Session", + "description": "Tied to a session, optionally to a specific tool call within that session.", "allOf": [ { "$ref": "#/$defs/ElicitationSessionScope" } - ], - "description": "Tied to a session, optionally to a specific tool call within that session.", - "title": "Session" + ] }, { + "title": "Request", + "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", "allOf": [ { "$ref": "#/$defs/ElicitationRequestScope" } - ], - "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", - "title": "Request" + ] } ], + "required": [ + "requestedSchema" + ] + }, + "ElicitationId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an elicitation.", + "type": "string" + }, + "ElicitationUrlMode": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL.", + "type": "object", "properties": { "elicitationId": { + "description": "The unique identifier for this elicitation.", "allOf": [ { "$ref": "#/$defs/ElicitationId" } - ], - "description": "The unique identifier for this elicitation." + ] }, "url": { "description": "The URL to direct the user to.", - "format": "uri", - "type": "string" - } - }, - "required": [ - "elicitationId", - "url" - ], - "type": "object" - }, - "EmbeddedResource": { - "description": "The contents of a resource, embedded into a prompt or tool call result.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/$defs/Annotations" - }, - { - "type": "null" - } - ], - "x-deserialize-default-on-error": true - }, - "resource": { - "$ref": "#/$defs/EmbeddedResourceResource" + "type": "string", + "format": "uri" } }, - "required": [ - "resource" - ], - "type": "object" - }, - "EmbeddedResourceResource": { "anyOf": [ { + "title": "Session", + "description": "Tied to a session, optionally to a specific tool call within that session.", "allOf": [ { - "$ref": "#/$defs/TextResourceContents" + "$ref": "#/$defs/ElicitationSessionScope" } - ], - "title": "TextResourceContents" + ] }, { + "title": "Request", + "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", "allOf": [ { - "$ref": "#/$defs/BlobResourceContents" + "$ref": "#/$defs/ElicitationRequestScope" } - ], - "title": "BlobResourceContents" + ] } ], - "description": "Resource content that can be embedded in a message." + "required": [ + "elicitationId", + "url" + ] }, - "EnumOption": { - "description": "A titled enum option with a const value and human-readable title.", + "ConnectMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/connect`.", + "type": "object", "properties": { - "const": { - "description": "The constant value for this option.", - "type": "string" + "acpId": { + "description": "The ACP MCP server ID that was provided by the component declaring the MCP server.", + "allOf": [ + { + "$ref": "#/$defs/McpServerAcpId" + } + ] }, - "title": { - "description": "Human-readable title for this option.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "const", - "title" + "acpId" ], - "type": "object" + "x-side": "client", + "x-method": "mcp/connect" }, - "EnvVariable": { - "description": "An environment variable to set when launching an MCP server.", + "McpServerAcpId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an MCP server using the ACP transport.\n\nThe value is opaque and generated by the ACP component providing the MCP server. It is\nused by `mcp/connect` to route connection requests back to the component that declared the\nserver.", + "type": "string" + }, + "MessageMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/message`.", + "type": "object", "properties": { + "connectionId": { + "description": "The MCP-over-ACP connection this message is sent on.", + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ] + }, + "method": { + "description": "The inner MCP method name.", + "type": "string" + }, + "params": { + "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "type": [ + "object", + "null" + ], + "additionalProperties": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "name": { - "description": "The name of the environment variable.", - "type": "string" - }, - "value": { - "description": "The value to set for the environment variable.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "name", - "value" + "connectionId", + "method" ], - "type": "object" + "x-side": "both", + "x-method": "mcp/message" }, - "Error": { - "description": "JSON-RPC error object.\n\nRepresents an error that occurred during method execution, following the\nJSON-RPC 2.0 error object specification with optional additional data.\n\nSee protocol docs: [JSON-RPC Error Object](https://www.jsonrpc.org/specification#error_object)", + "McpConnectionId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for an active MCP-over-ACP connection.", + "type": "string" + }, + "DisconnectMcpRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/disconnect`.", + "type": "object", "properties": { - "code": { + "connectionId": { + "description": "The MCP-over-ACP connection to close.", "allOf": [ { - "$ref": "#/$defs/ErrorCode" + "$ref": "#/$defs/McpConnectionId" } - ], - "description": "A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." - }, - "data": { - "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." + ] }, - "message": { - "description": "A string providing a short description of the error.\nThe message should be limited to a concise single sentence.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "code", - "message" + "connectionId" ], - "type": "object" + "x-side": "client", + "x-method": "mcp/disconnect" }, - "ErrorCode": { + "ExtRequest": { + "description": "Allows for sending an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "AgentResponse": { + "description": "A JSON-RPC response object.", "anyOf": [ { - "const": -32700, - "description": "**Parse error**: Invalid JSON was received by the server.\nAn error occurred on the server while parsing the JSON text.", - "format": "int32", - "title": "Parse error", - "type": "integer" - }, - { - "const": -32600, - "description": "**Invalid request**: The JSON sent is not a valid Request object.", - "format": "int32", - "title": "Invalid request", - "type": "integer" - }, - { - "const": -32601, - "description": "**Method not found**: The method does not exist or is not available.", - "format": "int32", - "title": "Method not found", - "type": "integer" - }, - { - "const": -32602, - "description": "**Invalid params**: Invalid method parameter(s).", - "format": "int32", - "title": "Invalid params", - "type": "integer" - }, - { - "const": -32603, - "description": "**Internal error**: Internal JSON-RPC error.\nReserved for implementation-defined server errors.", - "format": "int32", - "title": "Internal error", - "type": "integer" - }, - { - "const": -32800, - "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", - "format": "int32", - "title": "Request cancelled", - "type": "integer" - }, - { - "const": -32000, - "description": "**Authentication required**: Authentication is required before this operation can be performed.", - "format": "int32", - "title": "Authentication required", - "type": "integer" - }, - { - "const": -32002, - "description": "**Resource not found**: A given resource, such as a file, was not found.", - "format": "int32", - "title": "Resource not found", - "type": "integer" - }, - { - "const": -32042, - "description": "**URL elicitation required**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe agent requires user input via a URL-based elicitation before it can proceed.", - "format": "int32", - "title": "URL elicitation required", - "type": "integer" + "title": "Result", + "description": "A successful JSON-RPC response.", + "type": "object", + "properties": { + "id": { + "description": "The id of the request this response answers.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] + }, + "result": { + "description": "Method-specific response data.", + "anyOf": [ + { + "title": "InitializeResponse", + "description": "Successful result returned for a `initialize` request.", + "allOf": [ + { + "$ref": "#/$defs/InitializeResponse" + } + ] + }, + { + "title": "AuthenticateResponse", + "description": "Successful result returned for a `authenticate` request.", + "allOf": [ + { + "$ref": "#/$defs/AuthenticateResponse" + } + ] + }, + { + "title": "ListProvidersResponse", + "description": "Successful result returned for a `providers/list` request.", + "allOf": [ + { + "$ref": "#/$defs/ListProvidersResponse" + } + ] + }, + { + "title": "SetProviderResponse", + "description": "Successful result returned for a `providers/set` request.", + "allOf": [ + { + "$ref": "#/$defs/SetProviderResponse" + } + ] + }, + { + "title": "DisableProviderResponse", + "description": "Successful result returned for a `providers/disable` request.", + "allOf": [ + { + "$ref": "#/$defs/DisableProviderResponse" + } + ] + }, + { + "title": "LogoutResponse", + "description": "Successful result returned for a `logout` request.", + "allOf": [ + { + "$ref": "#/$defs/LogoutResponse" + } + ] + }, + { + "title": "NewSessionResponse", + "description": "Successful result returned for a `session/new` request.", + "allOf": [ + { + "$ref": "#/$defs/NewSessionResponse" + } + ] + }, + { + "title": "LoadSessionResponse", + "description": "Successful result returned for a `session/load` request.", + "allOf": [ + { + "$ref": "#/$defs/LoadSessionResponse" + } + ] + }, + { + "title": "ListSessionsResponse", + "description": "Successful result returned for a `session/list` request.", + "allOf": [ + { + "$ref": "#/$defs/ListSessionsResponse" + } + ] + }, + { + "title": "DeleteSessionResponse", + "description": "Successful result returned for a `session/delete` request.", + "allOf": [ + { + "$ref": "#/$defs/DeleteSessionResponse" + } + ] + }, + { + "title": "ForkSessionResponse", + "description": "Successful result returned for a `session/fork` request.", + "allOf": [ + { + "$ref": "#/$defs/ForkSessionResponse" + } + ] + }, + { + "title": "ResumeSessionResponse", + "description": "Successful result returned for a `session/resume` request.", + "allOf": [ + { + "$ref": "#/$defs/ResumeSessionResponse" + } + ] + }, + { + "title": "CloseSessionResponse", + "description": "Successful result returned for a `session/close` request.", + "allOf": [ + { + "$ref": "#/$defs/CloseSessionResponse" + } + ] + }, + { + "title": "SetSessionModeResponse", + "description": "Successful result returned for a `session/set_mode` request.", + "allOf": [ + { + "$ref": "#/$defs/SetSessionModeResponse" + } + ] + }, + { + "title": "SetSessionConfigOptionResponse", + "description": "Successful result returned for a `session/set_config_option` request.", + "allOf": [ + { + "$ref": "#/$defs/SetSessionConfigOptionResponse" + } + ] + }, + { + "title": "PromptResponse", + "description": "Successful result returned for a `session/prompt` request.", + "allOf": [ + { + "$ref": "#/$defs/PromptResponse" + } + ] + }, + { + "title": "StartNesResponse", + "description": "Successful result returned for a `nes/start` request.", + "allOf": [ + { + "$ref": "#/$defs/StartNesResponse" + } + ] + }, + { + "title": "SuggestNesResponse", + "description": "Successful result returned for a `nes/suggest` request.", + "allOf": [ + { + "$ref": "#/$defs/SuggestNesResponse" + } + ] + }, + { + "title": "CloseNesResponse", + "description": "Successful result returned for a `nes/close` request.", + "allOf": [ + { + "$ref": "#/$defs/CloseNesResponse" + } + ] + }, + { + "title": "ExtMethodResponse", + "description": "Successful result returned by an extension method outside the core ACP method set.", + "allOf": [ + { + "$ref": "#/$defs/ExtResponse" + } + ] + }, + { + "title": "MessageMcpResponse", + "description": "Successful result returned by an MCP-over-ACP `mcp/message` request.", + "allOf": [ + { + "$ref": "#/$defs/MessageMcpResponse" + } + ] + } + ] + } + }, + "required": [ + "id", + "result" + ] }, { - "description": "Other undefined error code.", - "format": "int32", - "title": "Other", - "type": "integer" - } - ], - "description": "Predefined error codes for common JSON-RPC and ACP-specific errors.\n\nThese codes follow the JSON-RPC 2.0 specification for standard errors\nand use the reserved range (-32000 to -32099) for protocol-specific errors." - }, - "ExtNotification": { - "description": "Allows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" - }, - "ExtRequest": { - "description": "Allows for sending an arbitrary request that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" - }, - "ExtResponse": { - "description": "Allows for sending an arbitrary response to an [`ExtRequest`] that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" - }, - "FileSystemCapabilities": { - "description": "File system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "title": "Error", + "description": "A failed JSON-RPC response.", + "type": "object", + "properties": { + "id": { + "description": "The id of the request this response answers.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] + }, + "error": { + "description": "Method-specific error data.", + "allOf": [ + { + "$ref": "#/$defs/Error" + } + ] + } + }, + "required": [ + "id", + "error" ] - }, - "readTextFile": { - "default": false, - "description": "Whether the Client supports `fs/read_text_file` requests.", - "type": "boolean" - }, - "writeTextFile": { - "default": false, - "description": "Whether the Client supports `fs/write_text_file` requests.", - "type": "boolean" } - }, - "type": "object" + ], + "x-docs-ignore": true }, - "ForkSessionRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for forking an existing session.\n\nCreates a new session based on the context of an existing one, allowing\noperations like generating summaries without affecting the original session's history.\n\nOnly available if the Agent supports the `session.fork` capability.", + "InitializeResponse": { + "description": "Response to the `initialize` method.\n\nContains the negotiated protocol version and agent capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "protocolVersion": { + "description": "The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", + "allOf": [ + { + "$ref": "#/$defs/ProtocolVersion" + } ] }, - "additionalDirectories": { - "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", - "items": { - "type": "string" - }, - "type": "array" - }, - "cwd": { - "description": "The working directory for this session.", - "type": "string" - }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", - "items": { - "$ref": "#/$defs/McpServer" + "agentCapabilities": { + "description": "Capabilities supported by the agent.", + "default": { + "loadSession": false, + "promptCapabilities": { + "image": false, + "audio": false, + "embeddedContext": false + }, + "mcpCapabilities": { + "http": false, + "sse": false, + "acp": false + }, + "sessionCapabilities": {}, + "auth": {} }, - "type": "array" - }, - "sessionId": { "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/AgentCapabilities" } - ], - "description": "The ID of the session to fork." - } - }, - "required": [ - "sessionId", - "cwd" - ], - "type": "object", - "x-method": "session/fork", - "x-side": "agent" - }, - "ForkSessionResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from forking an existing session.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", + "authMethods": { + "description": "Authentication methods supported by the agent.", + "type": "array", "items": { - "$ref": "#/$defs/SessionConfigOption" + "$ref": "#/$defs/AuthMethod" }, - "type": [ - "array", - "null" - ], + "default": [], "x-deserialize-default-on-error": true, "x-deserialize-skip-invalid-items": true }, - "modes": { + "agentInfo": { + "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", "anyOf": [ { - "$ref": "#/$defs/SessionModeState" + "$ref": "#/$defs/Implementation" }, { "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", "x-deserialize-default-on-error": true }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "Unique identifier for the newly created forked session." - } - }, - "required": [ - "sessionId" - ], - "type": "object", - "x-method": "session/fork", - "x-side": "agent" - }, - "HttpHeader": { - "description": "An HTTP header to set when making requests to the MCP server.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "name": { - "description": "The name of the HTTP header.", - "type": "string" - }, - "value": { - "description": "The value to set for the HTTP header.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "name", - "value" + "protocolVersion" ], - "type": "object" + "x-side": "agent", + "x-method": "initialize" }, - "ImageContent": { - "description": "An image provided to or from an LLM.", + "ProtocolVersion": { + "description": "Protocol version identifier.\n\nThis version is only bumped for breaking changes.\nNon-breaking changes should be introduced via capabilities.", + "type": "integer", + "format": "uint16", + "minimum": 0, + "maximum": 65535 + }, + "AgentCapabilities": { + "description": "Capabilities supported by the agent.\n\nAdvertised during initialization to inform the client about\navailable features and content types.\n\nSee protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol/initialization#agent-capabilities)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "loadSession": { + "description": "Whether the agent supports `session/load`.", + "type": "boolean", + "default": false + }, + "promptCapabilities": { + "description": "Prompt capabilities supported by the agent.", + "default": { + "image": false, + "audio": false, + "embeddedContext": false + }, + "allOf": [ + { + "$ref": "#/$defs/PromptCapabilities" + } ] }, - "annotations": { + "mcpCapabilities": { + "description": "MCP capabilities supported by the agent.", + "default": { + "http": false, + "sse": false, + "acp": false + }, + "allOf": [ + { + "$ref": "#/$defs/McpCapabilities" + } + ] + }, + "sessionCapabilities": { + "description": "Session lifecycle and prompt capabilities advertised by the agent.", + "default": {}, + "allOf": [ + { + "$ref": "#/$defs/SessionCapabilities" + } + ] + }, + "auth": { + "description": "Authentication-related capabilities supported by the agent.", + "default": {}, + "allOf": [ + { + "$ref": "#/$defs/AgentAuthCapabilities" + } + ] + }, + "providers": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "anyOf": [ + { + "$ref": "#/$defs/ProvidersCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "nes": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.", "anyOf": [ { - "$ref": "#/$defs/Annotations" + "$ref": "#/$defs/NesCapabilities" }, { "type": "null" @@ -3475,3141 +2854,3960 @@ ], "x-deserialize-default-on-error": true }, - "data": { - "type": "string" - }, - "mimeType": { - "type": "string" + "positionEncoding": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", + "anyOf": [ + { + "$ref": "#/$defs/PositionEncodingKind" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "uri": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } - }, - "required": [ - "data", - "mimeType" - ], - "type": "object" + } }, - "Implementation": { - "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an MCP implementation, with an optional\ntitle for UI representation.", + "PromptCapabilities": { + "description": "Prompt capabilities supported by the agent in `session/prompt` requests.\n\nBaseline agent functionality requires support for [`ContentBlock::Text`]\nand [`ContentBlock::ResourceLink`] in prompt requests.\n\nOther variants must be explicitly opted in to.\nCapabilities for different types of content in prompt requests.\n\nIndicates which content types beyond the baseline (text and resource links)\nthe agent can process.\n\nSee protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)", + "type": "object", "properties": { + "image": { + "description": "Agent supports [`ContentBlock::Image`].", + "type": "boolean", + "default": false + }, + "audio": { + "description": "Agent supports [`ContentBlock::Audio`].", + "type": "boolean", + "default": false + }, + "embeddedContext": { + "description": "Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", + "type": "boolean", + "default": false + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "name": { - "description": "Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn\u2019t present.", - "type": "string" - }, - "title": { - "description": "Intended for UI and end-user contexts \u2014 optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display.", - "type": [ - "string", - "null" - ] - }, - "version": { - "description": "Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. \"1.0.0\").", - "type": "string" + ], + "additionalProperties": true } - }, - "required": [ - "name", - "version" - ], - "type": "object" + } }, - "InitializeRequest": { - "description": "Request parameters for the initialize method.\n\nSent by the client to establish connection and negotiate capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "McpCapabilities": { + "description": "MCP capabilities supported by the agent", + "type": "object", "properties": { + "http": { + "description": "Agent supports [`McpServer::Http`].", + "type": "boolean", + "default": false + }, + "sse": { + "description": "Agent supports [`McpServer::Sse`].", + "type": "boolean", + "default": false + }, + "acp": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`].", + "type": "boolean", + "default": false + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "clientCapabilities": { - "allOf": [ + ], + "additionalProperties": true + } + } + }, + "SessionCapabilities": { + "description": "Session capabilities supported by the agent.\n\nAs a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.\n\nOptionally, they **MAY** support other session methods and notifications by specifying additional capabilities.\n\nNote: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.\n\nSee protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)", + "type": "object", + "properties": { + "list": { + "description": "Whether the agent supports `session/list`.", + "anyOf": [ { - "$ref": "#/$defs/ClientCapabilities" + "$ref": "#/$defs/SessionListCapabilities" + }, + { + "type": "null" } ], - "default": { - "auth": { - "terminal": false - }, - "fs": { - "readTextFile": false, - "writeTextFile": false - }, - "terminal": false - }, - "description": "Capabilities supported by the client." + "x-deserialize-default-on-error": true }, - "clientInfo": { + "delete": { + "description": "Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", "anyOf": [ { - "$ref": "#/$defs/Implementation" + "$ref": "#/$defs/SessionDeleteCapabilities" }, { "type": "null" } ], - "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", "x-deserialize-default-on-error": true }, - "protocolVersion": { - "allOf": [ + "additionalDirectories": { + "description": "Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + "anyOf": [ { - "$ref": "#/$defs/ProtocolVersion" + "$ref": "#/$defs/SessionAdditionalDirectoriesCapabilities" + }, + { + "type": "null" } ], - "description": "The latest protocol version supported by the client." - } - }, - "required": [ - "protocolVersion" - ], - "type": "object", - "x-method": "initialize", - "x-side": "agent" - }, - "InitializeResponse": { - "description": "Response to the `initialize` method.\n\nContains the negotiated protocol version and agent capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "x-deserialize-default-on-error": true }, - "agentCapabilities": { - "allOf": [ + "fork": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.", + "anyOf": [ { - "$ref": "#/$defs/AgentCapabilities" + "$ref": "#/$defs/SessionForkCapabilities" + }, + { + "type": "null" } ], - "default": { - "auth": {}, - "loadSession": false, - "mcpCapabilities": { - "acp": false, - "http": false, - "sse": false - }, - "promptCapabilities": { - "audio": false, - "embeddedContext": false, - "image": false - }, - "sessionCapabilities": {} - }, - "description": "Capabilities supported by the agent." + "x-deserialize-default-on-error": true }, - "agentInfo": { + "resume": { + "description": "Whether the agent supports `session/resume`.", "anyOf": [ { - "$ref": "#/$defs/Implementation" + "$ref": "#/$defs/SessionResumeCapabilities" }, { "type": "null" } ], - "description": "Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", "x-deserialize-default-on-error": true }, - "authMethods": { - "default": [], - "description": "Authentication methods supported by the agent.", - "items": { - "$ref": "#/$defs/AuthMethod" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "protocolVersion": { - "allOf": [ + "close": { + "description": "Whether the agent supports `session/close`.", + "anyOf": [ { - "$ref": "#/$defs/ProtocolVersion" + "$ref": "#/$defs/SessionCloseCapabilities" + }, + { + "type": "null" } ], - "description": "The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version." + "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - }, - "required": [ - "protocolVersion" - ], - "type": "object", - "x-method": "initialize", - "x-side": "agent" + } }, - "IntegerPropertySchema": { - "description": "Schema for integer properties in an elicitation form.", + "SessionListCapabilities": { + "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", + "type": "object", "properties": { - "default": { - "description": "Default value.", - "format": "int64", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "description": { - "description": "Human-readable description.", + ], + "additionalProperties": true + } + } + }, + "SessionDeleteCapabilities": { + "description": "Capabilities for the `session/delete` method.\n\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] - }, - "maximum": { - "description": "Maximum value (inclusive).", - "format": "int64", + ], + "additionalProperties": true + } + } + }, + "SessionAdditionalDirectoriesCapabilities": { + "description": "Capabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", - "null" - ] - }, - "minimum": { - "description": "Minimum value (inclusive).", - "format": "int64", + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "SessionForkCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "title": { - "description": "Optional title for the property.", + ], + "additionalProperties": true + } + } + }, + "SessionResumeCapabilities": { + "description": "Capabilities for the `session/resume` method.\n\nBy supplying `{}` it means that the agent supports resuming of sessions.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object" + } }, - "KillTerminalRequest": { - "description": "Request to kill a terminal without releasing it.", + "SessionCloseCapabilities": { + "description": "Capabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ + ], + "additionalProperties": true + } + } + }, + "AgentAuthCapabilities": { + "description": "Authentication-related capabilities supported by the agent.", + "type": "object", + "properties": { + "logout": { + "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "anyOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/LogoutCapabilities" + }, + { + "type": "null" } ], - "description": "The session ID for this request." + "x-deserialize-default-on-error": true }, - "terminalId": { - "description": "The ID of the terminal to kill.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - }, - "required": [ - "sessionId", - "terminalId" - ], - "type": "object", - "x-method": "terminal/kill", - "x-side": "client" + } }, - "KillTerminalResponse": { - "description": "Response to `terminal/kill` method", + "LogoutCapabilities": { + "description": "Logout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "terminal/kill", - "x-side": "client" + } }, - "ListProvidersRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/list`.", + "ProvidersCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "providers/list", - "x-side": "agent" + } }, - "ListProvidersResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/list`.", + "NesCapabilities": { + "description": "NES capabilities advertised by the agent during initialization.", + "type": "object", "properties": { + "events": { + "description": "Events the agent wants to receive.", + "anyOf": [ + { + "$ref": "#/$defs/NesEventCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "context": { + "description": "Context the agent wants attached to each suggestion request.", + "anyOf": [ + { + "$ref": "#/$defs/NesContextCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "providers": { - "description": "Configurable providers with current routing info suitable for UI display.", - "items": { - "$ref": "#/$defs/ProviderInfo" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + ], + "additionalProperties": true } - }, - "required": [ - "providers" - ], - "type": "object", - "x-method": "providers/list", - "x-side": "agent" + } }, - "ListSessionsRequest": { - "description": "Request parameters for listing existing sessions.\n\nOnly available if the Agent supports the `sessionCapabilities.list` capability.", + "NesEventCapabilities": { + "description": "Event capabilities the agent can consume.", + "type": "object", "properties": { + "document": { + "description": "Document event capabilities.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentEventCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true + } + } + }, + "NesDocumentEventCapabilities": { + "description": "Document event capabilities the agent wants to receive.", + "type": "object", + "properties": { + "didOpen": { + "description": "Whether the agent wants `document/didOpen` events.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidOpenCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "cursor": { - "description": "Opaque cursor token from a previous response's nextCursor field for cursor-based pagination", - "type": [ - "string", - "null" - ] + "didChange": { + "description": "Whether the agent wants `document/didChange` events, and the sync kind.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidChangeCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "cwd": { - "description": "Filter sessions by working directory. Must be an absolute path.", + "didClose": { + "description": "Whether the agent wants `document/didClose` events.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidCloseCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "didSave": { + "description": "Whether the agent wants `document/didSave` events.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidSaveCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "didFocus": { + "description": "Whether the agent wants `document/didFocus` events.", + "anyOf": [ + { + "$ref": "#/$defs/NesDocumentDidFocusCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "session/list", - "x-side": "agent" + } }, - "ListSessionsResponse": { - "description": "Response from listing sessions.", + "NesDocumentDidOpenCapabilities": { + "description": "Marker for `document/didOpen` capability support.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + } + }, + "NesDocumentDidChangeCapabilities": { + "description": "Capabilities for `document/didChange` events.", + "type": "object", + "properties": { + "syncKind": { + "description": "The sync kind the agent wants: `\"full\"` or `\"incremental\"`.", + "allOf": [ + { + "$ref": "#/$defs/TextDocumentSyncKind" + } ] }, - "nextCursor": { - "description": "Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] - }, - "sessions": { - "description": "Array of session information objects", - "items": { - "$ref": "#/$defs/SessionInfo" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + ], + "additionalProperties": true } }, "required": [ - "sessions" - ], - "type": "object", - "x-method": "session/list", - "x-side": "agent" + "syncKind" + ] }, - "LlmProtocol": { - "anyOf": [ - { - "const": "anthropic", - "description": "Anthropic API protocol.", - "type": "string" - }, - { - "const": "openai", - "description": "OpenAI API protocol.", - "type": "string" - }, - { - "const": "azure", - "description": "Azure OpenAI API protocol.", - "type": "string" - }, - { - "const": "vertex", - "description": "Google Vertex AI API protocol.", - "type": "string" - }, + "TextDocumentSyncKind": { + "description": "How the agent wants document changes delivered.", + "oneOf": [ { - "const": "bedrock", - "description": "AWS Bedrock API protocol.", - "type": "string" + "description": "Client sends the entire file content on each change.", + "type": "string", + "const": "full" }, { - "description": "Unknown or custom protocol.", - "title": "other", - "type": "string" + "description": "Client sends only the changed ranges.", + "type": "string", + "const": "incremental" } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWell-known API protocol identifiers for LLM providers.\n\nAgents and clients MUST handle unknown protocol identifiers gracefully.\n\nProtocol names beginning with `_` are free for custom use, like other ACP extension methods.\nProtocol names that do not begin with `_` are reserved for the ACP spec." + ] }, - "LoadSessionRequest": { - "description": "Request parameters for loading an existing session.\n\nOnly available if the Agent supports the `loadSession` capability.\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "NesDocumentDidCloseCapabilities": { + "description": "Marker for `document/didClose` capability support.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "additionalDirectories": { - "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - "items": { - "type": "string" - }, - "type": "array" - }, - "cwd": { - "description": "The working directory for this session.", - "type": "string" - }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", - "items": { - "$ref": "#/$defs/McpServer" - }, - "type": "array" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The ID of the session to load." + "additionalProperties": true } - }, - "required": [ - "mcpServers", - "cwd", - "sessionId" - ], - "type": "object", - "x-method": "session/load", - "x-side": "agent" + } }, - "LoadSessionResponse": { - "description": "Response from loading an existing session.", + "NesDocumentDidSaveCapabilities": { + "description": "Marker for `document/didSave` capability support.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, + ], + "additionalProperties": true + } + } + }, + "NesDocumentDidFocusCapabilities": { + "description": "Marker for `document/didFocus` capability support.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "array", + "object", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "additionalProperties": true + } + } + }, + "NesContextCapabilities": { + "description": "Context capabilities the agent wants attached to each suggestion request.", + "type": "object", + "properties": { + "recentFiles": { + "description": "Whether the agent wants recent files context.", + "anyOf": [ + { + "$ref": "#/$defs/NesRecentFilesCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "modes": { + "relatedSnippets": { + "description": "Whether the agent wants related snippets context.", "anyOf": [ { - "$ref": "#/$defs/SessionModeState" + "$ref": "#/$defs/NesRelatedSnippetsCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "editHistory": { + "description": "Whether the agent wants edit history context.", + "anyOf": [ + { + "$ref": "#/$defs/NesEditHistoryCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "userActions": { + "description": "Whether the agent wants user actions context.", + "anyOf": [ + { + "$ref": "#/$defs/NesUserActionsCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "openFiles": { + "description": "Whether the agent wants open files context.", + "anyOf": [ + { + "$ref": "#/$defs/NesOpenFilesCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "diagnostics": { + "description": "Whether the agent wants diagnostics context.", + "anyOf": [ + { + "$ref": "#/$defs/NesDiagnosticsCapabilities" }, { "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "session/load", - "x-side": "agent" + } }, - "LogoutCapabilities": { - "description": "Logout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "NesRecentFilesCapabilities": { + "description": "Capabilities for recent files context.", + "type": "object", "properties": { + "maxCount": { + "description": "Maximum number of recent files the agent can use.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object" + } }, - "LogoutRequest": { - "description": "Request parameters for the logout method.\n\nTerminates the current authenticated session.", + "NesRelatedSnippetsCapabilities": { + "description": "Capabilities for related snippets context.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, + } + }, + "NesEditHistoryCapabilities": { + "description": "Capabilities for edit history context.", "type": "object", - "x-method": "logout", - "x-side": "agent" + "properties": { + "maxCount": { + "description": "Maximum number of edit history entries the agent can use.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } }, - "LogoutResponse": { - "description": "Response to the `logout` method.", + "NesUserActionsCapabilities": { + "description": "Capabilities for user actions context.", + "type": "object", "properties": { + "maxCount": { + "description": "Maximum number of user actions the agent can use.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, + } + }, + "NesOpenFilesCapabilities": { + "description": "Capabilities for open files context.", "type": "object", - "x-method": "logout", - "x-side": "agent" + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } }, - "McpCapabilities": { - "description": "MCP capabilities supported by the agent", + "NesDiagnosticsCapabilities": { + "description": "Capabilities for diagnostics context.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "acp": { - "default": false, - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`].", - "type": "boolean" + ], + "additionalProperties": true + } + } + }, + "PositionEncodingKind": { + "description": "The encoding used for character offsets in positions.\n\nFollows the same conventions as LSP 3.17. The default is UTF-16.", + "oneOf": [ + { + "description": "Character offsets count UTF-16 code units. This is the default.", + "type": "string", + "const": "utf-16" }, - "http": { - "default": false, - "description": "Agent supports [`McpServer::Http`].", - "type": "boolean" + { + "description": "Character offsets count Unicode code points.", + "type": "string", + "const": "utf-32" }, - "sse": { - "default": false, - "description": "Agent supports [`McpServer::Sse`].", - "type": "boolean" + { + "description": "Character offsets count UTF-8 code units (bytes).", + "type": "string", + "const": "utf-8" } - }, - "type": "object" - }, - "McpConnectionId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA unique identifier for an active MCP-over-ACP connection.", - "type": "string" + ] }, - "McpServer": { + "AuthMethod": { + "description": "Describes an available authentication method.\n\nThe `type` field acts as the discriminator in the serialized JSON form.\nWhen no `type` is present, the method is treated as `agent`.", "anyOf": [ { - "allOf": [ - { - "$ref": "#/$defs/McpServerHttp" - } - ], - "description": "HTTP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUser provides a key that the client passes to the agent as an environment variable.", + "type": "object", "properties": { "type": { - "const": "http", - "type": "string" + "type": "string", + "const": "env_var" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/McpServerSse" + "$ref": "#/$defs/AuthMethodEnvVar" } - ], - "description": "SSE transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.", + ] + }, + { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nClient runs an interactive terminal for the user to authenticate via a TUI.", + "type": "object", "properties": { "type": { - "const": "sse", - "type": "string" + "type": "string", + "const": "terminal" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/McpServerAcp" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.acp` is `true`.\nThe MCP server is provided by an ACP component and communicates over the ACP channel.", - "properties": { - "type": { - "const": "acp", - "type": "string" + "$ref": "#/$defs/AuthMethodTerminal" } - }, - "required": [ - "type" - ], - "type": "object" + ] }, { + "title": "agent", + "description": "Agent handles authentication itself.\n\nThis is the default when no `type` is specified.", "allOf": [ { - "$ref": "#/$defs/McpServerStdio" + "$ref": "#/$defs/AuthMethodAgent" } - ], - "description": "Stdio transport configuration\n\nAll Agents MUST support this transport.", - "title": "stdio" + ] } - ], - "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)" + ] }, - "McpServerAcp": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration for MCP.\n\nThe MCP server is provided by an ACP component and communicates over the ACP channel\nusing `mcp/connect`, `mcp/message`, and `mcp/disconnect`.", + "AuthMethodId": { + "description": "Typed identifier used for auth method values on the wire.", + "type": "string" + }, + "AuthEnvVar": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDescribes a single environment variable for an [`AuthMethodEnvVar`] authentication method.", + "type": "object", "properties": { + "name": { + "description": "The environment variable name (e.g. `\"OPENAI_API_KEY\"`).", + "type": "string" + }, + "label": { + "description": "Human-readable label for this variable, displayed in client UI.", + "type": [ + "string", + "null" + ] + }, + "secret": { + "description": "Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`.", + "type": "boolean", + "default": true + }, + "optional": { + "description": "Whether this variable is optional.\n\nDefaults to `false`.", + "type": "boolean", + "default": false + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, + ], + "additionalProperties": true + } + }, + "required": [ + "name" + ] + }, + "AuthMethodEnvVar": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nEnvironment variable authentication method.\n\nThe user provides credentials that the client passes to the agent as environment variables.", + "type": "object", + "properties": { "id": { + "description": "Unique identifier for this authentication method.", "allOf": [ { - "$ref": "#/$defs/McpServerAcpId" + "$ref": "#/$defs/AuthMethodId" } - ], - "description": "Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." + ] }, "name": { - "description": "Human-readable name identifying this MCP server.", + "description": "Human-readable name of the authentication method.", "type": "string" - } - }, - "required": [ - "name", - "id" - ], - "type": "object" - }, - "McpServerAcpId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an MCP server using the ACP transport.\n\nThe value is opaque and generated by the ACP component providing the MCP server. It is\nused by `mcp/connect` to route connection requests back to the component that declared the\nserver.", - "type": "string" - }, - "McpServerHttp": { - "description": "HTTP transport configuration for MCP.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + }, + "description": { + "description": "Optional description providing more details about this authentication method.", "type": [ - "object", + "string", "null" ] }, - "headers": { - "description": "HTTP headers to set when making requests to the MCP server.", + "vars": { + "description": "The environment variables the client should set.", + "type": "array", "items": { - "$ref": "#/$defs/HttpHeader" - }, - "type": "array" + "$ref": "#/$defs/AuthEnvVar" + } }, - "name": { - "description": "Human-readable name identifying this MCP server.", - "type": "string" + "link": { + "description": "Optional link to a page where the user can obtain their credentials.", + "type": [ + "string", + "null" + ] }, - "url": { - "description": "URL to the MCP server.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ + "id", "name", - "url", - "headers" - ], - "type": "object" + "vars" + ] }, - "McpServerSse": { - "description": "SSE transport configuration for MCP.", + "AuthMethodTerminal": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nTerminal-based authentication method.\n\nThe client runs an interactive terminal for the user to authenticate via a TUI.", + "type": "object", "properties": { + "id": { + "description": "Unique identifier for this authentication method.", + "allOf": [ + { + "$ref": "#/$defs/AuthMethodId" + } + ] + }, + "name": { + "description": "Human-readable name of the authentication method.", + "type": "string" + }, + "description": { + "description": "Optional description providing more details about this authentication method.", + "type": [ + "string", + "null" + ] + }, + "args": { + "description": "Additional arguments to pass when running the agent binary for terminal auth.", + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "description": "Additional environment variables to set when running the agent binary for terminal auth.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "id", + "name" + ] + }, + "AuthMethodAgent": { + "description": "Agent handles authentication itself.\n\nThis is the default authentication method type.", + "type": "object", + "properties": { + "id": { + "description": "Unique identifier for this authentication method.", + "allOf": [ + { + "$ref": "#/$defs/AuthMethodId" + } ] }, - "headers": { - "description": "HTTP headers to set when making requests to the MCP server.", - "items": { - "$ref": "#/$defs/HttpHeader" - }, - "type": "array" - }, "name": { - "description": "Human-readable name identifying this MCP server.", + "description": "Human-readable name of the authentication method.", "type": "string" }, - "url": { - "description": "URL to the MCP server.", - "type": "string" + "description": { + "description": "Optional description providing more details about this authentication method.", + "type": [ + "string", + "null" + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "name", - "url", - "headers" - ], - "type": "object" - }, - "McpServerStdio": { - "description": "Stdio transport configuration for MCP.", + "id", + "name" + ] + }, + "Implementation": { + "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an MCP implementation, with an optional\ntitle for UI representation.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "name": { + "description": "Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn\u2019t present.", + "type": "string" + }, + "title": { + "description": "Intended for UI and end-user contexts \u2014 optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display.", "type": [ - "object", + "string", "null" ] }, - "args": { - "description": "Command-line arguments to pass to the MCP server.", - "items": { - "type": "string" - }, - "type": "array" - }, - "command": { - "description": "Path to the MCP server executable.", + "version": { + "description": "Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. \"1.0.0\").", "type": "string" }, - "env": { - "description": "Environment variables to set when launching the MCP server.", - "items": { - "$ref": "#/$defs/EnvVariable" - }, - "type": "array" - }, - "name": { - "description": "Human-readable name identifying this MCP server.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ "name", - "command", - "args", - "env" - ], - "type": "object" - }, - "MessageId": { - "description": "Unique identifier for a message within a session.", - "type": "string" + "version" + ] }, - "MessageMcpNotification": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification parameters for `mcp/message`.\n\nThis is used when the wrapped MCP message is a notification and the outer JSON-RPC\nenvelope has no `id`.", + "AuthenticateResponse": { + "description": "Response to the `authenticate` method.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "connectionId": { - "allOf": [ - { - "$ref": "#/$defs/McpConnectionId" - } ], - "description": "The MCP-over-ACP connection this message is sent on." - }, - "method": { - "description": "The inner MCP method name.", - "type": "string" + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "authenticate" + }, + "ListProvidersResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/list`.", + "type": "object", + "properties": { + "providers": { + "description": "Configurable providers with current routing info suitable for UI display.", + "type": "array", + "items": { + "$ref": "#/$defs/ProviderInfo" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "params": { - "additionalProperties": true, - "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, "required": [ - "connectionId", - "method" + "providers" ], - "type": "object", - "x-method": "mcp/message", - "x-side": "both" + "x-side": "agent", + "x-method": "providers/list" }, - "MessageMcpRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/message`.", + "ProviderInfo": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a configurable LLM provider.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "id": { + "description": "Provider identifier, for example \"main\" or \"openai\".", + "type": "string" }, - "connectionId": { - "allOf": [ + "supported": { + "description": "Supported protocol types for this provider.", + "type": "array", + "items": { + "$ref": "#/$defs/LlmProtocol" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "required": { + "description": "Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id.", + "type": "boolean" + }, + "current": { + "description": "Current effective non-secret routing config.\nNull or omitted means provider is disabled.", + "anyOf": [ { - "$ref": "#/$defs/McpConnectionId" + "$ref": "#/$defs/ProviderCurrentConfig" + }, + { + "type": "null" } - ], - "description": "The MCP-over-ACP connection this message is sent on." - }, - "method": { - "description": "The inner MCP method name.", - "type": "string" + ] }, - "params": { - "additionalProperties": true, - "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, "required": [ - "connectionId", - "method" - ], - "type": "object", - "x-method": "mcp/message", - "x-side": "both" - }, - "MessageMcpResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/message`.\n\nThis is the inner MCP response result payload. Any JSON value is valid.", - "x-method": "mcp/message", - "x-side": "both" + "id", + "supported", + "required" + ] }, - "MultiSelectItems": { + "LlmProtocol": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWell-known API protocol identifiers for LLM providers.\n\nAgents and clients MUST handle unknown protocol identifiers gracefully.\n\nProtocol names beginning with `_` are free for custom use, like other ACP extension methods.\nProtocol names that do not begin with `_` are reserved for the ACP spec.", "anyOf": [ { - "allOf": [ - { - "$ref": "#/$defs/UntitledMultiSelectItems" - } - ], - "description": "Untitled multi-select items with plain string values.", - "title": "Untitled" + "description": "Anthropic API protocol.", + "type": "string", + "const": "anthropic" }, { - "allOf": [ - { - "$ref": "#/$defs/TitledMultiSelectItems" - } - ], - "description": "Titled multi-select items with human-readable labels.", - "title": "Titled" + "description": "OpenAI API protocol.", + "type": "string", + "const": "openai" + }, + { + "description": "Azure OpenAI API protocol.", + "type": "string", + "const": "azure" + }, + { + "description": "Google Vertex AI API protocol.", + "type": "string", + "const": "vertex" + }, + { + "description": "AWS Bedrock API protocol.", + "type": "string", + "const": "bedrock" + }, + { + "title": "other", + "description": "Unknown or custom protocol.", + "type": "string" } - ], - "description": "Items for a multi-select (array) property schema." + ] }, - "MultiSelectPropertySchema": { - "description": "Schema for multi-select (array) properties in an elicitation form.", + "ProviderCurrentConfig": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCurrent effective non-secret routing configuration for a provider.", + "type": "object", "properties": { - "default": { - "description": "Default selected values.", - "items": { - "type": "string" - }, - "type": [ - "array", - "null" - ] - }, - "description": { - "description": "Human-readable description.", - "type": [ - "string", - "null" - ] - }, - "items": { + "apiType": { + "description": "Protocol currently used by this provider.", "allOf": [ { - "$ref": "#/$defs/MultiSelectItems" + "$ref": "#/$defs/LlmProtocol" } - ], - "description": "The items definition describing allowed values." + ] }, - "maxItems": { - "description": "Maximum number of items to select.", - "format": "uint64", - "minimum": 0, + "baseUrl": { + "description": "Base URL currently used by this provider.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "minItems": { - "description": "Minimum number of items to select.", - "format": "uint64", - "minimum": 0, + ], + "additionalProperties": true + } + }, + "required": [ + "apiType", + "baseUrl" + ] + }, + "SetProviderResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/set`.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "title": { - "description": "Optional title for the property.", + ], + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "providers/set" + }, + "DisableProviderResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/disable`.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } }, - "required": [ - "items" - ], - "type": "object" + "x-side": "agent", + "x-method": "providers/disable" }, - "NesCapabilities": { - "description": "NES capabilities advertised by the agent during initialization.", + "LogoutResponse": { + "description": "Response to the `logout` method.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "logout" + }, + "NewSessionResponse": { + "description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "type": "object", + "properties": { + "sessionId": { + "description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "context": { + "modes": { + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", "anyOf": [ { - "$ref": "#/$defs/NesContextCapabilities" + "$ref": "#/$defs/SessionModeState" }, { "type": "null" } ], - "description": "Context the agent wants attached to each suggestion request.", "x-deserialize-default-on-error": true }, - "events": { - "anyOf": [ - { - "$ref": "#/$defs/NesEventCapabilities" - }, - { - "type": "null" - } + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "type": [ + "array", + "null" ], - "description": "Events the agent wants to receive.", - "x-deserialize-default-on-error": true + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "session/new" }, - "NesContextCapabilities": { - "description": "Context capabilities the agent wants attached to each suggestion request.", + "SessionModeState": { + "description": "The set of modes and the one currently active.", + "type": "object", "properties": { + "currentModeId": { + "description": "The current mode the Agent is in.", + "allOf": [ + { + "$ref": "#/$defs/SessionModeId" + } + ] + }, + "availableModes": { + "description": "The set of modes that the Agent can operate in", + "type": "array", + "items": { + "$ref": "#/$defs/SessionMode" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "diagnostics": { - "anyOf": [ - { - "$ref": "#/$defs/NesDiagnosticsCapabilities" - }, - { - "type": "null" - } ], - "description": "Whether the agent wants diagnostics context.", - "x-deserialize-default-on-error": true - }, - "editHistory": { - "anyOf": [ - { - "$ref": "#/$defs/NesEditHistoryCapabilities" - }, + "additionalProperties": true + } + }, + "required": [ + "currentModeId", + "availableModes" + ] + }, + "SessionModeId": { + "description": "Unique identifier for a Session Mode.", + "type": "string" + }, + "SessionMode": { + "description": "A mode the agent can operate in.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "type": "object", + "properties": { + "id": { + "description": "Stable identifier used to refer to this protocol object in later messages.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionModeId" } - ], - "description": "Whether the agent wants edit history context.", - "x-deserialize-default-on-error": true + ] }, - "openFiles": { - "anyOf": [ - { - "$ref": "#/$defs/NesOpenFilesCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the agent wants open files context.", - "x-deserialize-default-on-error": true + "name": { + "description": "Human-readable name shown for this protocol object.", + "type": "string" }, - "recentFiles": { - "anyOf": [ - { - "$ref": "#/$defs/NesRecentFilesCapabilities" - }, + "description": { + "description": "Optional human-readable details shown with this protocol object.", + "type": [ + "string", + "null" + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "id", + "name" + ] + }, + "SessionConfigOption": { + "description": "A session configuration option selector and its current state.", + "type": "object", + "properties": { + "id": { + "description": "Unique identifier for the configuration option.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionConfigId" } - ], - "description": "Whether the agent wants recent files context.", - "x-deserialize-default-on-error": true + ] }, - "relatedSnippets": { + "name": { + "description": "Human-readable label for the option.", + "type": "string" + }, + "description": { + "description": "Optional description for the Client to display to the user.", + "type": [ + "string", + "null" + ] + }, + "category": { + "description": "Optional semantic category for this option (UX only).", "anyOf": [ { - "$ref": "#/$defs/NesRelatedSnippetsCapabilities" + "$ref": "#/$defs/SessionConfigOptionCategory" }, { "type": "null" } ], - "description": "Whether the agent wants related snippets context.", "x-deserialize-default-on-error": true }, - "userActions": { - "anyOf": [ - { - "$ref": "#/$defs/NesUserActionsCapabilities" - }, - { - "type": "null" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Whether the agent wants user actions context.", - "x-deserialize-default-on-error": true + "additionalProperties": true } }, - "type": "object" - }, - "NesDiagnostic": { - "description": "A diagnostic (error, warning, etc.).", - "properties": { - "message": { - "description": "The diagnostic message.", - "type": "string" - }, - "range": { + "required": [ + "id", + "name" + ], + "oneOf": [ + { + "description": "Single-value selector (dropdown).", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "select" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/Range" + "$ref": "#/$defs/SessionConfigSelect" } - ], - "description": "The range of the diagnostic." + ] }, - "severity": { + { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "boolean" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/NesDiagnosticSeverity" + "$ref": "#/$defs/SessionConfigBoolean" } - ], - "description": "The severity of the diagnostic." - }, - "uri": { - "description": "The URI of the file containing the diagnostic.", - "type": "string" + ] } - }, - "required": [ - "uri", - "range", - "severity", - "message" ], - "type": "object" + "discriminator": { + "propertyName": "type" + } }, - "NesDiagnosticSeverity": { - "description": "Severity of a diagnostic.", - "oneOf": [ + "SessionConfigId": { + "description": "Unique identifier for a session configuration option.", + "type": "string" + }, + "SessionConfigOptionCategory": { + "description": "Semantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec.", + "anyOf": [ { - "const": "error", - "description": "An error.", - "type": "string" + "description": "Session mode selector.", + "type": "string", + "const": "mode" }, { - "const": "warning", - "description": "A warning.", - "type": "string" + "description": "Model selector.", + "type": "string", + "const": "model" }, { - "const": "information", - "description": "An informational message.", - "type": "string" + "description": "Model-related configuration parameter.", + "type": "string", + "const": "model_config" }, { - "const": "hint", - "description": "A hint.", + "description": "Thought/reasoning level selector.", + "type": "string", + "const": "thought_level" + }, + { + "title": "other", + "description": "Unknown / uncategorized selector.", "type": "string" } ] }, - "NesDiagnosticsCapabilities": { - "description": "Capabilities for diagnostics context.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "SessionConfigValueId": { + "description": "Unique identifier for a session configuration option value.", + "type": "string" + }, + "SessionConfigSelectOptions": { + "description": "Possible values for a session configuration option.", + "anyOf": [ + { + "title": "Ungrouped", + "description": "A flat list of options with no grouping.", + "type": "array", + "items": { + "$ref": "#/$defs/SessionConfigSelectOption" + } + }, + { + "title": "Grouped", + "description": "A list of options grouped under headers.", + "type": "array", + "items": { + "$ref": "#/$defs/SessionConfigSelectGroup" + } } - }, - "type": "object" + ] }, - "NesDocumentDidChangeCapabilities": { - "description": "Capabilities for `document/didChange` events.", + "SessionConfigSelectOption": { + "description": "A possible value for a session configuration option.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "syncKind": { + "value": { + "description": "Unique identifier for this option value.", "allOf": [ { - "$ref": "#/$defs/TextDocumentSyncKind" + "$ref": "#/$defs/SessionConfigValueId" } - ], - "description": "The sync kind the agent wants: `\"full\"` or `\"incremental\"`." - } - }, - "required": [ - "syncKind" - ], - "type": "object" - }, - "NesDocumentDidCloseCapabilities": { - "description": "Marker for `document/didClose` capability support.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] - } - }, - "type": "object" - }, - "NesDocumentDidFocusCapabilities": { - "description": "Marker for `document/didFocus` capability support.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + }, + "name": { + "description": "Human-readable label for this option value.", + "type": "string" + }, + "description": { + "description": "Optional description for this option value.", "type": [ - "object", + "string", "null" ] - } - }, - "type": "object" - }, - "NesDocumentDidOpenCapabilities": { - "description": "Marker for `document/didOpen` capability support.", - "properties": { + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "value", + "name" + ] }, - "NesDocumentDidSaveCapabilities": { - "description": "Marker for `document/didSave` capability support.", + "SessionConfigSelectGroup": { + "description": "A group of possible values for a session configuration option.", + "type": "object", "properties": { + "group": { + "description": "Unique identifier for this group.", + "allOf": [ + { + "$ref": "#/$defs/SessionConfigGroupId" + } + ] + }, + "name": { + "description": "Human-readable label for this group.", + "type": "string" + }, + "options": { + "description": "The set of option values in this group.", + "type": "array", + "items": { + "$ref": "#/$defs/SessionConfigSelectOption" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "group", + "name", + "options" + ] }, - "NesDocumentEventCapabilities": { - "description": "Document event capabilities the agent wants to receive.", + "SessionConfigGroupId": { + "description": "Unique identifier for a session configuration option value group.", + "type": "string" + }, + "SessionConfigSelect": { + "description": "A single-value selector (dropdown) session configuration option payload.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "didChange": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentDidChangeCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the agent wants `document/didChange` events, and the sync kind.", - "x-deserialize-default-on-error": true - }, - "didClose": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentDidCloseCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the agent wants `document/didClose` events.", - "x-deserialize-default-on-error": true - }, - "didFocus": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentDidFocusCapabilities" - }, - { - "type": "null" - } - ], - "description": "Whether the agent wants `document/didFocus` events.", - "x-deserialize-default-on-error": true - }, - "didOpen": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentDidOpenCapabilities" - }, + "currentValue": { + "description": "The currently selected value.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionConfigValueId" } - ], - "description": "Whether the agent wants `document/didOpen` events.", - "x-deserialize-default-on-error": true + ] }, - "didSave": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentDidSaveCapabilities" - }, + "options": { + "description": "The set of selectable options.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/SessionConfigSelectOptions" } - ], - "description": "Whether the agent wants `document/didSave` events.", - "x-deserialize-default-on-error": true - } - }, - "type": "object" - }, - "NesEditHistoryCapabilities": { - "description": "Capabilities for edit history context.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "maxCount": { - "description": "Maximum number of edit history entries the agent can use.", - "format": "uint32", - "minimum": 0, - "type": [ - "integer", - "null" ] } }, - "type": "object" + "required": [ + "currentValue", + "options" + ] }, - "NesEditHistoryEntry": { - "description": "An entry in the edit history.", - "properties": { - "diff": { - "description": "A diff representing the edit.", - "type": "string" - }, - "uri": { - "description": "The URI of the edited file.", - "type": "string" + "SessionConfigBoolean": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", + "type": "object", + "properties": { + "currentValue": { + "description": "The current value of the boolean option.", + "type": "boolean" } }, "required": [ - "uri", - "diff" - ], - "type": "object" + "currentValue" + ] }, - "NesEditSuggestion": { - "description": "A text edit suggestion.", + "LoadSessionResponse": { + "description": "Response from loading an existing session.", + "type": "object", "properties": { - "cursorPosition": { + "modes": { + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", "anyOf": [ { - "$ref": "#/$defs/Position" + "$ref": "#/$defs/SessionModeState" }, { "type": "null" } ], - "description": "Optional suggested cursor position after applying edits.", "x-deserialize-default-on-error": true }, - "edits": { - "description": "The text edits to apply.", + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "type": [ + "array", + "null" + ], "items": { - "$ref": "#/$defs/NesTextEdit" + "$ref": "#/$defs/SessionConfigOption" }, - "type": "array" - }, - "id": { - "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "uri": { - "description": "The URI of the file to edit.", - "type": "string" - } - }, - "required": [ - "id", - "uri", - "edits" - ], - "type": "object" - }, - "NesEventCapabilities": { - "description": "Event capabilities the agent can consume.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "document": { - "anyOf": [ - { - "$ref": "#/$defs/NesDocumentEventCapabilities" - }, - { - "type": "null" - } ], - "description": "Document event capabilities.", - "x-deserialize-default-on-error": true + "additionalProperties": true } }, - "type": "object" + "x-side": "agent", + "x-method": "session/load" }, - "NesExcerpt": { - "description": "A code excerpt from a file.", + "ListSessionsResponse": { + "description": "Response from listing sessions.", + "type": "object", "properties": { - "endLine": { - "description": "The end line of the excerpt (zero-based).", - "format": "uint32", - "minimum": 0, - "type": "integer" + "sessions": { + "description": "Array of session information objects", + "type": "array", + "items": { + "$ref": "#/$defs/SessionInfo" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "startLine": { - "description": "The start line of the excerpt (zero-based).", - "format": "uint32", - "minimum": 0, - "type": "integer" + "nextCursor": { + "description": "Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", + "type": [ + "string", + "null" + ] }, - "text": { - "description": "The text content of the excerpt.", - "type": "string" - } - }, - "required": [ - "startLine", - "endLine", - "text" - ], - "type": "object" - }, - "NesJumpCapabilities": { - "description": "Marker for jump suggestion support.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "sessions" + ], + "x-side": "agent", + "x-method": "session/list" }, - "NesJumpSuggestion": { - "description": "A jump-to-location suggestion.", + "SessionInfo": { + "description": "Information about a session returned by session/list", + "type": "object", "properties": { - "id": { - "description": "Unique identifier for accept/reject tracking.", - "type": "string" - }, - "position": { + "sessionId": { + "description": "Unique identifier for the session", "allOf": [ { - "$ref": "#/$defs/Position" + "$ref": "#/$defs/SessionId" } - ], - "description": "The target position within the file." + ] }, - "uri": { - "description": "The file to navigate to.", - "type": "string" - } - }, - "required": [ - "id", - "uri", - "position" - ], - "type": "object" - }, - "NesOpenFile": { - "description": "An open file in the editor.", - "properties": { - "languageId": { - "description": "The language identifier.", + "cwd": { + "description": "The working directory for this session. Must be an absolute path.", "type": "string" }, - "lastFocusedMs": { - "description": "Timestamp in milliseconds since epoch of when the file was last focused.", - "format": "uint64", - "minimum": 0, + "additionalDirectories": { + "description": "Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", + "type": "array", + "items": { + "type": "string" + } + }, + "title": { + "description": "Human-readable title for the session", "type": [ - "integer", + "string", "null" ], "x-deserialize-default-on-error": true }, - "uri": { - "description": "The URI of the file.", - "type": "string" - }, - "visibleRange": { - "anyOf": [ - { - "$ref": "#/$defs/Range" - }, - { - "type": "null" - } + "updatedAt": { + "description": "ISO 8601 timestamp of last activity", + "type": [ + "string", + "null" ], - "description": "The visible range in the editor, if any.", "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "uri", - "languageId" - ], - "type": "object" + "sessionId", + "cwd" + ] }, - "NesOpenFilesCapabilities": { - "description": "Capabilities for open files context.", + "DeleteSessionResponse": { + "description": "Response from deleting a session.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "x-side": "agent", + "x-method": "session/delete" }, - "NesRecentFile": { - "description": "A recently accessed file.", + "ForkSessionResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from forking an existing session.", + "type": "object", "properties": { - "languageId": { - "description": "The language identifier.", - "type": "string" + "sessionId": { + "description": "Unique identifier for the newly created forked session.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] }, - "text": { - "description": "The full text content of the file.", - "type": "string" + "modes": { + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "uri": { - "description": "The URI of the file.", - "type": "string" - } - }, - "required": [ - "uri", - "languageId", - "text" - ], - "type": "object" - }, - "NesRecentFilesCapabilities": { - "description": "Capabilities for recent files context.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", "type": [ - "object", + "array", "null" - ] + ], + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "maxCount": { - "description": "Maximum number of recent files the agent can use.", - "format": "uint32", - "minimum": 0, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" - }, - "NesRejectReason": { - "description": "The reason a suggestion was rejected.", - "oneOf": [ - { - "const": "rejected", - "description": "The user explicitly dismissed the suggestion.", - "type": "string" - }, - { - "const": "ignored", - "description": "The suggestion was shown but the user continued editing without interacting.", - "type": "string" - }, - { - "const": "replaced", - "description": "The suggestion was superseded by a newer suggestion.", - "type": "string" - }, - { - "const": "cancelled", - "description": "The request was cancelled before the agent returned a response.", - "type": "string" - } - ] + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "session/fork" }, - "NesRelatedSnippet": { - "description": "A related code snippet from a file.", + "ResumeSessionResponse": { + "description": "Response from resuming an existing session.", + "type": "object", "properties": { - "excerpts": { - "description": "The code excerpts.", + "modes": { + "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "anyOf": [ + { + "$ref": "#/$defs/SessionModeState" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "configOptions": { + "description": "Initial session configuration options if supported by the Agent.", + "type": [ + "array", + "null" + ], "items": { - "$ref": "#/$defs/NesExcerpt" + "$ref": "#/$defs/SessionConfigOption" }, - "type": "array" + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "uri": { - "description": "The URI of the file containing the snippets.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, - "required": [ - "uri", - "excerpts" - ], - "type": "object" + "x-side": "agent", + "x-method": "session/resume" }, - "NesRelatedSnippetsCapabilities": { - "description": "Capabilities for related snippets context.", + "CloseSessionResponse": { + "description": "Response from closing a session.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "x-side": "agent", + "x-method": "session/close" }, - "NesRenameCapabilities": { - "description": "Marker for rename suggestion support.", + "SetSessionModeResponse": { + "description": "Response to `session/set_mode` method.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "x-side": "agent", + "x-method": "session/set_mode" }, - "NesRenameSuggestion": { - "description": "A rename symbol suggestion.", + "SetSessionConfigOptionResponse": { + "description": "Response to `session/set_config_option` method.", + "type": "object", "properties": { - "id": { - "description": "Unique identifier for accept/reject tracking.", - "type": "string" - }, - "newName": { - "description": "The new name for the symbol.", - "type": "string" + "configOptions": { + "description": "The full set of configuration options and their current values.", + "type": "array", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "position": { - "allOf": [ - { - "$ref": "#/$defs/Position" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The position of the symbol to rename." - }, - "uri": { - "description": "The file URI containing the symbol.", - "type": "string" + "additionalProperties": true } }, "required": [ - "id", - "uri", - "position", - "newName" + "configOptions" ], - "type": "object" + "x-side": "agent", + "x-method": "session/set_config_option" }, - "NesRepository": { - "description": "Repository metadata for an NES session.", + "PromptResponse": { + "description": "Response from processing a user prompt.\n\nSee protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)", + "type": "object", "properties": { - "name": { - "description": "The repository name.", - "type": "string" + "stopReason": { + "description": "Indicates why the agent stopped processing the turn.", + "allOf": [ + { + "$ref": "#/$defs/StopReason" + } + ] }, - "owner": { - "description": "The repository owner.", - "type": "string" + "usage": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional).", + "anyOf": [ + { + "$ref": "#/$defs/Usage" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "remoteUrl": { - "description": "The remote URL of the repository.", - "type": "string" - } - }, - "required": [ - "name", - "owner", - "remoteUrl" - ], - "type": "object" - }, - "NesSearchAndReplaceCapabilities": { - "description": "Marker for search and replace suggestion support.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "stopReason" + ], + "x-side": "agent", + "x-method": "session/prompt" }, - "NesSearchAndReplaceSuggestion": { - "description": "A search-and-replace suggestion.", - "properties": { - "id": { - "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "StopReason": { + "description": "Reasons why an agent stops processing a prompt turn.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)", + "oneOf": [ + { + "description": "The turn ended successfully.", + "type": "string", + "const": "end_turn" }, - "isRegex": { - "description": "Whether `search` is a regular expression. Defaults to `false`.", - "type": [ - "boolean", - "null" - ] + { + "description": "The turn ended because the agent reached the maximum number of tokens.", + "type": "string", + "const": "max_tokens" }, - "replace": { - "description": "The replacement text.", - "type": "string" + { + "description": "The turn ended because the agent reached the maximum number of allowed\nagent requests between user turns.", + "type": "string", + "const": "max_turn_requests" }, - "search": { - "description": "The text or pattern to find.", - "type": "string" + { + "description": "The turn ended because the agent refused to continue. The user prompt\nand everything that comes after it won't be included in the next\nprompt, so this should be reflected in the UI.", + "type": "string", + "const": "refusal" }, - "uri": { - "description": "The file URI to search within.", - "type": "string" + { + "description": "The turn was cancelled by the client via `session/cancel`.\n\nThis stop reason MUST be returned when the client sends a `session/cancel`\nnotification, even if the cancellation causes exceptions in underlying operations.\nAgents should catch these exceptions and return this semantically meaningful\nresponse to confirm successful cancellation.", + "type": "string", + "const": "cancelled" } - }, - "required": [ - "id", - "uri", - "search", - "replace" - ], - "type": "object" + ] }, - "NesSuggestContext": { - "description": "Context attached to a suggestion request.", + "Usage": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage information for a prompt turn.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "totalTokens": { + "description": "Sum of all token types across session.", + "type": "integer", + "format": "uint64", + "minimum": 0 }, - "diagnostics": { - "description": "Current diagnostics (errors, warnings).", - "items": { - "$ref": "#/$defs/NesDiagnostic" - }, + "inputTokens": { + "description": "Total input tokens across all turns.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "outputTokens": { + "description": "Total output tokens across all turns.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "thoughtTokens": { + "description": "Total thought/reasoning tokens", "type": [ - "array", + "integer", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "format": "uint64", + "minimum": 0 }, - "editHistory": { - "description": "Recent edit history.", - "items": { - "$ref": "#/$defs/NesEditHistoryEntry" - }, + "cachedReadTokens": { + "description": "Total cache read tokens.", "type": [ - "array", + "integer", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "format": "uint64", + "minimum": 0 }, - "openFiles": { - "description": "Currently open files in the editor.", - "items": { - "$ref": "#/$defs/NesOpenFile" - }, + "cachedWriteTokens": { + "description": "Total cache write tokens.", "type": [ - "array", + "integer", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "format": "uint64", + "minimum": 0 }, - "recentFiles": { - "description": "Recently accessed files.", - "items": { - "$ref": "#/$defs/NesRecentFile" - }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "array", + "object", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "additionalProperties": true + } + }, + "required": [ + "totalTokens", + "inputTokens", + "outputTokens" + ] + }, + "StartNesResponse": { + "description": "Response to `nes/start`.", + "type": "object", + "properties": { + "sessionId": { + "description": "The session ID for the newly started NES session.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] }, - "relatedSnippets": { - "description": "Related code snippets.", - "items": { - "$ref": "#/$defs/NesRelatedSnippet" - }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "array", + "object", "null" ], + "additionalProperties": true + } + }, + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "nes/start" + }, + "SuggestNesResponse": { + "description": "Response to `nes/suggest`.", + "type": "object", + "properties": { + "suggestions": { + "description": "The list of suggestions.", + "type": "array", + "items": { + "$ref": "#/$defs/NesSuggestion" + }, "x-deserialize-default-on-error": true, "x-deserialize-skip-invalid-items": true }, - "userActions": { - "description": "Recent user actions (typing, navigation, etc.).", - "items": { - "$ref": "#/$defs/NesUserAction" - }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "array", + "object", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "additionalProperties": true } }, - "type": "object" + "required": [ + "suggestions" + ], + "x-side": "agent", + "x-method": "nes/suggest" }, "NesSuggestion": { "description": "A suggestion returned by the agent.", - "discriminator": { - "propertyName": "kind" - }, "oneOf": [ { - "allOf": [ - { - "$ref": "#/$defs/NesEditSuggestion" - } - ], "description": "A text edit suggestion.", + "type": "object", "properties": { "kind": { - "const": "edit", - "type": "string" + "type": "string", + "const": "edit" } }, "required": [ "kind" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/NesJumpSuggestion" + "$ref": "#/$defs/NesEditSuggestion" } - ], + ] + }, + { "description": "A jump-to-location suggestion.", + "type": "object", "properties": { "kind": { - "const": "jump", - "type": "string" + "type": "string", + "const": "jump" } }, "required": [ "kind" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/NesRenameSuggestion" + "$ref": "#/$defs/NesJumpSuggestion" } - ], + ] + }, + { "description": "A rename symbol suggestion.", + "type": "object", "properties": { "kind": { - "const": "rename", - "type": "string" + "type": "string", + "const": "rename" } }, "required": [ "kind" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/NesSearchAndReplaceSuggestion" + "$ref": "#/$defs/NesRenameSuggestion" } - ], + ] + }, + { "description": "A search-and-replace suggestion.", + "type": "object", "properties": { "kind": { - "const": "searchAndReplace", - "type": "string" + "type": "string", + "const": "searchAndReplace" } }, "required": [ "kind" ], - "type": "object" + "allOf": [ + { + "$ref": "#/$defs/NesSearchAndReplaceSuggestion" + } + ] } - ] + ], + "discriminator": { + "propertyName": "kind" + } }, "NesTextEdit": { "description": "A text edit within a suggestion.", + "type": "object", "properties": { - "newText": { - "description": "The replacement text.", - "type": "string" - }, "range": { + "description": "The range to replace.", "allOf": [ { "$ref": "#/$defs/Range" } + ] + }, + "newText": { + "description": "The replacement text.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The range to replace." + "additionalProperties": true } }, "required": [ "range", "newText" - ], - "type": "object" + ] }, - "NesTriggerKind": { - "description": "What triggered the suggestion request.", - "oneOf": [ - { - "const": "automatic", - "description": "Triggered by user typing or cursor movement.", + "Range": { + "description": "A range in a text document, expressed as start and end positions.", + "type": "object", + "properties": { + "start": { + "description": "The start position (inclusive).", + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ] + }, + "end": { + "description": "The end position (exclusive).", + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "start", + "end" + ] + }, + "Position": { + "description": "A zero-based position in a text document.\n\nThe meaning of `character` depends on the negotiated position encoding.", + "type": "object", + "properties": { + "line": { + "description": "Zero-based line number.", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "character": { + "description": "Zero-based character offset (encoding-dependent).", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "line", + "character" + ] + }, + "NesEditSuggestion": { + "description": "A text edit suggestion.", + "type": "object", + "properties": { + "id": { + "description": "Unique identifier for accept/reject tracking.", "type": "string" }, - { - "const": "diagnostic", - "description": "Triggered by a diagnostic appearing at or near the cursor.", + "uri": { + "description": "The URI of the file to edit.", "type": "string" }, - { - "const": "manual", - "description": "Triggered by an explicit user action (keyboard shortcut).", + "edits": { + "description": "The text edits to apply.", + "type": "array", + "items": { + "$ref": "#/$defs/NesTextEdit" + } + }, + "cursorPosition": { + "description": "Optional suggested cursor position after applying edits.", + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "id", + "uri", + "edits" + ] + }, + "NesJumpSuggestion": { + "description": "A jump-to-location suggestion.", + "type": "object", + "properties": { + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "uri": { + "description": "The file to navigate to.", "type": "string" + }, + "position": { + "description": "The target position within the file.", + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } + }, + "required": [ + "id", + "uri", + "position" ] }, - "NesUserAction": { - "description": "A user action (typing, cursor movement, etc.).", + "NesRenameSuggestion": { + "description": "A rename symbol suggestion.", + "type": "object", "properties": { - "action": { - "description": "The kind of action (e.g., \"insertChar\", \"cursorMovement\").", + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "uri": { + "description": "The file URI containing the symbol.", "type": "string" }, "position": { + "description": "The position of the symbol to rename.", "allOf": [ { "$ref": "#/$defs/Position" } - ], - "description": "The position where the action occurred." - }, - "timestampMs": { - "description": "Timestamp in milliseconds since epoch.", - "format": "uint64", - "minimum": 0, - "type": "integer" + ] }, - "uri": { - "description": "The URI of the file where the action occurred.", + "newName": { + "description": "The new name for the symbol.", "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "action", + "id", "uri", "position", - "timestampMs" - ], - "type": "object" + "newName" + ] }, - "NesUserActionsCapabilities": { - "description": "Capabilities for user actions context.", + "NesSearchAndReplaceSuggestion": { + "description": "A search-and-replace suggestion.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "id": { + "description": "Unique identifier for accept/reject tracking.", + "type": "string" + }, + "uri": { + "description": "The file URI to search within.", + "type": "string" + }, + "search": { + "description": "The text or pattern to find.", + "type": "string" + }, + "replace": { + "description": "The replacement text.", + "type": "string" + }, + "isRegex": { + "description": "Whether `search` is a regular expression. Defaults to `false`.", "type": [ - "object", + "boolean", "null" ] }, - "maxCount": { - "description": "Maximum number of user actions the agent can use.", - "format": "uint32", - "minimum": 0, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "id", + "uri", + "search", + "replace" + ] }, - "NewSessionRequest": { - "description": "Request parameters for creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "CloseNesResponse": { + "description": "Response from closing an NES session.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "nes/close" + }, + "ExtResponse": { + "description": "Allows for sending an arbitrary response to an [`ExtRequest`] that is not part of the ACP spec.\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "MessageMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/message`.\n\nThis is the inner MCP response result payload. Any JSON value is valid.", + "x-side": "both", + "x-method": "mcp/message" + }, + "Error": { + "description": "JSON-RPC error object.\n\nRepresents an error that occurred during method execution, following the\nJSON-RPC 2.0 error object specification with optional additional data.\n\nSee protocol docs: [JSON-RPC Error Object](https://www.jsonrpc.org/specification#error_object)", + "type": "object", + "properties": { + "code": { + "description": "A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification.", + "allOf": [ + { + "$ref": "#/$defs/ErrorCode" + } ] }, - "additionalDirectories": { - "description": "Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", - "items": { - "type": "string" - }, - "type": "array" - }, - "cwd": { - "description": "The working directory for this session. Must be an absolute path.", + "message": { + "description": "A string providing a short description of the error.\nThe message should be limited to a concise single sentence.", "type": "string" }, - "mcpServers": { - "description": "List of MCP (Model Context Protocol) servers the agent should connect to.", - "items": { - "$ref": "#/$defs/McpServer" - }, - "type": "array" + "data": { + "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." } }, "required": [ - "cwd", - "mcpServers" - ], - "type": "object", - "x-method": "session/new", - "x-side": "agent" + "code", + "message" + ] }, - "NewSessionResponse": { - "description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "ErrorCode": { + "description": "Predefined error codes for common JSON-RPC and ACP-specific errors.\n\nThese codes follow the JSON-RPC 2.0 specification for standard errors\nand use the reserved range (-32000 to -32099) for protocol-specific errors.", + "anyOf": [ + { + "title": "Parse error", + "description": "**Parse error**: Invalid JSON was received by the server.\nAn error occurred on the server while parsing the JSON text.", + "type": "integer", + "format": "int32", + "const": -32700 }, - "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, - "type": [ - "array", - "null" - ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + { + "title": "Invalid request", + "description": "**Invalid request**: The JSON sent is not a valid Request object.", + "type": "integer", + "format": "int32", + "const": -32600 }, - "modes": { + { + "title": "Method not found", + "description": "**Method not found**: The method does not exist or is not available.", + "type": "integer", + "format": "int32", + "const": -32601 + }, + { + "title": "Invalid params", + "description": "**Invalid params**: Invalid method parameter(s).", + "type": "integer", + "format": "int32", + "const": -32602 + }, + { + "title": "Internal error", + "description": "**Internal error**: Internal JSON-RPC error.\nReserved for implementation-defined server errors.", + "type": "integer", + "format": "int32", + "const": -32603 + }, + { + "title": "Request cancelled", + "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", + "type": "integer", + "format": "int32", + "const": -32800 + }, + { + "title": "Authentication required", + "description": "**Authentication required**: Authentication is required before this operation can be performed.", + "type": "integer", + "format": "int32", + "const": -32000 + }, + { + "title": "Resource not found", + "description": "**Resource not found**: A given resource, such as a file, was not found.", + "type": "integer", + "format": "int32", + "const": -32002 + }, + { + "title": "URL elicitation required", + "description": "**URL elicitation required**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe agent requires user input via a URL-based elicitation before it can proceed.", + "type": "integer", + "format": "int32", + "const": -32042 + }, + { + "title": "Other", + "description": "Other undefined error code.", + "type": "integer", + "format": "int32" + } + ] + }, + "AgentNotification": { + "description": "A JSON-RPC notification object.", + "type": "object", + "properties": { + "method": { + "description": "The notification method name.", + "type": "string" + }, + "params": { + "description": "Method-specific notification parameters.", "anyOf": [ { - "$ref": "#/$defs/SessionModeState" + "description": "All possible notifications that an agent can send to a client.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response.", + "anyOf": [ + { + "title": "SessionNotification", + "description": "Handles session update notifications from the agent.\n\nThis is a notification endpoint (no response expected) that receives\nreal-time updates about session progress, including message chunks,\ntool calls, and execution plans.\n\nNote: Clients SHOULD continue accepting tool call updates even after\nsending a `session/cancel` notification, as the agent may send final\nupdates before responding with the cancelled stop reason.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "allOf": [ + { + "$ref": "#/$defs/SessionNotification" + } + ] + }, + { + "title": "CompleteElicitationNotification", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification that a URL-based elicitation has completed.", + "allOf": [ + { + "$ref": "#/$defs/CompleteElicitationNotification" + } + ] + }, + { + "title": "MessageMcpNotification", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReceives an MCP-over-ACP notification.", + "allOf": [ + { + "$ref": "#/$defs/MessageMcpNotification" + } + ] + }, + { + "title": "ExtNotification", + "description": "Handles extension notifications from the agent.\n\nAllows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "allOf": [ + { + "$ref": "#/$defs/ExtNotification" + } + ] + } + ] }, { "type": "null" } - ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", - "x-deserialize-default-on-error": true - }, + ] + } + }, + "required": [ + "method" + ], + "x-docs-ignore": true + }, + "SessionNotification": { + "description": "Notification containing a session update from the agent.\n\nUsed to stream real-time progress and results during prompt processing.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "type": "object", + "properties": { "sessionId": { + "description": "The ID of the session this update pertains to.", "allOf": [ { "$ref": "#/$defs/SessionId" } + ] + }, + "update": { + "description": "The actual update content.", + "allOf": [ + { + "$ref": "#/$defs/SessionUpdate" + } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation." + "additionalProperties": true } }, "required": [ - "sessionId" + "sessionId", + "update" ], - "type": "object", - "x-method": "session/new", - "x-side": "agent" + "x-side": "client", + "x-method": "session/update" }, - "NumberPropertySchema": { - "description": "Schema for number (floating-point) properties in an elicitation form.", - "properties": { - "default": { - "description": "Default value.", - "format": "double", - "type": [ - "number", - "null" + "SessionUpdate": { + "description": "Different types of updates that can be sent during session processing.\n\nThese updates provide real-time feedback about the agent's progress.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "oneOf": [ + { + "description": "A chunk of the user's message being streamed.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "user_message_chunk" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } ] }, - "description": { - "description": "Human-readable description.", - "type": [ - "string", - "null" + { + "description": "A chunk of the agent's response being streamed.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "agent_message_chunk" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } ] }, - "maximum": { - "description": "Maximum value (inclusive).", - "format": "double", - "type": [ - "number", - "null" + { + "description": "A chunk of the agent's internal reasoning being streamed.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "agent_thought_chunk" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ContentChunk" + } ] }, - "minimum": { - "description": "Minimum value (inclusive).", - "format": "double", - "type": [ - "number", - "null" + { + "description": "Notification that a new tool call has been initiated.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "tool_call" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ToolCall" + } ] }, - "title": { - "description": "Optional title for the property.", - "type": [ - "string", - "null" + { + "description": "Update on the status or results of a tool call.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "tool_call_update" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ToolCallUpdate" + } ] - } - }, - "type": "object" - }, - "PermissionOption": { - "description": "An option presented to the user when requesting permission.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + }, + { + "description": "The agent's execution plan for complex tasks.\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "plan" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/Plan" + } ] }, - "kind": { + { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "plan_update" + } + }, + "required": [ + "sessionUpdate" + ], "allOf": [ { - "$ref": "#/$defs/PermissionOptionKind" + "$ref": "#/$defs/PlanUpdate" } + ] + }, + { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "plan_removed" + } + }, + "required": [ + "sessionUpdate" ], - "description": "Hint about the nature of this permission option." + "allOf": [ + { + "$ref": "#/$defs/PlanRemoved" + } + ] }, - "name": { - "description": "Human-readable label to display to the user.", - "type": "string" + { + "description": "Available commands are ready or have changed", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "available_commands_update" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/AvailableCommandsUpdate" + } + ] }, - "optionId": { + { + "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "current_mode_update" + } + }, + "required": [ + "sessionUpdate" + ], "allOf": [ { - "$ref": "#/$defs/PermissionOptionId" + "$ref": "#/$defs/CurrentModeUpdate" + } + ] + }, + { + "description": "Session configuration options have been updated.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "config_option_update" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/ConfigOptionUpdate" + } + ] + }, + { + "description": "Session metadata has been updated (title, timestamps, custom metadata)", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "session_info_update" + } + }, + "required": [ + "sessionUpdate" + ], + "allOf": [ + { + "$ref": "#/$defs/SessionInfoUpdate" + } + ] + }, + { + "description": "Context window and cost update for the session.", + "type": "object", + "properties": { + "sessionUpdate": { + "type": "string", + "const": "usage_update" } + }, + "required": [ + "sessionUpdate" ], - "description": "Unique identifier for this permission option." + "allOf": [ + { + "$ref": "#/$defs/UsageUpdate" + } + ] } - }, - "required": [ - "optionId", - "name", - "kind" ], - "type": "object" + "discriminator": { + "propertyName": "sessionUpdate" + } }, - "PermissionOptionId": { - "description": "Unique identifier for a permission option.", + "MessageId": { + "description": "Unique identifier for a message within a session.", "type": "string" }, - "PermissionOptionKind": { - "description": "The type of permission option being presented to the user.\n\nHelps clients choose appropriate icons and UI treatment.", - "oneOf": [ - { - "const": "allow_once", - "description": "Allow this operation only this time.", - "type": "string" - }, - { - "const": "allow_always", - "description": "Allow this operation and remember the choice.", - "type": "string" - }, - { - "const": "reject_once", - "description": "Reject this operation only this time.", - "type": "string" - }, - { - "const": "reject_always", - "description": "Reject this operation and remember the choice.", - "type": "string" - } - ] - }, - "Plan": { - "description": "An execution plan for accomplishing complex tasks.\n\nPlans consist of multiple entries representing individual tasks or goals.\nAgents report plans to clients to provide visibility into their execution strategy.\nPlans can evolve during execution as the agent discovers new requirements or completes tasks.\n\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "ContentChunk": { + "description": "A streamed item of content", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "content": { + "description": "A single item of content", + "allOf": [ + { + "$ref": "#/$defs/ContentBlock" + } + ] + }, + "messageId": { + "description": "A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.", + "anyOf": [ + { + "$ref": "#/$defs/MessageId" + }, + { + "type": "null" + } ] }, - "entries": { - "description": "The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update.", - "items": { - "$ref": "#/$defs/PlanEntry" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - } - }, - "required": [ - "entries" - ], - "type": "object" - }, - "PlanCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for receiving `plan_update` and `plan_removed` session updates.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "content" + ] }, - "PlanEntry": { - "description": "A single entry in the execution plan.\n\nRepresents a task or goal that the assistant intends to accomplish\nas part of fulfilling the user's request.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "ToolCall": { + "description": "Represents a tool call that the language model has requested.\n\nTool calls are actions that the agent executes on behalf of the language model,\nsuch as reading files, executing code, or fetching data from external sources.\n\nSee protocol docs: [Tool Calls](https://agentclientprotocol.com/protocol/tool-calls)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "toolCallId": { + "description": "Unique identifier for this tool call within the session.", + "allOf": [ + { + "$ref": "#/$defs/ToolCallId" + } ] }, - "content": { - "description": "Human-readable description of what this task aims to accomplish.", + "title": { + "description": "Human-readable title describing what the tool is doing.", "type": "string" }, - "priority": { + "kind": { + "description": "The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment.", "allOf": [ { - "$ref": "#/$defs/PlanEntryPriority" + "$ref": "#/$defs/ToolKind" } - ], - "description": "The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." + ] }, "status": { + "description": "Current execution status of the tool call.", "allOf": [ { - "$ref": "#/$defs/PlanEntryStatus" + "$ref": "#/$defs/ToolCallStatus" } - ], - "description": "Current execution status of this task." - } - }, - "required": [ - "content", - "priority", - "status" - ], - "type": "object" - }, - "PlanEntryPriority": { - "description": "Priority levels for plan entries.\n\nUsed to indicate the relative importance or urgency of different\ntasks in the execution plan.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", - "oneOf": [ - { - "const": "high", - "description": "High priority task - critical to the overall goal.", - "type": "string" - }, - { - "const": "medium", - "description": "Medium priority task - important but not critical.", - "type": "string" + ] }, - { - "const": "low", - "description": "Low priority task - nice to have but not essential.", - "type": "string" - } - ] - }, - "PlanEntryStatus": { - "description": "Status of a plan entry in the execution flow.\n\nTracks the lifecycle of each task from planning through completion.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", - "oneOf": [ - { - "const": "pending", - "description": "The task has not started yet.", - "type": "string" + "content": { + "description": "Content produced by the tool call.", + "type": "array", + "items": { + "$ref": "#/$defs/ToolCallContent" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - { - "const": "in_progress", - "description": "The task is currently being worked on.", - "type": "string" + "locations": { + "description": "File locations affected by this tool call.\nEnables \"follow-along\" features in clients.", + "type": "array", + "items": { + "$ref": "#/$defs/ToolCallLocation" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - { - "const": "completed", - "description": "The task has been successfully completed.", - "type": "string" - } - ] - }, - "PlanFile": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented by a file URI.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "rawInput": { + "description": "Raw input parameters sent to the tool." }, - "id": { - "allOf": [ - { - "$ref": "#/$defs/PlanId" - } - ], - "description": "The plan ID to update." + "rawOutput": { + "description": "Raw output returned by the tool." }, - "uri": { - "description": "The URI of the file containing the plan.", - "type": "string" - } - }, - "required": [ - "id", - "uri" - ], - "type": "object" - }, - "PlanId": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a plan within a session.", - "type": "string" - }, - "PlanItems": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as structured entries.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "entries": { - "description": "The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update.", - "items": { - "$ref": "#/$defs/PlanEntry" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "id": { - "allOf": [ - { - "$ref": "#/$defs/PlanId" - } ], - "description": "The plan ID to update." + "additionalProperties": true } }, "required": [ - "id", - "entries" - ], - "type": "object" + "toolCallId", + "title" + ] }, - "PlanMarkdown": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as raw markdown content.", + "PlanEntry": { + "description": "A single entry in the execution plan.\n\nRepresents a task or goal that the assistant intends to accomplish\nas part of fulfilling the user's request.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, "content": { - "description": "Markdown content for the plan.", + "description": "Human-readable description of what this task aims to accomplish.", "type": "string" }, - "id": { + "priority": { + "description": "The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal.", "allOf": [ { - "$ref": "#/$defs/PlanId" + "$ref": "#/$defs/PlanEntryPriority" } - ], - "description": "The plan ID to update." - } - }, - "required": [ - "id", - "content" - ], - "type": "object" - }, - "PlanRemoved": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] }, - "id": { + "status": { + "description": "Current execution status of this task.", "allOf": [ { - "$ref": "#/$defs/PlanId" + "$ref": "#/$defs/PlanEntryStatus" } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The plan ID to remove." + "additionalProperties": true } }, "required": [ - "id" - ], - "type": "object" + "content", + "priority", + "status" + ] }, - "PlanUpdate": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", + "PlanEntryPriority": { + "description": "Priority levels for plan entries.\n\nUsed to indicate the relative importance or urgency of different\ntasks in the execution plan.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "oneOf": [ + { + "description": "High priority task - critical to the overall goal.", + "type": "string", + "const": "high" + }, + { + "description": "Medium priority task - important but not critical.", + "type": "string", + "const": "medium" + }, + { + "description": "Low priority task - nice to have but not essential.", + "type": "string", + "const": "low" + } + ] + }, + "PlanEntryStatus": { + "description": "Status of a plan entry in the execution flow.\n\nTracks the lifecycle of each task from planning through completion.\nSee protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)", + "oneOf": [ + { + "description": "The task has not started yet.", + "type": "string", + "const": "pending" + }, + { + "description": "The task is currently being worked on.", + "type": "string", + "const": "in_progress" + }, + { + "description": "The task has been successfully completed.", + "type": "string", + "const": "completed" + } + ] + }, + "Plan": { + "description": "An execution plan for accomplishing complex tasks.\n\nPlans consist of multiple entries representing individual tasks or goals.\nAgents report plans to clients to provide visibility into their execution strategy.\nPlans can evolve during execution as the agent discovers new requirements or completes tasks.\n\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", + "type": "object", "properties": { + "entries": { + "description": "The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update.", + "type": "array", + "items": { + "$ref": "#/$defs/PlanEntry" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "plan": { - "allOf": [ - { - "$ref": "#/$defs/PlanUpdateContent" - } ], - "description": "The updated plan content." + "additionalProperties": true } }, "required": [ - "plan" - ], - "type": "object" + "entries" + ] }, "PlanUpdateContent": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUpdated content for a plan.", - "discriminator": { - "propertyName": "type" - }, "oneOf": [ { - "allOf": [ - { - "$ref": "#/$defs/PlanItems" - } - ], "description": "Structured plan entries.", + "type": "object", "properties": { "type": { - "const": "items", - "type": "string" + "type": "string", + "const": "items" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/PlanFile" + "$ref": "#/$defs/PlanItems" } - ], + ] + }, + { "description": "A URI pointing to a file containing the plan.", + "type": "object", "properties": { "type": { - "const": "file", - "type": "string" + "type": "string", + "const": "file" } }, "required": [ "type" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/PlanMarkdown" + "$ref": "#/$defs/PlanFile" } - ], + ] + }, + { "description": "Raw markdown content for the plan.", + "type": "object", "properties": { "type": { - "const": "markdown", - "type": "string" + "type": "string", + "const": "markdown" } }, "required": [ "type" ], - "type": "object" + "allOf": [ + { + "$ref": "#/$defs/PlanMarkdown" + } + ] } - ] + ], + "discriminator": { + "propertyName": "type" + } }, - "Position": { - "description": "A zero-based position in a text document.\n\nThe meaning of `character` depends on the negotiated position encoding.", + "PlanId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a plan within a session.", + "type": "string" + }, + "PlanItems": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as structured entries.", + "type": "object", "properties": { - "character": { - "description": "Zero-based character offset (encoding-dependent).", - "format": "uint32", - "minimum": 0, - "type": "integer" + "id": { + "description": "The plan ID to update.", + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ] }, - "line": { - "description": "Zero-based line number.", - "format": "uint32", - "minimum": 0, - "type": "integer" + "entries": { + "description": "The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update.", + "type": "array", + "items": { + "$ref": "#/$defs/PlanEntry" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "line", - "character" - ], - "type": "object" + "id", + "entries" + ] }, - "PositionEncodingKind": { - "description": "The encoding used for character offsets in positions.\n\nFollows the same conventions as LSP 3.17. The default is UTF-16.", - "oneOf": [ - { - "const": "utf-16", - "description": "Character offsets count UTF-16 code units. This is the default.", - "type": "string" + "PlanFile": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented by a file URI.", + "type": "object", + "properties": { + "id": { + "description": "The plan ID to update.", + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ] }, - { - "const": "utf-32", - "description": "Character offsets count Unicode code points.", + "uri": { + "description": "The URI of the file containing the plan.", "type": "string" }, - { - "const": "utf-8", - "description": "Character offsets count UTF-8 code units (bytes).", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } + }, + "required": [ + "id", + "uri" ] }, - "PromptCapabilities": { - "description": "Prompt capabilities supported by the agent in `session/prompt` requests.\n\nBaseline agent functionality requires support for [`ContentBlock::Text`]\nand [`ContentBlock::ResourceLink`] in prompt requests.\n\nOther variants must be explicitly opted in to.\nCapabilities for different types of content in prompt requests.\n\nIndicates which content types beyond the baseline (text and resource links)\nthe agent can process.\n\nSee protocol docs: [Prompt Capabilities](https://agentclientprotocol.com/protocol/initialization#prompt-capabilities)", + "PlanMarkdown": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as raw markdown content.", + "type": "object", "properties": { + "id": { + "description": "The plan ID to update.", + "allOf": [ + { + "$ref": "#/$defs/PlanId" + } + ] + }, + "content": { + "description": "Markdown content for the plan.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "audio": { - "default": false, - "description": "Agent supports [`ContentBlock::Audio`].", - "type": "boolean" - }, - "embeddedContext": { - "default": false, - "description": "Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", - "type": "boolean" - }, - "image": { - "default": false, - "description": "Agent supports [`ContentBlock::Image`].", - "type": "boolean" + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "id", + "content" + ] }, - "PromptRequest": { - "description": "Request parameters for sending a user prompt to the agent.\n\nContains the user's message and any additional context.\n\nSee protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)", + "PlanUpdate": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", + "type": "object", "properties": { + "plan": { + "description": "The updated plan content.", + "allOf": [ + { + "$ref": "#/$defs/PlanUpdateContent" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "prompt": { - "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", - "items": { - "$ref": "#/$defs/ContentBlock" - }, - "type": "array" - }, - "sessionId": { + ], + "additionalProperties": true + } + }, + "required": [ + "plan" + ] + }, + "PlanRemoved": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", + "type": "object", + "properties": { + "id": { + "description": "The plan ID to remove.", "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/PlanId" } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the session to send this user message to" + "additionalProperties": true } }, "required": [ - "sessionId", - "prompt" - ], - "type": "object", - "x-method": "session/prompt", - "x-side": "agent" + "id" + ] }, - "PromptResponse": { - "description": "Response from processing a user prompt.\n\nSee protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)", + "AvailableCommand": { + "description": "Information about a command.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "name": { + "description": "Command name (e.g., `create_plan`, `research_codebase`).", + "type": "string" }, - "stopReason": { - "allOf": [ - { - "$ref": "#/$defs/StopReason" - } - ], - "description": "Indicates why the agent stopped processing the turn." + "description": { + "description": "Human-readable description of what the command does.", + "type": "string" }, - "usage": { + "input": { + "description": "Input for the command if required", "anyOf": [ { - "$ref": "#/$defs/Usage" + "$ref": "#/$defs/AvailableCommandInput" }, { "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional).", "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "stopReason" - ], - "type": "object", - "x-method": "session/prompt", - "x-side": "agent" - }, - "ProtocolVersion": { - "description": "Protocol version identifier.\n\nThis version is only bumped for breaking changes.\nNon-breaking changes should be introduced via capabilities.", - "format": "uint16", - "maximum": 65535, - "minimum": 0, - "type": "integer" + "name", + "description" + ] }, - "ProviderCurrentConfig": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCurrent effective non-secret routing configuration for a provider.", - "properties": { - "apiType": { + "AvailableCommandInput": { + "description": "The input specification for a command.", + "anyOf": [ + { + "title": "unstructured", + "description": "All text that was typed after the command name is provided as input.", "allOf": [ { - "$ref": "#/$defs/LlmProtocol" + "$ref": "#/$defs/UnstructuredCommandInput" } - ], - "description": "Protocol currently used by this provider." - }, - "baseUrl": { - "description": "Base URL currently used by this provider.", - "type": "string" + ] } - }, - "required": [ - "apiType", - "baseUrl" - ], - "type": "object" + ] }, - "ProviderInfo": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a configurable LLM provider.", + "UnstructuredCommandInput": { + "description": "All text that was typed after the command name is provided as input.", + "type": "object", "properties": { + "hint": { + "description": "A hint to display when the input hasn't been provided yet", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "current": { - "anyOf": [ - { - "$ref": "#/$defs/ProviderCurrentConfig" - }, - { - "type": "null" - } ], - "description": "Current effective non-secret routing config.\nNull or omitted means provider is disabled." - }, - "id": { - "description": "Provider identifier, for example \"main\" or \"openai\".", - "type": "string" - }, - "required": { - "description": "Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id.", - "type": "boolean" - }, - "supported": { - "description": "Supported protocol types for this provider.", - "items": { - "$ref": "#/$defs/LlmProtocol" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "additionalProperties": true } }, "required": [ - "id", - "supported", - "required" - ], - "type": "object" + "hint" + ] }, - "ProvidersCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "AvailableCommandsUpdate": { + "description": "Available commands are ready or have changed", + "type": "object", "properties": { + "availableCommands": { + "description": "Commands the agent can execute", + "type": "array", + "items": { + "$ref": "#/$defs/AvailableCommand" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "availableCommands" + ] }, - "Range": { - "description": "A range in a text document, expressed as start and end positions.", + "CurrentModeUpdate": { + "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "type": "object", "properties": { - "end": { + "currentModeId": { + "description": "The ID of the current mode", "allOf": [ { - "$ref": "#/$defs/Position" + "$ref": "#/$defs/SessionModeId" } - ], - "description": "The end position (exclusive)." + ] }, - "start": { - "allOf": [ - { - "$ref": "#/$defs/Position" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The start position (inclusive)." + "additionalProperties": true } }, "required": [ - "start", - "end" - ], - "type": "object" + "currentModeId" + ] }, - "ReadTextFileRequest": { - "description": "Request to read content from a text file.\n\nOnly available if the client supports the `fs.readTextFile` capability.", + "ConfigOptionUpdate": { + "description": "Session configuration options have been updated.", + "type": "object", "properties": { + "configOptions": { + "description": "The full set of configuration options and their current values.", + "type": "array", + "items": { + "$ref": "#/$defs/SessionConfigOption" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "limit": { - "description": "Maximum number of lines to read.", - "format": "uint32", - "minimum": 0, + ], + "additionalProperties": true + } + }, + "required": [ + "configOptions" + ] + }, + "SessionInfoUpdate": { + "description": "Update to session metadata. All fields are optional to support partial updates.\n\nAgents send this notification to update session information like title or custom metadata.\nThis allows clients to display dynamic session names and track session state changes.", + "type": "object", + "properties": { + "title": { + "description": "Human-readable title for the session. Set to null to clear.", "type": [ - "integer", + "string", "null" ] }, - "line": { - "description": "Line number to start reading from (1-based).", - "format": "uint32", - "minimum": 0, + "updatedAt": { + "description": "ISO 8601 timestamp of last activity. Set to null to clear.", "type": [ - "integer", + "string", "null" ] }, - "path": { - "description": "Absolute path to the file to read.", - "type": "string" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The session ID for this request." - } - }, - "required": [ - "sessionId", - "path" - ], - "type": "object", - "x-method": "fs/read_text_file", - "x-side": "client" - }, - "ReadTextFileResponse": { - "description": "Response containing the contents of a text file.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "content": { - "type": "string" + ], + "additionalProperties": true } - }, - "required": [ - "content" - ], - "type": "object", - "x-method": "fs/read_text_file", - "x-side": "client" + } }, - "RejectNesNotification": { - "description": "Notification sent when a suggestion is rejected.", + "Cost": { + "description": "Cost information for a session.", + "type": "object", "properties": { + "amount": { + "description": "Total cumulative cost for session.", + "type": "number", + "format": "double" + }, + "currency": { + "description": "ISO 4217 currency code (e.g., \"USD\", \"EUR\").", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true + } + }, + "required": [ + "amount", + "currency" + ] + }, + "UsageUpdate": { + "description": "Context window and cost update for a session.", + "type": "object", + "properties": { + "used": { + "description": "Tokens currently in context.", + "type": "integer", + "format": "uint64", + "minimum": 0 }, - "id": { - "description": "The ID of the rejected suggestion.", - "type": "string" + "size": { + "description": "Total context window size in tokens.", + "type": "integer", + "format": "uint64", + "minimum": 0 }, - "reason": { + "cost": { + "description": "Cumulative session cost (optional).", "anyOf": [ { - "$ref": "#/$defs/NesRejectReason" + "$ref": "#/$defs/Cost" }, { "type": "null" } ], - "description": "The reason for rejection.", "x-deserialize-default-on-error": true }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The session ID for this notification." + "additionalProperties": true } }, "required": [ - "sessionId", - "id" - ], - "type": "object", - "x-method": "nes/reject", - "x-side": "agent" + "used", + "size" + ] }, - "ReleaseTerminalRequest": { - "description": "Request to release a terminal and free its resources.", + "CompleteElicitationNotification": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification sent by the agent when a URL-based elicitation is complete.", + "type": "object", "properties": { + "elicitationId": { + "description": "The ID of the elicitation that completed.", + "allOf": [ + { + "$ref": "#/$defs/ElicitationId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for this request." - }, - "terminalId": { - "description": "The ID of the terminal to release.", - "type": "string" + "additionalProperties": true } }, "required": [ - "sessionId", - "terminalId" + "elicitationId" ], - "type": "object", - "x-method": "terminal/release", - "x-side": "client" + "x-side": "client", + "x-method": "elicitation/complete" }, - "ReleaseTerminalResponse": { - "description": "Response to terminal/release method", + "MessageMcpNotification": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification parameters for `mcp/message`.\n\nThis is used when the wrapped MCP message is a notification and the outer JSON-RPC\nenvelope has no `id`.", + "type": "object", "properties": { + "connectionId": { + "description": "The MCP-over-ACP connection this message is sent on.", + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ] + }, + "method": { + "description": "The inner MCP method name.", + "type": "string" + }, + "params": { + "description": "Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params.", + "type": [ + "object", + "null" + ], + "additionalProperties": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "connectionId", + "method" + ], + "x-side": "both", + "x-method": "mcp/message" + }, + "ExtNotification": { + "description": "Allows the Agent to send an arbitrary notification that is not part of the ACP spec.\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)" + }, + "ClientRequest": { + "description": "A JSON-RPC request object.", + "type": "object", + "properties": { + "id": { + "description": "The request id used to correlate the matching response.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] + }, + "method": { + "description": "The method name to invoke.", + "type": "string" + }, + "params": { + "description": "Method-specific request parameters.", + "anyOf": [ + { + "description": "All possible requests that a client can send to an agent.\n\nThis enum is used internally for routing RPC requests. You typically won't need\nto use this directly.\n\nThis enum encompasses all method calls from client to agent.", + "anyOf": [ + { + "title": "InitializeRequest", + "description": "Establishes the connection with a client and negotiates protocol capabilities.\n\nThis method is called once at the beginning of the connection to:\n- Negotiate the protocol version to use\n- Exchange capability information between client and agent\n- Determine available authentication methods\n\nThe agent should respond with its supported protocol version and capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "allOf": [ + { + "$ref": "#/$defs/InitializeRequest" + } + ] + }, + { + "title": "AuthenticateRequest", + "description": "Authenticates the client using the specified authentication method.\n\nCalled when the agent requires authentication before allowing session creation.\nThe client provides the authentication method ID that was advertised during initialization.\n\nAfter successful authentication, the client can proceed to create sessions with\n`new_session` without receiving an `auth_required` error.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "allOf": [ + { + "$ref": "#/$defs/AuthenticateRequest" + } + ] + }, + { + "title": "ListProvidersRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nLists providers that can be configured by the client.", + "allOf": [ + { + "$ref": "#/$defs/ListProvidersRequest" + } + ] + }, + { + "title": "SetProviderRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nReplaces the configuration for a provider.", + "allOf": [ + { + "$ref": "#/$defs/SetProviderRequest" + } + ] + }, + { + "title": "DisableProviderRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nDisables a provider.", + "allOf": [ + { + "$ref": "#/$defs/DisableProviderRequest" + } + ] + }, + { + "title": "LogoutRequest", + "description": "Logs out of the current authenticated state.\n\nAfter a successful logout, all new sessions will require authentication.\nThere is no guarantee about the behavior of already running sessions.", + "allOf": [ + { + "$ref": "#/$defs/LogoutRequest" + } + ] + }, + { + "title": "NewSessionRequest", + "description": "Creates a new conversation session with the agent.\n\nSessions represent independent conversation contexts with their own history and state.\n\nThe agent should:\n- Create a new session context\n- Connect to any specified MCP servers\n- Return a unique session ID for future requests\n\nMay return an `auth_required` error if the agent requires authentication.\n\nSee protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)", + "allOf": [ + { + "$ref": "#/$defs/NewSessionRequest" + } + ] + }, + { + "title": "LoadSessionRequest", + "description": "Loads an existing session to resume a previous conversation.\n\nThis method is only available if the agent advertises the `loadSession` capability.\n\nThe agent should:\n- Restore the session context and conversation history\n- Connect to the specified MCP servers\n- Stream the entire conversation history back to the client via notifications\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "allOf": [ + { + "$ref": "#/$defs/LoadSessionRequest" + } + ] + }, + { + "title": "ListSessionsRequest", + "description": "Lists existing sessions known to the agent.\n\nThis method is only available if the agent advertises the `sessionCapabilities.list` capability.\n\nThe agent should return metadata about sessions with optional filtering and pagination support.", + "allOf": [ + { + "$ref": "#/$defs/ListSessionsRequest" + } + ] + }, + { + "title": "DeleteSessionRequest", + "description": "Deletes an existing session from `session/list`.\n\nThis method is only available if the agent advertises the `sessionCapabilities.delete` capability.", + "allOf": [ + { + "$ref": "#/$defs/DeleteSessionRequest" + } + ] + }, + { + "title": "ForkSessionRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForks an existing session to create a new independent session.\n\nThis method is only available if the agent advertises the `session.fork` capability.\n\nThe agent should create a new session with the same conversation context as the\noriginal, allowing operations like generating summaries without affecting the\noriginal session's history.", + "allOf": [ + { + "$ref": "#/$defs/ForkSessionRequest" + } + ] + }, + { + "title": "ResumeSessionRequest", + "description": "Resumes an existing session without returning previous messages.\n\nThis method is only available if the agent advertises the `sessionCapabilities.resume` capability.\n\nThe agent should resume the session context, allowing the conversation to continue\nwithout replaying the message history (unlike `session/load`).", + "allOf": [ + { + "$ref": "#/$defs/ResumeSessionRequest" + } + ] + }, + { + "title": "CloseSessionRequest", + "description": "Closes an active session and frees up any resources associated with it.\n\nThis method is only available if the agent advertises the `sessionCapabilities.close` capability.\n\nThe agent must cancel any ongoing work (as if `session/cancel` was called)\nand then free up any resources associated with the session.", + "allOf": [ + { + "$ref": "#/$defs/CloseSessionRequest" + } + ] + }, + { + "title": "SetSessionModeRequest", + "description": "Sets the current mode for a session.\n\nAllows switching between different agent modes (e.g., \"ask\", \"architect\", \"code\")\nthat affect system prompts, tool availability, and permission behaviors.\n\nThe mode must be one of the modes advertised in `availableModes` during session\ncreation or loading. Agents may also change modes autonomously and notify the\nclient via `current_mode_update` notifications.\n\nThis method can be called at any time during a session, whether the Agent is\nidle or actively generating a response.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "allOf": [ + { + "$ref": "#/$defs/SetSessionModeRequest" + } + ] + }, + { + "title": "SetSessionConfigOptionRequest", + "description": "Sets the current value for a session configuration option.", + "allOf": [ + { + "$ref": "#/$defs/SetSessionConfigOptionRequest" + } + ] + }, + { + "title": "PromptRequest", + "description": "Processes a user prompt within a session.\n\nThis method handles the whole lifecycle of a prompt:\n- Receives user messages with optional context (files, images, etc.)\n- Processes the prompt using language models\n- Reports language model content and tool calls to the Clients\n- Requests permission to run tools\n- Executes any requested tool calls\n- Returns when the turn is complete with a stop reason\n\nSee protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)", + "allOf": [ + { + "$ref": "#/$defs/PromptRequest" + } + ] + }, + { + "title": "StartNesRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nStarts an NES session.", + "allOf": [ + { + "$ref": "#/$defs/StartNesRequest" + } + ] + }, + { + "title": "SuggestNesRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequests a code suggestion.", + "allOf": [ + { + "$ref": "#/$defs/SuggestNesRequest" + } + ] + }, + { + "title": "CloseNesRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCloses an active NES session and frees up any resources associated with it.\n\nThe agent must cancel any ongoing work and then free up any resources\nassociated with the NES session.", + "allOf": [ + { + "$ref": "#/$defs/CloseNesRequest" + } + ] + }, + { + "title": "MessageMcpRequest", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExchanges an MCP-over-ACP message.", + "allOf": [ + { + "$ref": "#/$defs/MessageMcpRequest" + } + ] + }, + { + "title": "ExtMethodRequest", + "description": "Handles extension method requests from the client.\n\nExtension methods provide a way to add custom functionality while maintaining\nprotocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "allOf": [ + { + "$ref": "#/$defs/ExtRequest" + } + ] + } + ] + }, + { + "type": "null" + } ] } }, - "type": "object", - "x-method": "terminal/release", - "x-side": "client" - }, - "RequestId": { - "anyOf": [ - { - "title": "Null", - "type": "null" - }, - { - "format": "int64", - "title": "Number", - "type": "integer" - }, - { - "title": "Str", - "type": "string" - } + "required": [ + "id", + "method" ], - "description": "JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + "x-docs-ignore": true }, - "RequestPermissionOutcome": { - "description": "The outcome of a permission request.", - "discriminator": { - "propertyName": "outcome" - }, - "oneOf": [ - { - "description": "The prompt turn was cancelled before the user responded.\n\nWhen a client sends a `session/cancel` notification to cancel an ongoing\nprompt turn, it MUST respond to all pending `session/request_permission`\nrequests with this `Cancelled` outcome.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", - "properties": { - "outcome": { - "const": "cancelled", - "type": "string" - } - }, - "required": [ - "outcome" - ], - "type": "object" - }, - { + "InitializeRequest": { + "description": "Request parameters for the initialize method.\n\nSent by the client to establish connection and negotiate capabilities.\n\nSee protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)", + "type": "object", + "properties": { + "protocolVersion": { + "description": "The latest protocol version supported by the client.", "allOf": [ { - "$ref": "#/$defs/SelectedPermissionOutcome" - } - ], - "description": "The user selected one of the provided options.", - "properties": { - "outcome": { - "const": "selected", - "type": "string" + "$ref": "#/$defs/ProtocolVersion" } - }, - "required": [ - "outcome" - ], - "type": "object" - } - ] - }, - "RequestPermissionRequest": { - "description": "Request for user permission to execute a tool call.\n\nSent when the agent needs authorization before performing a sensitive operation.\n\nSee protocol docs: [Requesting Permission](https://agentclientprotocol.com/protocol/tool-calls#requesting-permission)", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" ] }, - "options": { - "description": "Available permission options for the user to choose from.", - "items": { - "$ref": "#/$defs/PermissionOption" + "clientCapabilities": { + "description": "Capabilities supported by the client.", + "default": { + "fs": { + "readTextFile": false, + "writeTextFile": false + }, + "terminal": false, + "auth": { + "terminal": false + } }, - "type": "array" - }, - "sessionId": { "allOf": [ { - "$ref": "#/$defs/SessionId" + "$ref": "#/$defs/ClientCapabilities" } - ], - "description": "The session ID for this request." + ] }, - "toolCall": { - "allOf": [ + "clientInfo": { + "description": "Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", + "anyOf": [ { - "$ref": "#/$defs/ToolCallUpdate" + "$ref": "#/$defs/Implementation" + }, + { + "type": "null" } ], - "description": "Details about the tool call requiring permission." - } - }, - "required": [ - "sessionId", - "toolCall", - "options" - ], - "type": "object", - "x-method": "session/request_permission", - "x-side": "client" - }, - "RequestPermissionResponse": { - "description": "Response to a permission request.", - "properties": { + "x-deserialize-default-on-error": true + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "outcome": { - "allOf": [ - { - "$ref": "#/$defs/RequestPermissionOutcome" - } ], - "description": "The user's decision on the permission request." + "additionalProperties": true } }, "required": [ - "outcome" + "protocolVersion" ], - "type": "object", - "x-method": "session/request_permission", - "x-side": "client" + "x-side": "agent", + "x-method": "initialize" }, - "ResourceLink": { - "description": "A resource that the server is capable of reading, included in a prompt or tool call result.", + "ClientCapabilities": { + "description": "Capabilities supported by the client.\n\nAdvertised during initialization to inform the agent about\navailable features and methods.\n\nSee protocol docs: [Client Capabilities](https://agentclientprotocol.com/protocol/initialization#client-capabilities)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "fs": { + "description": "File system capabilities supported by the client.\nDetermines which file operations the agent can request.", + "default": { + "readTextFile": false, + "writeTextFile": false + }, + "allOf": [ + { + "$ref": "#/$defs/FileSystemCapabilities" + } ] }, - "annotations": { + "terminal": { + "description": "Whether the Client support all `terminal/*` methods.", + "type": "boolean", + "default": false + }, + "session": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client.", "anyOf": [ { - "$ref": "#/$defs/Annotations" + "$ref": "#/$defs/ClientSessionCapabilities" }, { "type": "null" @@ -6617,2538 +6815,2856 @@ ], "x-deserialize-default-on-error": true }, - "description": { - "type": [ - "string", - "null" - ] - }, - "mimeType": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": "string" - }, - "size": { - "format": "int64", - "type": [ - "integer", - "null" - ] - }, - "title": { - "type": [ - "string", - "null" - ] + "plan": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types.", + "anyOf": [ + { + "$ref": "#/$defs/PlanCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "uri": { - "type": "string" - } - }, - "required": [ - "name", - "uri" - ], - "type": "object" - }, - "ResumeSessionRequest": { - "description": "Request parameters for resuming an existing session.\n\nResumes an existing session without returning previous messages (unlike `session/load`).\nThis is useful for agents that can resume sessions but don't implement full session loading.\n\nOnly available if the Agent supports the `sessionCapabilities.resume` capability.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "auth": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`.", + "default": { + "terminal": false + }, + "allOf": [ + { + "$ref": "#/$defs/AuthCapabilities" + } ] }, - "additionalDirectories": { - "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - "items": { - "type": "string" - }, - "type": "array" + "elicitation": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.", + "anyOf": [ + { + "$ref": "#/$defs/ElicitationCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "cwd": { - "description": "The working directory for this session.", - "type": "string" + "nes": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.", + "anyOf": [ + { + "$ref": "#/$defs/ClientNesCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true }, - "mcpServers": { - "description": "List of MCP servers to connect to for this session.", + "positionEncodings": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", + "type": "array", "items": { - "$ref": "#/$defs/McpServer" + "$ref": "#/$defs/PositionEncodingKind" }, - "type": "array" - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the session to resume." + "additionalProperties": true } - }, - "required": [ - "sessionId", - "cwd" - ], - "type": "object", - "x-method": "session/resume", - "x-side": "agent" + } }, - "ResumeSessionResponse": { - "description": "Response from resuming an existing session.", + "FileSystemCapabilities": { + "description": "File system capabilities that a client may support.\n\nSee protocol docs: [FileSystem](https://agentclientprotocol.com/protocol/initialization#filesystem)", + "type": "object", "properties": { + "readTextFile": { + "description": "Whether the Client supports `fs/read_text_file` requests.", + "type": "boolean", + "default": false + }, + "writeTextFile": { + "description": "Whether the Client supports `fs/write_text_file` requests.", + "type": "boolean", + "default": false + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, + ], + "additionalProperties": true + } + } + }, + "ClientSessionCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client.", + "type": "object", + "properties": { "configOptions": { - "description": "Initial session configuration options if supported by the Agent.", - "items": { - "$ref": "#/$defs/SessionConfigOption" - }, + "description": "Config option capabilities supported by the client.\n\nOmitted or `null` means the client does not advertise support for any\nconfig option extensions.", + "anyOf": [ + { + "$ref": "#/$defs/SessionConfigOptionsCapabilities" + }, + { + "type": "null" + } + ], + "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "array", + "object", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "modes": { + "additionalProperties": true + } + } + }, + "SessionConfigOptionsCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession configuration option capabilities supported by the client.", + "type": "object", + "properties": { + "boolean": { + "description": "Whether the client supports boolean session configuration options.\n\nOmitted or `null` means the client does not advertise support.\nSupplying `{}` means agents may include `type: \"boolean\"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: \"boolean\"` and a boolean `value`.", "anyOf": [ { - "$ref": "#/$defs/SessionModeState" + "$ref": "#/$defs/BooleanConfigOptionCapabilities" }, { "type": "null" } ], - "description": "Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - }, - "type": "object", - "x-method": "session/resume", - "x-side": "agent" - }, - "Role": { - "description": "The sender or recipient of messages and data in a conversation.", - "enum": [ - "assistant", - "user" - ], - "type": "string" + } }, - "SelectedPermissionOutcome": { - "description": "The user selected one of the provided options.", + "BooleanConfigOptionCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for boolean session configuration options.\n\nSupplying `{}` means the client supports boolean session configuration options.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "optionId": { - "allOf": [ - { - "$ref": "#/$defs/PermissionOptionId" - } ], - "description": "The ID of the option the user selected." + "additionalProperties": true } - }, - "required": [ - "optionId" - ], - "type": "object" + } }, - "SessionAdditionalDirectoriesCapabilities": { - "description": "Capabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", + "PlanCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for receiving `plan_update` and `plan_removed` session updates.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object" + } }, - "SessionCapabilities": { - "description": "Session capabilities supported by the agent.\n\nAs a baseline, all Agents **MUST** support `session/new`, `session/prompt`, `session/cancel`, and `session/update`.\n\nOptionally, they **MAY** support other session methods and notifications by specifying additional capabilities.\n\nNote: `session/load` is still handled by the top-level `load_session` capability. This will be unified in future versions of the protocol.\n\nSee protocol docs: [Session Capabilities](https://agentclientprotocol.com/protocol/initialization#session-capabilities)", + "AuthCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\n\nAdvertised during initialization to inform the agent which authentication\nmethod types the client can handle. This governs opt-in types that require\nadditional client-side support.", + "type": "object", "properties": { + "terminal": { + "description": "Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods.", + "type": "boolean", + "default": false + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "additionalDirectories": { + ], + "additionalProperties": true + } + } + }, + "ElicitationCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.", + "type": "object", + "properties": { + "form": { + "description": "Whether the client supports form-based elicitation.", "anyOf": [ { - "$ref": "#/$defs/SessionAdditionalDirectoriesCapabilities" + "$ref": "#/$defs/ElicitationFormCapabilities" }, { "type": "null" } ], - "description": "Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", "x-deserialize-default-on-error": true }, - "close": { + "url": { + "description": "Whether the client supports URL-based elicitation.", "anyOf": [ { - "$ref": "#/$defs/SessionCloseCapabilities" + "$ref": "#/$defs/ElicitationUrlCapabilities" }, { "type": "null" } ], - "description": "Whether the agent supports `session/close`.", "x-deserialize-default-on-error": true }, - "delete": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "ElicitationFormCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation capabilities.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "ElicitationUrlCapabilities": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation capabilities.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + } + }, + "ClientNesCapabilities": { + "description": "NES capabilities advertised by the client during initialization.", + "type": "object", + "properties": { + "jump": { + "description": "Whether the client supports the `jump` suggestion kind.", "anyOf": [ { - "$ref": "#/$defs/SessionDeleteCapabilities" + "$ref": "#/$defs/NesJumpCapabilities" }, { "type": "null" } ], - "description": "Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", "x-deserialize-default-on-error": true }, - "fork": { + "rename": { + "description": "Whether the client supports the `rename` suggestion kind.", "anyOf": [ { - "$ref": "#/$defs/SessionForkCapabilities" + "$ref": "#/$defs/NesRenameCapabilities" }, { "type": "null" } ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.", "x-deserialize-default-on-error": true }, - "list": { + "searchAndReplace": { + "description": "Whether the client supports the `searchAndReplace` suggestion kind.", "anyOf": [ { - "$ref": "#/$defs/SessionListCapabilities" + "$ref": "#/$defs/NesSearchAndReplaceCapabilities" }, { "type": "null" } ], - "description": "Whether the agent supports `session/list`.", "x-deserialize-default-on-error": true }, - "resume": { - "anyOf": [ - { - "$ref": "#/$defs/SessionResumeCapabilities" - }, - { - "type": "null" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Whether the agent supports `session/resume`.", - "x-deserialize-default-on-error": true + "additionalProperties": true } - }, - "type": "object" + } }, - "SessionCloseCapabilities": { - "description": "Capabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", + "NesJumpCapabilities": { + "description": "Marker for jump suggestion support.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - } - }, - "type": "object" - }, - "SessionConfigBoolean": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", - "properties": { - "currentValue": { - "description": "The current value of the boolean option.", - "type": "boolean" - } - }, - "required": [ - "currentValue" - ], - "type": "object" - }, - "SessionConfigGroupId": { - "description": "Unique identifier for a session configuration option value group.", - "type": "string" - }, - "SessionConfigId": { - "description": "Unique identifier for a session configuration option.", - "type": "string" - }, - "SessionConfigOption": { - "description": "A session configuration option selector and its current state.", - "discriminator": { - "propertyName": "type" - }, - "oneOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigSelect" - } - ], - "description": "Single-value selector (dropdown).", - "properties": { - "type": { - "const": "select", - "type": "string" - } - }, - "required": [ - "type" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigBoolean" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", - "properties": { - "type": { - "const": "boolean", - "type": "string" - } - }, - "required": [ - "type" ], - "type": "object" + "additionalProperties": true } - ], + } + }, + "NesRenameCapabilities": { + "description": "Marker for rename suggestion support.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "category": { - "anyOf": [ - { - "$ref": "#/$defs/SessionConfigOptionCategory" - }, - { - "type": "null" - } ], - "description": "Optional semantic category for this option (UX only).", - "x-deserialize-default-on-error": true - }, - "description": { - "description": "Optional description for the Client to display to the user.", + "additionalProperties": true + } + } + }, + "NesSearchAndReplaceCapabilities": { + "description": "Marker for search and replace suggestion support.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] - }, - "id": { + ], + "additionalProperties": true + } + } + }, + "AuthenticateRequest": { + "description": "Request parameters for the authenticate method.\n\nSpecifies which authentication method to use.", + "type": "object", + "properties": { + "methodId": { + "description": "The ID of the authentication method to use.\nMust be one of the methods advertised in the initialize response.", "allOf": [ { - "$ref": "#/$defs/SessionConfigId" + "$ref": "#/$defs/AuthMethodId" } - ], - "description": "Unique identifier for the configuration option." + ] }, - "name": { - "description": "Human-readable label for the option.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "id", - "name" + "methodId" ], - "type": "object" + "x-side": "agent", + "x-method": "authenticate" }, - "SessionConfigOptionCategory": { - "anyOf": [ - { - "const": "mode", - "description": "Session mode selector.", - "type": "string" - }, - { - "const": "model", - "description": "Model selector.", - "type": "string" - }, - { - "const": "thought_level", - "description": "Thought/reasoning level selector.", - "type": "string" - }, - { - "description": "Unknown / uncategorized selector.", - "title": "other", - "type": "string" + "ListProvidersRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/list`.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - ], - "description": "Semantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec." + }, + "x-side": "agent", + "x-method": "providers/list" }, - "SessionConfigSelect": { - "description": "A single-value selector (dropdown) session configuration option payload.", + "SetProviderRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider id.", + "type": "object", "properties": { - "currentValue": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } - ], - "description": "The currently selected value." + "id": { + "description": "Provider id to configure.", + "type": "string" }, - "options": { + "apiType": { + "description": "Protocol type for this provider.", "allOf": [ { - "$ref": "#/$defs/SessionConfigSelectOptions" + "$ref": "#/$defs/LlmProtocol" } + ] + }, + "baseUrl": { + "description": "Base URL for requests sent through this provider.", + "type": "string" + }, + "headers": { + "description": "Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The set of selectable options." + "additionalProperties": true } }, "required": [ - "currentValue", - "options" + "id", + "apiType", + "baseUrl" ], - "type": "object" + "x-side": "agent", + "x-method": "providers/set" }, - "SessionConfigSelectGroup": { - "description": "A group of possible values for a session configuration option.", + "DisableProviderRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/disable`.", + "type": "object", "properties": { + "id": { + "description": "Provider id to disable.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "group": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigGroupId" - } ], - "description": "Unique identifier for this group." - }, - "name": { - "description": "Human-readable label for this group.", - "type": "string" - }, - "options": { - "description": "The set of option values in this group.", - "items": { - "$ref": "#/$defs/SessionConfigSelectOption" - }, - "type": "array" + "additionalProperties": true } }, "required": [ - "group", - "name", - "options" + "id" ], - "type": "object" + "x-side": "agent", + "x-method": "providers/disable" }, - "SessionConfigSelectOption": { - "description": "A possible value for a session configuration option.", + "LogoutRequest": { + "description": "Request parameters for the logout method.\n\nTerminates the current authenticated session.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "logout" + }, + "NewSessionRequest": { + "description": "Request parameters for creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", + "type": "object", + "properties": { + "cwd": { + "description": "The working directory for this session. Must be an absolute path.", + "type": "string" }, - "description": { - "description": "Optional description for this option value.", - "type": [ - "string", - "null" - ] + "additionalDirectories": { + "description": "Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", + "type": "array", + "items": { + "type": "string" + } }, - "name": { - "description": "Human-readable label for this option value.", - "type": "string" + "mcpServers": { + "description": "List of MCP (Model Context Protocol) servers the agent should connect to.", + "type": "array", + "items": { + "$ref": "#/$defs/McpServer" + } }, - "value": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigValueId" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Unique identifier for this option value." + "additionalProperties": true } }, "required": [ - "value", - "name" + "cwd", + "mcpServers" ], - "type": "object" + "x-side": "agent", + "x-method": "session/new" }, - "SessionConfigSelectOptions": { + "McpServer": { + "description": "Configuration for connecting to an MCP (Model Context Protocol) server.\n\nMCP servers provide tools and context that the agent can use when\nprocessing prompts.\n\nSee protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers)", "anyOf": [ { - "description": "A flat list of options with no grouping.", - "items": { - "$ref": "#/$defs/SessionConfigSelectOption" + "description": "HTTP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.http` is `true`.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "http" + } }, - "title": "Ungrouped", - "type": "array" + "required": [ + "type" + ], + "allOf": [ + { + "$ref": "#/$defs/McpServerHttp" + } + ] }, { - "description": "A list of options grouped under headers.", - "items": { - "$ref": "#/$defs/SessionConfigSelectGroup" + "description": "SSE transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.sse` is `true`.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "sse" + } }, - "title": "Grouped", - "type": "array" + "required": [ + "type" + ], + "allOf": [ + { + "$ref": "#/$defs/McpServerSse" + } + ] + }, + { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration\n\nOnly available when the Agent capabilities indicate `mcp_capabilities.acp` is `true`.\nThe MCP server is provided by an ACP component and communicates over the ACP channel.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "acp" + } + }, + "required": [ + "type" + ], + "allOf": [ + { + "$ref": "#/$defs/McpServerAcp" + } + ] + }, + { + "title": "stdio", + "description": "Stdio transport configuration\n\nAll Agents MUST support this transport.", + "allOf": [ + { + "$ref": "#/$defs/McpServerStdio" + } + ] } - ], - "description": "Possible values for a session configuration option." - }, - "SessionConfigValueId": { - "description": "Unique identifier for a session configuration option value.", - "type": "string" + ] }, - "SessionDeleteCapabilities": { - "description": "Capabilities for the `session/delete` method.\n\nSupplying `{}` means the agent supports deleting sessions from `session/list`.", + "HttpHeader": { + "description": "An HTTP header to set when making requests to the MCP server.", + "type": "object", "properties": { + "name": { + "description": "The name of the HTTP header.", + "type": "string" + }, + "value": { + "description": "The value to set for the HTTP header.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "name", + "value" + ] }, - "SessionForkCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", + "McpServerHttp": { + "description": "HTTP transport configuration for MCP.", + "type": "object", "properties": { + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" + }, + "url": { + "description": "URL to the MCP server.", + "type": "string" + }, + "headers": { + "description": "HTTP headers to set when making requests to the MCP server.", + "type": "array", + "items": { + "$ref": "#/$defs/HttpHeader" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" - }, - "SessionId": { - "description": "A unique identifier for a conversation session between a client and agent.\n\nSessions maintain their own context, conversation history, and state,\nallowing multiple independent interactions with the same agent.\n\nSee protocol docs: [Session ID](https://agentclientprotocol.com/protocol/session-setup#session-id)", - "type": "string" + "required": [ + "name", + "url", + "headers" + ] }, - "SessionInfo": { - "description": "Information about a session returned by session/list", + "McpServerSse": { + "description": "SSE transport configuration for MCP.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "additionalDirectories": { - "description": "Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", - "items": { - "type": "string" - }, - "type": "array" - }, - "cwd": { - "description": "The working directory for this session. Must be an absolute path.", + "name": { + "description": "Human-readable name identifying this MCP server.", "type": "string" }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "Unique identifier for the session" + "url": { + "description": "URL to the MCP server.", + "type": "string" }, - "title": { - "description": "Human-readable title for the session", - "type": [ - "string", - "null" - ], - "x-deserialize-default-on-error": true + "headers": { + "description": "HTTP headers to set when making requests to the MCP server.", + "type": "array", + "items": { + "$ref": "#/$defs/HttpHeader" + } }, - "updatedAt": { - "description": "ISO 8601 timestamp of last activity", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" ], - "x-deserialize-default-on-error": true + "additionalProperties": true } }, "required": [ - "sessionId", - "cwd" - ], - "type": "object" + "name", + "url", + "headers" + ] }, - "SessionInfoUpdate": { - "description": "Update to session metadata. All fields are optional to support partial updates.\n\nAgents send this notification to update session information like title or custom metadata.\nThis allows clients to display dynamic session names and track session state changes.", + "McpServerAcp": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nACP transport configuration for MCP.\n\nThe MCP server is provided by an ACP component and communicates over the ACP channel\nusing `mcp/connect`, `mcp/message`, and `mcp/disconnect`.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" }, - "title": { - "description": "Human-readable title for the session. Set to null to clear.", - "type": [ - "string", - "null" + "id": { + "description": "Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection.", + "allOf": [ + { + "$ref": "#/$defs/McpServerAcpId" + } ] }, - "updatedAt": { - "description": "ISO 8601 timestamp of last activity. Set to null to clear.", - "type": [ - "string", - "null" - ] - } - }, - "type": "object" - }, - "SessionListCapabilities": { - "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "name", + "id" + ] }, - "SessionMode": { - "description": "A mode the agent can operate in.\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", + "McpServerStdio": { + "description": "Stdio transport configuration for MCP.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "name": { + "description": "Human-readable name identifying this MCP server.", + "type": "string" }, - "description": { - "type": [ - "string", - "null" - ] + "command": { + "description": "Path to the MCP server executable.", + "type": "string" }, - "id": { - "$ref": "#/$defs/SessionModeId" + "args": { + "description": "Command-line arguments to pass to the MCP server.", + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "description": "Environment variables to set when launching the MCP server.", + "type": "array", + "items": { + "$ref": "#/$defs/EnvVariable" + } }, - "name": { - "type": "string" - } - }, - "required": [ - "id", - "name" - ], - "type": "object" - }, - "SessionModeId": { - "description": "Unique identifier for a Session Mode.", - "type": "string" - }, - "SessionModeState": { - "description": "The set of modes and the one currently active.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "availableModes": { - "description": "The set of modes that the Agent can operate in", - "items": { - "$ref": "#/$defs/SessionMode" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "currentModeId": { - "allOf": [ - { - "$ref": "#/$defs/SessionModeId" - } ], - "description": "The current mode the Agent is in." + "additionalProperties": true } }, "required": [ - "currentModeId", - "availableModes" - ], - "type": "object" + "name", + "command", + "args", + "env" + ] }, - "SessionNotification": { - "description": "Notification containing a session update from the agent.\n\nUsed to stream real-time progress and results during prompt processing.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", + "LoadSessionRequest": { + "description": "Request parameters for loading an existing session.\n\nOnly available if the Agent supports the `loadSession` capability.\n\nSee protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "type": "array", + "items": { + "$ref": "#/$defs/McpServer" + } + }, + "cwd": { + "description": "The working directory for this session.", + "type": "string" + }, + "additionalDirectories": { + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + "type": "array", + "items": { + "type": "string" + } }, "sessionId": { + "description": "The ID of the session to load.", "allOf": [ { "$ref": "#/$defs/SessionId" } - ], - "description": "The ID of the session this update pertains to." + ] }, - "update": { - "allOf": [ - { - "$ref": "#/$defs/SessionUpdate" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The actual update content." + "additionalProperties": true } }, "required": [ - "sessionId", - "update" + "mcpServers", + "cwd", + "sessionId" ], - "type": "object", - "x-method": "session/update", - "x-side": "client" + "x-side": "agent", + "x-method": "session/load" }, - "SessionResumeCapabilities": { - "description": "Capabilities for the `session/resume` method.\n\nBy supplying `{}` it means that the agent supports resuming of sessions.", + "ListSessionsRequest": { + "description": "Request parameters for listing existing sessions.\n\nOnly available if the Agent supports the `sessionCapabilities.list` capability.", + "type": "object", "properties": { + "cwd": { + "description": "Filter sessions by working directory. Must be an absolute path.", + "type": [ + "string", + "null" + ] + }, + "cursor": { + "description": "Opaque cursor token from a previous response's nextCursor field for cursor-based pagination", + "type": [ + "string", + "null" + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "x-side": "agent", + "x-method": "session/list" }, - "SessionUpdate": { - "description": "Different types of updates that can be sent during session processing.\n\nThese updates provide real-time feedback about the agent's progress.\n\nSee protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)", - "discriminator": { - "propertyName": "sessionUpdate" - }, - "oneOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/ContentChunk" - } - ], - "description": "A chunk of the user's message being streamed.", - "properties": { - "sessionUpdate": { - "const": "user_message_chunk", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ContentChunk" - } - ], - "description": "A chunk of the agent's response being streamed.", - "properties": { - "sessionUpdate": { - "const": "agent_message_chunk", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ContentChunk" - } - ], - "description": "A chunk of the agent's internal reasoning being streamed.", - "properties": { - "sessionUpdate": { - "const": "agent_thought_chunk", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ToolCall" - } - ], - "description": "Notification that a new tool call has been initiated.", - "properties": { - "sessionUpdate": { - "const": "tool_call", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/ToolCallUpdate" - } - ], - "description": "Update on the status or results of a tool call.", - "properties": { - "sessionUpdate": { - "const": "tool_call_update", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { - "allOf": [ - { - "$ref": "#/$defs/Plan" - } - ], - "description": "The agent's execution plan for complex tasks.\nSee protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)", - "properties": { - "sessionUpdate": { - "const": "plan", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" - }, - { + "DeleteSessionRequest": { + "description": "Request parameters for deleting an existing session from `session/list`.\n\nOnly available if the Agent supports the `sessionCapabilities.delete` capability.", + "type": "object", + "properties": { + "sessionId": { + "description": "The ID of the session to delete.", "allOf": [ { - "$ref": "#/$defs/PlanUpdate" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA content update for a plan identified by ID.", - "properties": { - "sessionUpdate": { - "const": "plan_update", - "type": "string" + "$ref": "#/$defs/SessionId" } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + ] }, - { - "allOf": [ - { - "$ref": "#/$defs/PlanRemoved" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", - "properties": { - "sessionUpdate": { - "const": "plan_removed", - "type": "string" - } - }, - "required": [ - "sessionUpdate" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "type": "object" - }, - { + "additionalProperties": true + } + }, + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "session/delete" + }, + "ForkSessionRequest": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for forking an existing session.\n\nCreates a new session based on the context of an existing one, allowing\noperations like generating summaries without affecting the original session's history.\n\nOnly available if the Agent supports the `session.fork` capability.", + "type": "object", + "properties": { + "sessionId": { + "description": "The ID of the session to fork.", "allOf": [ { - "$ref": "#/$defs/AvailableCommandsUpdate" - } - ], - "description": "Available commands are ready or have changed", - "properties": { - "sessionUpdate": { - "const": "available_commands_update", - "type": "string" + "$ref": "#/$defs/SessionId" } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + ] }, - { - "allOf": [ - { - "$ref": "#/$defs/CurrentModeUpdate" - } - ], - "description": "The current mode of the session has changed\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)", - "properties": { - "sessionUpdate": { - "const": "current_mode_update", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + "cwd": { + "description": "The working directory for this session.", + "type": "string" }, - { - "allOf": [ - { - "$ref": "#/$defs/ConfigOptionUpdate" - } - ], - "description": "Session configuration options have been updated.", - "properties": { - "sessionUpdate": { - "const": "config_option_update", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + "additionalDirectories": { + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + "type": "array", + "items": { + "type": "string" + } }, - { - "allOf": [ - { - "$ref": "#/$defs/SessionInfoUpdate" - } - ], - "description": "Session metadata has been updated (title, timestamps, custom metadata)", - "properties": { - "sessionUpdate": { - "const": "session_info_update", - "type": "string" - } - }, - "required": [ - "sessionUpdate" - ], - "type": "object" + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "type": "array", + "items": { + "$ref": "#/$defs/McpServer" + } }, - { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "required": [ + "sessionId", + "cwd" + ], + "x-side": "agent", + "x-method": "session/fork" + }, + "ResumeSessionRequest": { + "description": "Request parameters for resuming an existing session.\n\nResumes an existing session without returning previous messages (unlike `session/load`).\nThis is useful for agents that can resume sessions but don't implement full session loading.\n\nOnly available if the Agent supports the `sessionCapabilities.resume` capability.", + "type": "object", + "properties": { + "sessionId": { + "description": "The ID of the session to resume.", "allOf": [ { - "$ref": "#/$defs/UsageUpdate" - } - ], - "description": "Context window and cost update for the session.", - "properties": { - "sessionUpdate": { - "const": "usage_update", - "type": "string" + "$ref": "#/$defs/SessionId" } - }, - "required": [ - "sessionUpdate" + ] + }, + "cwd": { + "description": "The working directory for this session.", + "type": "string" + }, + "additionalDirectories": { + "description": "Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + "type": "array", + "items": { + "type": "string" + } + }, + "mcpServers": { + "description": "List of MCP servers to connect to for this session.", + "type": "array", + "items": { + "$ref": "#/$defs/McpServer" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "type": "object" + "additionalProperties": true } - ] + }, + "required": [ + "sessionId", + "cwd" + ], + "x-side": "agent", + "x-method": "session/resume" }, - "SetProviderRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider id.", + "CloseSessionRequest": { + "description": "Request parameters for closing an active session.\n\nIf supported, the agent **must** cancel any ongoing work related to the session\n(treat it as if `session/cancel` was called) and then free up any resources\nassociated with the session.\n\nOnly available if the Agent supports the `sessionCapabilities.close` capability.", + "type": "object", "properties": { + "sessionId": { + "description": "The ID of the session to close.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "session/close" + }, + "SetSessionModeRequest": { + "description": "Request parameters for setting a session mode.", + "type": "object", + "properties": { + "sessionId": { + "description": "The ID of the session to set the mode for.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "apiType": { + "modeId": { + "description": "The ID of the mode to set.", "allOf": [ { - "$ref": "#/$defs/LlmProtocol" + "$ref": "#/$defs/SessionModeId" } - ], - "description": "Protocol type for this provider." - }, - "baseUrl": { - "description": "Base URL for requests sent through this provider.", - "type": "string" - }, - "headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers.", - "type": "object" + ] }, - "id": { - "description": "Provider id to configure.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "id", - "apiType", - "baseUrl" + "sessionId", + "modeId" ], - "type": "object", - "x-method": "providers/set", - "x-side": "agent" + "x-side": "agent", + "x-method": "session/set_mode" }, - "SetProviderResponse": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `providers/set`.", + "SetSessionConfigOptionRequest": { + "description": "Request parameters for setting a session configuration option.", + "type": "object", "properties": { + "sessionId": { + "description": "The ID of the session to set the configuration option for.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, + "configId": { + "description": "The ID of the configuration option to set.", + "allOf": [ + { + "$ref": "#/$defs/SessionConfigId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "providers/set", - "x-side": "agent" - }, - "SetSessionConfigOptionRequest": { + "required": [ + "sessionId", + "configId" + ], "anyOf": [ { "description": "A boolean value (`type: \"boolean\"`).", + "type": "object", "properties": { - "type": { - "const": "boolean", - "type": "string" - }, "value": { "description": "The boolean value.", "type": "boolean" + }, + "type": { + "type": "string", + "const": "boolean" } }, "required": [ "type", "value" - ], - "type": "object" + ] }, { + "title": "value_id", "description": "A [`SessionConfigValueId`] string value.\n\nThis is the default when `type` is absent on the wire. Unknown `type`\nvalues with string payloads also gracefully deserialize into this\nvariant.", + "type": "object", "properties": { "value": { + "description": "The value ID.", "allOf": [ { "$ref": "#/$defs/SessionConfigValueId" } - ], - "description": "The value ID." + ] } }, "required": [ "value" - ], - "title": "value_id", - "type": "object" + ] } ], - "description": "Request parameters for setting a session configuration option.", + "x-side": "agent", + "x-method": "session/set_config_option" + }, + "PromptRequest": { + "description": "Request parameters for sending a user prompt to the agent.\n\nContains the user's message and any additional context.\n\nSee protocol docs: [User Message](https://agentclientprotocol.com/protocol/prompt-turn#1-user-message)", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] - }, - "configId": { - "allOf": [ - { - "$ref": "#/$defs/SessionConfigId" - } - ], - "description": "The ID of the configuration option to set." - }, "sessionId": { + "description": "The ID of the session to send this user message to", "allOf": [ { "$ref": "#/$defs/SessionId" } + ] + }, + "prompt": { + "description": "The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to.", + "type": "array", + "items": { + "$ref": "#/$defs/ContentBlock" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the session to set the configuration option for." + "additionalProperties": true } }, "required": [ "sessionId", - "configId" + "prompt" ], - "type": "object", - "x-method": "session/set_config_option", - "x-side": "agent" + "x-side": "agent", + "x-method": "session/prompt" }, - "SetSessionConfigOptionResponse": { - "description": "Response to `session/set_config_option` method.", + "StartNesRequest": { + "description": "Request to start an NES session.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "workspaceUri": { + "description": "The root URI of the workspace.", "type": [ - "object", + "string", "null" ] }, - "configOptions": { - "description": "The full set of configuration options and their current values.", + "workspaceFolders": { + "description": "The workspace folders.", + "type": [ + "array", + "null" + ], "items": { - "$ref": "#/$defs/SessionConfigOption" + "$ref": "#/$defs/WorkspaceFolder" }, - "type": "array", "x-deserialize-default-on-error": true, "x-deserialize-skip-invalid-items": true - } - }, - "required": [ - "configOptions" - ], - "type": "object", - "x-method": "session/set_config_option", - "x-side": "agent" - }, - "SetSessionModeRequest": { - "description": "Request parameters for setting a session mode.", - "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] }, - "modeId": { - "allOf": [ + "repository": { + "description": "Repository metadata, if the workspace is a git repository.", + "anyOf": [ { - "$ref": "#/$defs/SessionModeId" + "$ref": "#/$defs/NesRepository" + }, + { + "type": "null" } ], - "description": "The ID of the mode to set." + "x-deserialize-default-on-error": true }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the session to set the mode for." - } - }, - "required": [ - "sessionId", - "modeId" - ], - "type": "object", - "x-method": "session/set_mode", - "x-side": "agent" + "additionalProperties": true + } + }, + "x-side": "agent", + "x-method": "nes/start" }, - "SetSessionModeResponse": { - "description": "Response to `session/set_mode` method.", + "WorkspaceFolder": { + "description": "A workspace folder.", + "type": "object", "properties": { + "uri": { + "description": "The URI of the folder.", + "type": "string" + }, + "name": { + "description": "The display name of the folder.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "session/set_mode", - "x-side": "agent" + "required": [ + "uri", + "name" + ] }, - "StartNesRequest": { - "description": "Request to start an NES session.", + "NesRepository": { + "description": "Repository metadata for an NES session.", + "type": "object", "properties": { + "name": { + "description": "The repository name.", + "type": "string" + }, + "owner": { + "description": "The repository owner.", + "type": "string" + }, + "remoteUrl": { + "description": "The remote URL of the repository.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "name", + "owner", + "remoteUrl" + ] + }, + "SuggestNesRequest": { + "description": "Request for a code suggestion.", + "type": "object", + "properties": { + "sessionId": { + "description": "The session ID for this request.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "repository": { + "uri": { + "description": "The URI of the document to suggest for.", + "type": "string" + }, + "version": { + "description": "The version number of the document.", + "type": "integer", + "format": "int64" + }, + "position": { + "description": "The current cursor position.", + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ] + }, + "selection": { + "description": "The current text selection range, if any.", "anyOf": [ { - "$ref": "#/$defs/NesRepository" + "$ref": "#/$defs/Range" }, { "type": "null" } ], - "description": "Repository metadata, if the workspace is a git repository.", "x-deserialize-default-on-error": true }, - "workspaceFolders": { - "description": "The workspace folders.", - "items": { - "$ref": "#/$defs/WorkspaceFolder" - }, - "type": [ - "array", - "null" + "triggerKind": { + "description": "What triggered this suggestion request.", + "allOf": [ + { + "$ref": "#/$defs/NesTriggerKind" + } + ] + }, + "context": { + "description": "Context for the suggestion, included based on agent capabilities.", + "anyOf": [ + { + "$ref": "#/$defs/NesSuggestContext" + }, + { + "type": "null" + } ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "x-deserialize-default-on-error": true }, - "workspaceUri": { - "description": "The root URI of the workspace.", - "type": [ - "string", - "null" - ] - } - }, - "type": "object", - "x-method": "nes/start", - "x-side": "agent" - }, - "StartNesResponse": { - "description": "Response to `nes/start`.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for the newly started NES session." + "additionalProperties": true } }, "required": [ - "sessionId" + "sessionId", + "uri", + "version", + "position", + "triggerKind" ], - "type": "object", - "x-method": "nes/start", - "x-side": "agent" - }, - "StopReason": { - "description": "Reasons why an agent stops processing a prompt turn.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/prompt-turn#stop-reasons)", - "oneOf": [ - { - "const": "end_turn", - "description": "The turn ended successfully.", - "type": "string" - }, - { - "const": "max_tokens", - "description": "The turn ended because the agent reached the maximum number of tokens.", - "type": "string" - }, - { - "const": "max_turn_requests", - "description": "The turn ended because the agent reached the maximum number of allowed\nagent requests between user turns.", - "type": "string" - }, - { - "const": "refusal", - "description": "The turn ended because the agent refused to continue. The user prompt\nand everything that comes after it won't be included in the next\nprompt, so this should be reflected in the UI.", - "type": "string" - }, - { - "const": "cancelled", - "description": "The turn was cancelled by the client via `session/cancel`.\n\nThis stop reason MUST be returned when the client sends a `session/cancel`\nnotification, even if the cancellation causes exceptions in underlying operations.\nAgents should catch these exceptions and return this semantically meaningful\nresponse to confirm successful cancellation.", - "type": "string" - } - ] + "x-side": "agent", + "x-method": "nes/suggest" }, - "StringFormat": { - "description": "String format types for string properties in elicitation schemas.", + "NesTriggerKind": { + "description": "What triggered the suggestion request.", "oneOf": [ { - "const": "email", - "description": "Email address format.", - "type": "string" - }, - { - "const": "uri", - "description": "URI format.", - "type": "string" + "description": "Triggered by user typing or cursor movement.", + "type": "string", + "const": "automatic" }, { - "const": "date", - "description": "Date format (YYYY-MM-DD).", - "type": "string" + "description": "Triggered by a diagnostic appearing at or near the cursor.", + "type": "string", + "const": "diagnostic" }, { - "const": "date-time", - "description": "Date-time format (ISO 8601).", - "type": "string" + "description": "Triggered by an explicit user action (keyboard shortcut).", + "type": "string", + "const": "manual" } ] }, - "StringPropertySchema": { - "description": "Schema for string properties in an elicitation form.\n\nWhen `enum` or `oneOf` is set, this represents a single-select enum\nwith `\"type\": \"string\"`.", + "NesSuggestContext": { + "description": "Context attached to a suggestion request.", + "type": "object", "properties": { - "default": { - "description": "Default value.", - "type": [ - "string", - "null" - ] - }, - "description": { - "description": "Human-readable description.", + "recentFiles": { + "description": "Recently accessed files.", "type": [ - "string", + "array", "null" - ] - }, - "enum": { - "description": "Enum values for untitled single-select enums.", + ], "items": { - "type": "string" + "$ref": "#/$defs/NesRecentFile" }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "relatedSnippets": { + "description": "Related code snippets.", "type": [ "array", "null" - ] - }, - "format": { - "anyOf": [ - { - "$ref": "#/$defs/StringFormat" - }, - { - "type": "null" - } ], - "description": "String format." + "items": { + "$ref": "#/$defs/NesRelatedSnippet" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "maxLength": { - "description": "Maximum string length.", - "format": "uint32", - "minimum": 0, + "editHistory": { + "description": "Recent edit history.", "type": [ - "integer", + "array", "null" - ] + ], + "items": { + "$ref": "#/$defs/NesEditHistoryEntry" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "minLength": { - "description": "Minimum string length.", - "format": "uint32", - "minimum": 0, + "userActions": { + "description": "Recent user actions (typing, navigation, etc.).", "type": [ - "integer", + "array", "null" - ] - }, - "oneOf": { - "description": "Titled enum options for titled single-select enums.", + ], "items": { - "$ref": "#/$defs/EnumOption" + "$ref": "#/$defs/NesUserAction" }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true + }, + "openFiles": { + "description": "Currently open files in the editor.", "type": [ "array", "null" - ] + ], + "items": { + "$ref": "#/$defs/NesOpenFile" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "pattern": { - "description": "Pattern the string must match.", + "diagnostics": { + "description": "Current diagnostics (errors, warnings).", "type": [ - "string", + "array", "null" - ] + ], + "items": { + "$ref": "#/$defs/NesDiagnostic" + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, - "title": { - "description": "Optional title for the property.", + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } - }, - "type": "object" + } }, - "SuggestNesRequest": { - "description": "Request for a code suggestion.", + "NesRecentFile": { + "description": "A recently accessed file.", + "type": "object", "properties": { + "uri": { + "description": "The URI of the file.", + "type": "string" + }, + "languageId": { + "description": "The language identifier.", + "type": "string" + }, + "text": { + "description": "The full text content of the file.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "context": { - "anyOf": [ - { - "$ref": "#/$defs/NesSuggestContext" - }, - { - "type": "null" - } - ], - "description": "Context for the suggestion, included based on agent capabilities.", - "x-deserialize-default-on-error": true - }, - "position": { - "allOf": [ - { - "$ref": "#/$defs/Position" - } - ], - "description": "The current cursor position." - }, - "selection": { - "anyOf": [ - { - "$ref": "#/$defs/Range" - }, - { - "type": "null" - } - ], - "description": "The current text selection range, if any.", - "x-deserialize-default-on-error": true - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } - ], - "description": "The session ID for this request." - }, - "triggerKind": { - "allOf": [ - { - "$ref": "#/$defs/NesTriggerKind" - } ], - "description": "What triggered this suggestion request." - }, - "uri": { - "description": "The URI of the document to suggest for.", - "type": "string" - }, - "version": { - "description": "The version number of the document.", - "format": "int64", - "type": "integer" + "additionalProperties": true } }, "required": [ - "sessionId", "uri", - "version", - "position", - "triggerKind" - ], - "type": "object", - "x-method": "nes/suggest", - "x-side": "agent" + "languageId", + "text" + ] }, - "SuggestNesResponse": { - "description": "Response to `nes/suggest`.", + "NesRelatedSnippet": { + "description": "A related code snippet from a file.", + "type": "object", "properties": { + "uri": { + "description": "The URI of the file containing the snippets.", + "type": "string" + }, + "excerpts": { + "description": "The code excerpts.", + "type": "array", + "items": { + "$ref": "#/$defs/NesExcerpt" + } + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "suggestions": { - "description": "The list of suggestions.", - "items": { - "$ref": "#/$defs/NesSuggestion" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + ], + "additionalProperties": true } }, "required": [ - "suggestions" - ], - "type": "object", - "x-method": "nes/suggest", - "x-side": "agent" + "uri", + "excerpts" + ] }, - "Terminal": { - "description": "Embed a terminal created with `terminal/create` by its id.\n\nThe terminal must be added before calling `terminal/release`.\n\nSee protocol docs: [Terminal](https://agentclientprotocol.com/protocol/terminals)", + "NesExcerpt": { + "description": "A code excerpt from a file.", + "type": "object", "properties": { + "startLine": { + "description": "The start line of the excerpt (zero-based).", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "endLine": { + "description": "The end line of the excerpt (zero-based).", + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "text": { + "description": "The text content of the excerpt.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "terminalId": { - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "terminalId" - ], - "type": "object" + "startLine", + "endLine", + "text" + ] }, - "TerminalExitStatus": { - "description": "Exit status of a terminal command.", + "NesEditHistoryEntry": { + "description": "An entry in the edit history.", + "type": "object", "properties": { + "uri": { + "description": "The URI of the edited file.", + "type": "string" + }, + "diff": { + "description": "A diff representing the edit.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "exitCode": { - "description": "The process exit code (may be null if terminated by signal).", - "format": "uint32", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "signal": { - "description": "The signal that terminated the process (may be null if exited normally).", - "type": [ - "string", - "null" - ] + ], + "additionalProperties": true } }, - "type": "object" + "required": [ + "uri", + "diff" + ] }, - "TerminalOutputRequest": { - "description": "Request to get the current output and status of a terminal.", + "NesUserAction": { + "description": "A user action (typing, cursor movement, etc.).", + "type": "object", "properties": { + "action": { + "description": "The kind of action (e.g., \"insertChar\", \"cursorMovement\").", + "type": "string" + }, + "uri": { + "description": "The URI of the file where the action occurred.", + "type": "string" + }, + "position": { + "description": "The position where the action occurred.", + "allOf": [ + { + "$ref": "#/$defs/Position" + } + ] + }, + "timestampMs": { + "description": "Timestamp in milliseconds since epoch.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "sessionId": { - "allOf": [ - { - "$ref": "#/$defs/SessionId" - } ], - "description": "The session ID for this request." - }, - "terminalId": { - "description": "The ID of the terminal to get output from.", - "type": "string" + "additionalProperties": true } }, "required": [ - "sessionId", - "terminalId" - ], - "type": "object", - "x-method": "terminal/output", - "x-side": "client" + "action", + "uri", + "position", + "timestampMs" + ] }, - "TerminalOutputResponse": { - "description": "Response containing the terminal output and exit status.", + "NesOpenFile": { + "description": "An open file in the editor.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" - ] + "uri": { + "description": "The URI of the file.", + "type": "string" }, - "exitStatus": { + "languageId": { + "description": "The language identifier.", + "type": "string" + }, + "visibleRange": { + "description": "The visible range in the editor, if any.", "anyOf": [ { - "$ref": "#/$defs/TerminalExitStatus" + "$ref": "#/$defs/Range" }, { "type": "null" } ], - "description": "Exit status if the command has completed." + "x-deserialize-default-on-error": true }, - "output": { - "description": "The terminal output captured so far.", - "type": "string" + "lastFocusedMs": { + "description": "Timestamp in milliseconds since epoch of when the file was last focused.", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0, + "x-deserialize-default-on-error": true }, - "truncated": { - "description": "Whether the output was truncated due to byte limits.", - "type": "boolean" - } - }, - "required": [ - "output", - "truncated" - ], - "type": "object", - "x-method": "terminal/output", - "x-side": "client" - }, - "TextContent": { - "description": "Text provided to or from an LLM.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/$defs/Annotations" - }, - { - "type": "null" - } ], - "x-deserialize-default-on-error": true - }, - "text": { - "type": "string" + "additionalProperties": true } }, "required": [ - "text" - ], - "type": "object" + "uri", + "languageId" + ] }, - "TextDocumentContentChangeEvent": { - "description": "A content change event for a document.\n\nWhen `range` is `None`, `text` is the full content of the document.\nWhen `range` is `Some`, `text` replaces the given range.", + "NesDiagnostic": { + "description": "A diagnostic (error, warning, etc.).", + "type": "object", "properties": { + "uri": { + "description": "The URI of the file containing the diagnostic.", + "type": "string" + }, "range": { - "anyOf": [ + "description": "The range of the diagnostic.", + "allOf": [ { "$ref": "#/$defs/Range" - }, + } + ] + }, + "severity": { + "description": "The severity of the diagnostic.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/NesDiagnosticSeverity" } - ], - "description": "The range of the document that changed. If `None`, the entire content is replaced." + ] }, - "text": { - "description": "The new text for the range, or the full document content if `range` is `None`.", + "message": { + "description": "The diagnostic message.", "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "text" - ], - "type": "object" + "uri", + "range", + "severity", + "message" + ] }, - "TextDocumentSyncKind": { - "description": "How the agent wants document changes delivered.", + "NesDiagnosticSeverity": { + "description": "Severity of a diagnostic.", "oneOf": [ { - "const": "full", - "description": "Client sends the entire file content on each change.", - "type": "string" + "description": "An error.", + "type": "string", + "const": "error" }, { - "const": "incremental", - "description": "Client sends only the changed ranges.", - "type": "string" + "description": "A warning.", + "type": "string", + "const": "warning" + }, + { + "description": "An informational message.", + "type": "string", + "const": "information" + }, + { + "description": "A hint.", + "type": "string", + "const": "hint" } ] }, - "TextResourceContents": { - "description": "Text-based resource contents.", + "CloseNesRequest": { + "description": "Request to close an NES session.\n\nThe agent **must** cancel any ongoing work related to the NES session\nand then free up any resources associated with the session.", + "type": "object", "properties": { + "sessionId": { + "description": "The ID of the NES session to close.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "mimeType": { - "type": [ - "string", - "null" - ] - }, - "text": { - "type": "string" - }, - "uri": { - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "text", - "uri" + "sessionId" ], - "type": "object" + "x-side": "agent", + "x-method": "nes/close" }, - "TitledMultiSelectItems": { - "description": "Items definition for titled multi-select enum properties.", - "properties": { - "anyOf": { - "description": "Titled enum options.", - "items": { - "$ref": "#/$defs/EnumOption" + "ClientResponse": { + "description": "A JSON-RPC response object.", + "anyOf": [ + { + "title": "Result", + "description": "A successful JSON-RPC response.", + "type": "object", + "properties": { + "id": { + "description": "The id of the request this response answers.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] + }, + "result": { + "description": "Method-specific response data.", + "anyOf": [ + { + "title": "WriteTextFileResponse", + "description": "Successful result returned for a `fs/write_text_file` request.", + "allOf": [ + { + "$ref": "#/$defs/WriteTextFileResponse" + } + ] + }, + { + "title": "ReadTextFileResponse", + "description": "Successful result returned for a `fs/read_text_file` request.", + "allOf": [ + { + "$ref": "#/$defs/ReadTextFileResponse" + } + ] + }, + { + "title": "RequestPermissionResponse", + "description": "Successful result returned for a `session/request_permission` request.", + "allOf": [ + { + "$ref": "#/$defs/RequestPermissionResponse" + } + ] + }, + { + "title": "CreateTerminalResponse", + "description": "Successful result returned for a `terminal/create` request.", + "allOf": [ + { + "$ref": "#/$defs/CreateTerminalResponse" + } + ] + }, + { + "title": "TerminalOutputResponse", + "description": "Successful result returned for a `terminal/output` request.", + "allOf": [ + { + "$ref": "#/$defs/TerminalOutputResponse" + } + ] + }, + { + "title": "ReleaseTerminalResponse", + "description": "Successful result returned for a `terminal/release` request.", + "allOf": [ + { + "$ref": "#/$defs/ReleaseTerminalResponse" + } + ] + }, + { + "title": "WaitForTerminalExitResponse", + "description": "Successful result returned for a `terminal/wait_for_exit` request.", + "allOf": [ + { + "$ref": "#/$defs/WaitForTerminalExitResponse" + } + ] + }, + { + "title": "KillTerminalResponse", + "description": "Successful result returned for a `terminal/kill` request.", + "allOf": [ + { + "$ref": "#/$defs/KillTerminalResponse" + } + ] + }, + { + "title": "CreateElicitationResponse", + "description": "Successful result returned for a `elicitation/create` request.", + "allOf": [ + { + "$ref": "#/$defs/CreateElicitationResponse" + } + ] + }, + { + "title": "ConnectMcpResponse", + "description": "Successful result returned for a `mcp/connect` request.", + "allOf": [ + { + "$ref": "#/$defs/ConnectMcpResponse" + } + ] + }, + { + "title": "DisconnectMcpResponse", + "description": "Successful result returned for a `mcp/disconnect` request.", + "allOf": [ + { + "$ref": "#/$defs/DisconnectMcpResponse" + } + ] + }, + { + "title": "ExtMethodResponse", + "description": "Successful result returned by an extension method outside the core ACP method set.", + "allOf": [ + { + "$ref": "#/$defs/ExtResponse" + } + ] + }, + { + "title": "MessageMcpResponse", + "description": "Successful result returned by an MCP-over-ACP `mcp/message` request.", + "allOf": [ + { + "$ref": "#/$defs/MessageMcpResponse" + } + ] + } + ] + } + }, + "required": [ + "id", + "result" + ] + }, + { + "title": "Error", + "description": "A failed JSON-RPC response.", + "type": "object", + "properties": { + "id": { + "description": "The id of the request this response answers.", + "allOf": [ + { + "$ref": "#/$defs/RequestId" + } + ] + }, + "error": { + "description": "Method-specific error data.", + "allOf": [ + { + "$ref": "#/$defs/Error" + } + ] + } }, - "type": "array" + "required": [ + "id", + "error" + ] } - }, - "required": [ - "anyOf" ], - "type": "object" + "x-docs-ignore": true }, - "ToolCall": { - "description": "Represents a tool call that the language model has requested.\n\nTool calls are actions that the agent executes on behalf of the language model,\nsuch as reading files, executing code, or fetching data from external sources.\n\nSee protocol docs: [Tool Calls](https://agentclientprotocol.com/protocol/tool-calls)", + "WriteTextFileResponse": { + "description": "Response to `fs/write_text_file`", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, + ], + "additionalProperties": true + } + }, + "x-side": "client", + "x-method": "fs/write_text_file" + }, + "ReadTextFileResponse": { + "description": "Response containing the contents of a text file.", + "type": "object", + "properties": { "content": { - "description": "Content produced by the tool call.", - "items": { - "$ref": "#/$defs/ToolCallContent" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + "description": "Content payload returned by this response.", + "type": "string" }, - "kind": { - "allOf": [ - { - "$ref": "#/$defs/ToolKind" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment." - }, - "locations": { - "description": "File locations affected by this tool call.\nEnables \"follow-along\" features in clients.", - "items": { - "$ref": "#/$defs/ToolCallLocation" - }, - "type": "array", - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "rawInput": { - "description": "Raw input parameters sent to the tool." - }, - "rawOutput": { - "description": "Raw output returned by the tool." - }, - "status": { + "additionalProperties": true + } + }, + "required": [ + "content" + ], + "x-side": "client", + "x-method": "fs/read_text_file" + }, + "RequestPermissionResponse": { + "description": "Response to a permission request.", + "type": "object", + "properties": { + "outcome": { + "description": "The user's decision on the permission request.", "allOf": [ { - "$ref": "#/$defs/ToolCallStatus" + "$ref": "#/$defs/RequestPermissionOutcome" } - ], - "description": "Current execution status of the tool call." - }, - "title": { - "description": "Human-readable title describing what the tool is doing.", - "type": "string" + ] }, - "toolCallId": { - "allOf": [ - { - "$ref": "#/$defs/ToolCallId" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "Unique identifier for this tool call within the session." + "additionalProperties": true } }, "required": [ - "toolCallId", - "title" + "outcome" ], - "type": "object" + "x-side": "client", + "x-method": "session/request_permission" }, - "ToolCallContent": { - "description": "Content produced by a tool call.\n\nTool calls can produce different types of content including\nstandard content blocks (text, images) or file diffs.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content)", - "discriminator": { - "propertyName": "type" - }, + "RequestPermissionOutcome": { + "description": "The outcome of a permission request.", "oneOf": [ { - "allOf": [ - { - "$ref": "#/$defs/Content" - } - ], - "description": "Standard content block (text, images, resources).", + "description": "The prompt turn was cancelled before the user responded.\n\nWhen a client sends a `session/cancel` notification to cancel an ongoing\nprompt turn, it MUST respond to all pending `session/request_permission`\nrequests with this `Cancelled` outcome.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "type": "object", "properties": { - "type": { - "const": "content", - "type": "string" + "outcome": { + "type": "string", + "const": "cancelled" } }, "required": [ - "type" - ], - "type": "object" + "outcome" + ] }, { - "allOf": [ - { - "$ref": "#/$defs/Diff" - } - ], - "description": "File modification shown as a diff.", + "description": "The user selected one of the provided options.", + "type": "object", "properties": { - "type": { - "const": "diff", - "type": "string" + "outcome": { + "type": "string", + "const": "selected" } }, "required": [ - "type" + "outcome" ], - "type": "object" - }, - { "allOf": [ { - "$ref": "#/$defs/Terminal" + "$ref": "#/$defs/SelectedPermissionOutcome" } - ], - "description": "Embed a terminal created with `terminal/create` by its id.\n\nThe terminal must be added before calling `terminal/release`.\n\nSee protocol docs: [Terminal](https://agentclientprotocol.com/protocol/terminals)", - "properties": { - "type": { - "const": "terminal", - "type": "string" + ] + } + ], + "discriminator": { + "propertyName": "outcome" + } + }, + "SelectedPermissionOutcome": { + "description": "The user selected one of the provided options.", + "type": "object", + "properties": { + "optionId": { + "description": "The ID of the option the user selected.", + "allOf": [ + { + "$ref": "#/$defs/PermissionOptionId" } - }, - "required": [ - "type" + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "type": "object" + "additionalProperties": true } + }, + "required": [ + "optionId" ] }, - "ToolCallId": { - "description": "Unique identifier for a tool call within a session.", - "type": "string" - }, - "ToolCallLocation": { - "description": "A file location being accessed or modified by a tool.\n\nEnables clients to implement \"follow-along\" features that track\nwhich files the agent is working with in real-time.\n\nSee protocol docs: [Following the Agent](https://agentclientprotocol.com/protocol/tool-calls#following-the-agent)", + "CreateTerminalResponse": { + "description": "Response containing the ID of the created terminal.", + "type": "object", "properties": { + "terminalId": { + "description": "The unique identifier for the created terminal.", + "allOf": [ + { + "$ref": "#/$defs/TerminalId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" + ], + "additionalProperties": true + } + }, + "required": [ + "terminalId" + ], + "x-side": "client", + "x-method": "terminal/create" + }, + "TerminalOutputResponse": { + "description": "Response containing the terminal output and exit status.", + "type": "object", + "properties": { + "output": { + "description": "The terminal output captured so far.", + "type": "string" + }, + "truncated": { + "description": "Whether the output was truncated due to byte limits.", + "type": "boolean" + }, + "exitStatus": { + "description": "Exit status if the command has completed.", + "anyOf": [ + { + "$ref": "#/$defs/TerminalExitStatus" + }, + { + "type": "null" + } ] }, - "line": { - "description": "Optional line number within the file.", - "format": "uint32", - "minimum": 0, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "path": { - "description": "The file path being accessed or modified.", - "type": "string" + ], + "additionalProperties": true } }, "required": [ - "path" + "output", + "truncated" ], - "type": "object" + "x-side": "client", + "x-method": "terminal/output" }, - "ToolCallStatus": { - "description": "Execution status of a tool call.\n\nTool calls progress through different statuses during their lifecycle.\n\nSee protocol docs: [Status](https://agentclientprotocol.com/protocol/tool-calls#status)", - "oneOf": [ - { - "const": "pending", - "description": "The tool call hasn't started running yet because the input is either\nstreaming or we're awaiting approval.", - "type": "string" - }, - { - "const": "in_progress", - "description": "The tool call is currently running.", - "type": "string" + "TerminalExitStatus": { + "description": "Exit status of a terminal command.", + "type": "object", + "properties": { + "exitCode": { + "description": "The process exit code (may be null if terminated by signal).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0 }, - { - "const": "completed", - "description": "The tool call completed successfully.", - "type": "string" + "signal": { + "description": "The signal that terminated the process (may be null if exited normally).", + "type": [ + "string", + "null" + ] }, - { - "const": "failed", - "description": "The tool call failed with an error.", - "type": "string" + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } - ] + } }, - "ToolCallUpdate": { - "description": "An update to an existing tool call.\n\nUsed to report progress and results as tools execute. All fields except\nthe tool call ID are optional - only changed fields need to be included.\n\nSee protocol docs: [Updating](https://agentclientprotocol.com/protocol/tool-calls#updating)", + "ReleaseTerminalResponse": { + "description": "Response to terminal/release method", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "content": { - "description": "Replace the content collection.", - "items": { - "$ref": "#/$defs/ToolCallContent" - }, - "type": [ - "array", - "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "kind": { - "anyOf": [ - { - "$ref": "#/$defs/ToolKind" - }, - { - "type": "null" - } - ], - "description": "Update the tool kind.", - "x-deserialize-default-on-error": true - }, - "locations": { - "description": "Replace the locations collection.", - "items": { - "$ref": "#/$defs/ToolCallLocation" - }, + "additionalProperties": true + } + }, + "x-side": "client", + "x-method": "terminal/release" + }, + "WaitForTerminalExitResponse": { + "description": "Response containing the exit status of a terminal command.", + "type": "object", + "properties": { + "exitCode": { + "description": "The process exit code (may be null if terminated by signal).", "type": [ - "array", + "integer", "null" ], - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true - }, - "rawInput": { - "description": "Update the raw input." - }, - "rawOutput": { - "description": "Update the raw output." - }, - "status": { - "anyOf": [ - { - "$ref": "#/$defs/ToolCallStatus" - }, - { - "type": "null" - } - ], - "description": "Update the execution status.", - "x-deserialize-default-on-error": true + "format": "uint32", + "minimum": 0 }, - "title": { - "description": "Update the human-readable title.", + "signal": { + "description": "The signal that terminated the process (may be null if exited normally).", "type": [ "string", "null" ] }, - "toolCallId": { - "allOf": [ - { - "$ref": "#/$defs/ToolCallId" - } + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The ID of the tool call being updated." + "additionalProperties": true } }, - "required": [ - "toolCallId" - ], - "type": "object" + "x-side": "client", + "x-method": "terminal/wait_for_exit" }, - "ToolKind": { - "description": "Categories of tools that can be invoked.\n\nTool kinds help clients choose appropriate icons and optimize how they\ndisplay tool execution progress.\n\nSee protocol docs: [Creating](https://agentclientprotocol.com/protocol/tool-calls#creating)", + "KillTerminalResponse": { + "description": "Response to `terminal/kill` method", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, + "x-side": "client", + "x-method": "terminal/kill" + }, + "CreateElicitationResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse from the client to an elicitation request.", + "type": "object", + "properties": { + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true + } + }, "oneOf": [ { - "const": "read", - "description": "Reading files or data.", - "type": "string" - }, - { - "const": "edit", - "description": "Modifying files or content.", - "type": "string" - }, - { - "const": "delete", - "description": "Removing files or data.", - "type": "string" + "description": "The user accepted and provided content.", + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "accept" + } + }, + "required": [ + "action" + ], + "allOf": [ + { + "$ref": "#/$defs/ElicitationAcceptAction" + } + ] }, { - "const": "move", - "description": "Moving or renaming files.", - "type": "string" + "description": "The user declined the elicitation.", + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "decline" + } + }, + "required": [ + "action" + ] }, { - "const": "search", - "description": "Searching for information.", - "type": "string" - }, + "description": "The elicitation was cancelled.", + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "cancel" + } + }, + "required": [ + "action" + ] + } + ], + "discriminator": { + "propertyName": "action" + }, + "x-side": "client", + "x-method": "elicitation/create" + }, + "ElicitationContentValue": { + "description": "Allowed wire representations for [`ElicitationContentValue`].", + "anyOf": [ { - "const": "execute", - "description": "Running commands or code.", + "title": "String", + "description": "String value accepted in elicitation response content.", "type": "string" }, { - "const": "think", - "description": "Internal reasoning or planning.", - "type": "string" + "title": "Integer", + "description": "Integer value accepted in elicitation response content.", + "type": "integer", + "format": "int64" }, { - "const": "fetch", - "description": "Retrieving external data.", - "type": "string" + "title": "Number", + "description": "Number value accepted in elicitation response content.", + "type": "number", + "format": "double" }, { - "const": "switch_mode", - "description": "Switching the current session mode.", - "type": "string" + "title": "Boolean", + "description": "Boolean value accepted in elicitation response content.", + "type": "boolean" }, { - "const": "other", - "description": "Other tool types (default).", - "type": "string" + "title": "StringArray", + "description": "String array value accepted in elicitation response content.", + "type": "array", + "items": { + "type": "string" + } } ] }, - "UnstructuredCommandInput": { - "description": "All text that was typed after the command name is provided as input.", + "ElicitationAcceptAction": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe user accepted the elicitation and provided content.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "content": { + "description": "The user-provided content, if any, as an object matching the requested schema.", "type": [ "object", "null" - ] - }, - "hint": { - "description": "A hint to display when the input hasn't been provided yet", - "type": "string" - } - }, - "required": [ - "hint" - ], - "type": "object" - }, - "UntitledMultiSelectItems": { - "description": "Items definition for untitled multi-select enum properties.", - "properties": { - "enum": { - "description": "Allowed enum values.", - "items": { - "type": "string" - }, - "type": "array" - }, - "type": { - "allOf": [ - { - "$ref": "#/$defs/ElicitationStringType" - } ], - "description": "Item type discriminator. Must be `\"string\"`." + "additionalProperties": { + "$ref": "#/$defs/ElicitationContentValue" + } } - }, - "required": [ - "type", - "enum" - ], - "type": "object" + } }, - "Usage": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage information for a prompt turn.", - "properties": { - "cachedReadTokens": { - "description": "Total cache read tokens.", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "cachedWriteTokens": { - "description": "Total cache write tokens.", - "format": "uint64", - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "inputTokens": { - "description": "Total input tokens across all turns.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "outputTokens": { - "description": "Total output tokens across all turns.", - "format": "uint64", - "minimum": 0, - "type": "integer" + "ConnectMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/connect`.", + "type": "object", + "properties": { + "connectionId": { + "description": "The unique identifier for this MCP-over-ACP connection.", + "allOf": [ + { + "$ref": "#/$defs/McpConnectionId" + } + ] }, - "thoughtTokens": { - "description": "Total thought/reasoning tokens", - "format": "uint64", - "minimum": 0, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "integer", + "object", "null" - ] - }, - "totalTokens": { - "description": "Sum of all token types across session.", - "format": "uint64", - "minimum": 0, - "type": "integer" + ], + "additionalProperties": true } }, "required": [ - "totalTokens", - "inputTokens", - "outputTokens" + "connectionId" ], - "type": "object" + "x-side": "client", + "x-method": "mcp/connect" }, - "UsageUpdate": { - "description": "Context window and cost update for a session.", + "DisconnectMcpResponse": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nResponse to `mcp/disconnect`.", + "type": "object", "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true + } + }, + "x-side": "client", + "x-method": "mcp/disconnect" + }, + "ClientNotification": { + "description": "A JSON-RPC notification object.", + "type": "object", + "properties": { + "method": { + "description": "The notification method name.", + "type": "string" }, - "cost": { + "params": { + "description": "Method-specific notification parameters.", "anyOf": [ { - "$ref": "#/$defs/Cost" + "description": "All possible notifications that a client can send to an agent.\n\nThis enum is used internally for routing RPC notifications. You typically won't need\nto use this directly.\n\nNotifications do not expect a response.", + "anyOf": [ + { + "title": "CancelNotification", + "description": "Cancels ongoing operations for a session.\n\nThis is a notification sent by the client to cancel an ongoing prompt turn.\n\nUpon receiving this notification, the Agent SHOULD:\n- Stop all language model requests as soon as possible\n- Abort all tool call invocations in progress\n- Send any pending `session/update` notifications\n- Respond to the original `session/prompt` request with `StopReason::Cancelled`\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "allOf": [ + { + "$ref": "#/$defs/CancelNotification" + } + ] + }, + { + "title": "DidOpenDocumentNotification", + "description": "**UNSTABLE**\n\nNotification sent when a file is opened in the editor.", + "allOf": [ + { + "$ref": "#/$defs/DidOpenDocumentNotification" + } + ] + }, + { + "title": "DidChangeDocumentNotification", + "description": "**UNSTABLE**\n\nNotification sent when a file is edited.", + "allOf": [ + { + "$ref": "#/$defs/DidChangeDocumentNotification" + } + ] + }, + { + "title": "DidCloseDocumentNotification", + "description": "**UNSTABLE**\n\nNotification sent when a file is closed.", + "allOf": [ + { + "$ref": "#/$defs/DidCloseDocumentNotification" + } + ] + }, + { + "title": "DidSaveDocumentNotification", + "description": "**UNSTABLE**\n\nNotification sent when a file is saved.", + "allOf": [ + { + "$ref": "#/$defs/DidSaveDocumentNotification" + } + ] + }, + { + "title": "DidFocusDocumentNotification", + "description": "**UNSTABLE**\n\nNotification sent when a file becomes the active editor tab.", + "allOf": [ + { + "$ref": "#/$defs/DidFocusDocumentNotification" + } + ] + }, + { + "title": "AcceptNesNotification", + "description": "**UNSTABLE**\n\nNotification sent when a suggestion is accepted.", + "allOf": [ + { + "$ref": "#/$defs/AcceptNesNotification" + } + ] + }, + { + "title": "RejectNesNotification", + "description": "**UNSTABLE**\n\nNotification sent when a suggestion is rejected.", + "allOf": [ + { + "$ref": "#/$defs/RejectNesNotification" + } + ] + }, + { + "title": "MessageMcpNotification", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSends an MCP-over-ACP notification.", + "allOf": [ + { + "$ref": "#/$defs/MessageMcpNotification" + } + ] + }, + { + "title": "ExtNotification", + "description": "Handles extension notifications from the client.\n\nExtension notifications provide a way to send one-way messages for custom functionality\nwhile maintaining protocol compatibility.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "allOf": [ + { + "$ref": "#/$defs/ExtNotification" + } + ] + } + ] }, { "type": "null" } - ], - "description": "Cumulative session cost (optional).", - "x-deserialize-default-on-error": true - }, - "size": { - "description": "Total context window size in tokens.", - "format": "uint64", - "minimum": 0, - "type": "integer" - }, - "used": { - "description": "Tokens currently in context.", - "format": "uint64", - "minimum": 0, - "type": "integer" + ] } }, "required": [ - "used", - "size" + "method" ], - "type": "object" + "x-docs-ignore": true }, - "WaitForTerminalExitRequest": { - "description": "Request to wait for a terminal command to exit.", + "CancelNotification": { + "description": "Notification to cancel ongoing operations for a session.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)", + "type": "object", "properties": { + "sessionId": { + "description": "The ID of the session to cancel operations for.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, + ], + "additionalProperties": true + } + }, + "required": [ + "sessionId" + ], + "x-side": "agent", + "x-method": "session/cancel" + }, + "DidOpenDocumentNotification": { + "description": "Notification sent when a file is opened in the editor.", + "type": "object", + "properties": { "sessionId": { + "description": "The session ID for this notification.", "allOf": [ { "$ref": "#/$defs/SessionId" } - ], - "description": "The session ID for this request." + ] }, - "terminalId": { - "description": "The ID of the terminal to wait for.", + "uri": { + "description": "The URI of the opened document.", + "type": "string" + }, + "languageId": { + "description": "The language identifier of the document (e.g., \"rust\", \"python\").", "type": "string" + }, + "version": { + "description": "The version number of the document.", + "type": "integer", + "format": "int64" + }, + "text": { + "description": "The full text content of the document.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ "sessionId", - "terminalId" + "uri", + "languageId", + "version", + "text" ], - "type": "object", - "x-method": "terminal/wait_for_exit", - "x-side": "client" + "x-side": "agent", + "x-method": "document/didOpen" }, - "WaitForTerminalExitResponse": { - "description": "Response containing the exit status of a terminal command.", + "DidChangeDocumentNotification": { + "description": "Notification sent when a file is edited.", + "type": "object", "properties": { - "_meta": { - "additionalProperties": true, - "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - "type": [ - "object", - "null" + "sessionId": { + "description": "The session ID for this notification.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } ] }, - "exitCode": { - "description": "The process exit code (may be null if terminated by signal).", - "format": "uint32", - "minimum": 0, - "type": [ - "integer", - "null" - ] + "uri": { + "description": "The URI of the changed document.", + "type": "string" }, - "signal": { - "description": "The signal that terminated the process (may be null if exited normally).", + "version": { + "description": "The new version number of the document.", + "type": "integer", + "format": "int64" + }, + "contentChanges": { + "description": "The content changes.", + "type": "array", + "items": { + "$ref": "#/$defs/TextDocumentContentChangeEvent" + } + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ - "string", + "object", "null" - ] + ], + "additionalProperties": true } }, - "type": "object", - "x-method": "terminal/wait_for_exit", - "x-side": "client" + "required": [ + "sessionId", + "uri", + "version", + "contentChanges" + ], + "x-side": "agent", + "x-method": "document/didChange" }, - "WorkspaceFolder": { - "description": "A workspace folder.", + "TextDocumentContentChangeEvent": { + "description": "A content change event for a document.\n\nWhen `range` is `None`, `text` is the full content of the document.\nWhen `range` is `Some`, `text` replaces the given range.", + "type": "object", "properties": { - "name": { - "description": "The display name of the folder.", + "range": { + "description": "The range of the document that changed. If `None`, the entire content is replaced.", + "anyOf": [ + { + "$ref": "#/$defs/Range" + }, + { + "type": "null" + } + ] + }, + "text": { + "description": "The new text for the range, or the full document content if `range` is `None`.", "type": "string" }, - "uri": { - "description": "The URI of the folder.", - "type": "string" - } - }, - "required": [ - "uri", - "name" - ], - "type": "object" - }, - "WriteTextFileRequest": { - "description": "Request to write content to a text file.\n\nOnly available if the client supports the `fs.writeTextFile` capability.", - "properties": { "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] - }, - "content": { - "description": "The text content to write to the file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file to write.", - "type": "string" - }, + ], + "additionalProperties": true + } + }, + "required": [ + "text" + ] + }, + "DidCloseDocumentNotification": { + "description": "Notification sent when a file is closed.", + "type": "object", + "properties": { "sessionId": { + "description": "The session ID for this notification.", "allOf": [ { "$ref": "#/$defs/SessionId" } + ] + }, + "uri": { + "description": "The URI of the closed document.", + "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "description": "The session ID for this request." + "additionalProperties": true } }, "required": [ "sessionId", - "path", - "content" + "uri" ], - "type": "object", - "x-method": "fs/write_text_file", - "x-side": "client" + "x-side": "agent", + "x-method": "document/didClose" }, - "WriteTextFileResponse": { - "description": "Response to `fs/write_text_file`", + "DidSaveDocumentNotification": { + "description": "Notification sent when a file is saved.", + "type": "object", "properties": { + "sessionId": { + "description": "The session ID for this notification.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, + "uri": { + "description": "The URI of the saved document.", + "type": "string" + }, "_meta": { - "additionalProperties": true, "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" - ] + ], + "additionalProperties": true } }, + "required": [ + "sessionId", + "uri" + ], + "x-side": "agent", + "x-method": "document/didSave" + }, + "DidFocusDocumentNotification": { + "description": "Notification sent when a file becomes the active editor tab.", "type": "object", - "x-method": "fs/write_text_file", - "x-side": "client" - } - }, - "$schema": "https://json-schema.org/draft/2020-12/schema", - "anyOf": [ - { - "anyOf": [ - { + "properties": { + "sessionId": { + "description": "The session ID for this notification.", "allOf": [ { - "$ref": "#/$defs/AgentRequest" + "$ref": "#/$defs/SessionId" } - ], - "title": "Request" + ] }, - { + "uri": { + "description": "The URI of the focused document.", + "type": "string" + }, + "version": { + "description": "The version number of the document.", + "type": "integer", + "format": "int64" + }, + "position": { + "description": "The current cursor position.", "allOf": [ { - "$ref": "#/$defs/AgentResponse" + "$ref": "#/$defs/Position" } - ], - "title": "Response" + ] }, - { + "visibleRange": { + "description": "The portion of the file currently visible in the editor viewport.", "allOf": [ { - "$ref": "#/$defs/AgentNotification" + "$ref": "#/$defs/Range" } + ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "title": "Notification" + "additionalProperties": true } + }, + "required": [ + "sessionId", + "uri", + "version", + "position", + "visibleRange" ], - "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", + "x-side": "agent", + "x-method": "document/didFocus" + }, + "AcceptNesNotification": { + "description": "Notification sent when a suggestion is accepted.", + "type": "object", "properties": { - "jsonrpc": { - "enum": [ - "2.0" - ], + "sessionId": { + "description": "The session ID for this notification.", + "allOf": [ + { + "$ref": "#/$defs/SessionId" + } + ] + }, + "id": { + "description": "The ID of the accepted suggestion.", "type": "string" + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "jsonrpc" + "sessionId", + "id" ], - "title": "Agent", - "type": "object" + "x-side": "agent", + "x-method": "nes/accept" }, - { - "anyOf": [ - { + "RejectNesNotification": { + "description": "Notification sent when a suggestion is rejected.", + "type": "object", + "properties": { + "sessionId": { + "description": "The session ID for this notification.", "allOf": [ { - "$ref": "#/$defs/ClientRequest" + "$ref": "#/$defs/SessionId" } - ], - "title": "Request" + ] }, - { - "allOf": [ - { - "$ref": "#/$defs/ClientResponse" - } - ], - "title": "Response" + "id": { + "description": "The ID of the rejected suggestion.", + "type": "string" }, - { - "allOf": [ + "reason": { + "description": "The reason for rejection.", + "anyOf": [ { - "$ref": "#/$defs/ClientNotification" + "$ref": "#/$defs/NesRejectReason" + }, + { + "type": "null" } ], - "title": "Notification" - } - ], - "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", - "properties": { - "jsonrpc": { - "enum": [ - "2.0" + "x-deserialize-default-on-error": true + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" ], - "type": "string" + "additionalProperties": true } }, "required": [ - "jsonrpc" + "sessionId", + "id" ], - "title": "Client", - "type": "object" + "x-side": "agent", + "x-method": "nes/reject" }, - { - "description": "A message (request, response, or notification) with `\"jsonrpc\": \"2.0\"` specified as\n[required by JSON-RPC 2.0 Specification][1].\n\n[1]: https://www.jsonrpc.org/specification#compatibility", - "properties": { - "jsonrpc": { - "enum": [ - "2.0" - ], - "type": "string" + "NesRejectReason": { + "description": "The reason a suggestion was rejected.", + "oneOf": [ + { + "description": "The user explicitly dismissed the suggestion.", + "type": "string", + "const": "rejected" }, - "method": { - "type": "string" + { + "description": "The suggestion was shown but the user continued editing without interacting.", + "type": "string", + "const": "ignored" }, - "params": { - "anyOf": [ - { - "anyOf": [ - { - "allOf": [ - { - "$ref": "#/$defs/CancelRequestNotification" - } - ], - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", - "title": "CancelRequestNotification" - } - ], - "description": "General protocol-level notifications that all sides are expected to\nimplement.\n\nNotifications whose methods start with '$/' are messages which\nare protocol implementation dependent and might not be implementable in all\nclients or agents. For example if the implementation uses a single threaded\nsynchronous programming language then there is little it can do to react to\na `$/cancel_request` notification. If an agent or client receives\nnotifications starting with '$/' it is free to ignore the notification.\n\nNotifications do not expect a response." - }, + { + "description": "The suggestion was superseded by a newer suggestion.", + "type": "string", + "const": "replaced" + }, + { + "description": "The request was cancelled before the agent returned a response.", + "type": "string", + "const": "cancelled" + } + ] + }, + "CancelRequestNotification": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification to cancel an ongoing request.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "type": "object", + "properties": { + "requestId": { + "description": "The ID of the request to cancel.", + "allOf": [ { - "type": "null" + "$ref": "#/$defs/RequestId" } ] + }, + "_meta": { + "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + "type": [ + "object", + "null" + ], + "additionalProperties": true } }, "required": [ - "jsonrpc", - "method" + "requestId" ], - "title": "ProtocolLevel", - "type": "object", - "x-docs-ignore": true + "x-side": "protocol", + "x-method": "$/cancel_request" } - ], - "title": "Agent Client Protocol" + } } diff --git a/scripts/gen_all.py b/scripts/gen_all.py index 43c32a6..de1cb52 100644 --- a/scripts/gen_all.py +++ b/scripts/gen_all.py @@ -5,6 +5,7 @@ import json import os import re +import subprocess import sys import urllib.error import urllib.request @@ -22,6 +23,8 @@ VERSION_FILE = SCHEMA_DIR / "VERSION" DEFAULT_REPO = "agentclientprotocol/agent-client-protocol" +LEGACY_SCHEMA_PATHS = ("schema/schema.unstable.json", "schema/meta.unstable.json") +V1_SCHEMA_PATHS = ("schema/v1/schema.unstable.json", "schema/v1/meta.unstable.json") def parse_args() -> argparse.Namespace: @@ -45,6 +48,12 @@ def parse_args() -> argparse.Namespace: help="Skip downloading schema files even when a version is provided.", ) parser.set_defaults(format_output=True) + parser.add_argument( + "--no-format", + dest="format_output", + action="store_false", + help="Skip formatting generated Python files after regeneration.", + ) parser.add_argument( "--force", action="store_true", @@ -73,6 +82,8 @@ def main() -> None: gen_schema.generate_schema() gen_meta.generate_meta() gen_signature.gen_signature(ROOT / "src" / "acp") + if args.format_output: + format_generated_files() if ref: print(f"Generated schema using ref: {ref}") @@ -80,6 +91,18 @@ def main() -> None: print("Generated schema using local schema files") +def format_generated_files() -> None: + files = [ + ROOT / "src" / "acp" / "schema.py", + ROOT / "src" / "acp" / "meta.py", + ROOT / "src" / "acp" / "interfaces.py", + ROOT / "src" / "acp" / "agent" / "connection.py", + ROOT / "src" / "acp" / "client" / "connection.py", + ] + subprocess.check_call([sys.executable, "-m", "ruff", "check", "--fix", *(str(path) for path in files)]) # noqa: S603 + subprocess.check_call([sys.executable, "-m", "ruff", "format", *(str(path) for path in files)]) # noqa: S603 + + def _should_download(args: argparse.Namespace, version: str | None) -> bool: env_override = os.environ.get("ACP_SCHEMA_DOWNLOAD") if env_override is not None: @@ -101,6 +124,8 @@ def resolve_ref(version: str | None) -> str: return "refs/heads/main" if version.startswith("refs/"): return version + if re.fullmatch(r"schema-v\d+\.\d+\.\d+", version): + return f"refs/tags/{version}" if re.fullmatch(r"v?\d+\.\d+\.\d+", version): value = version if version.startswith("v") else f"v{version}" return f"refs/tags/{value}" @@ -109,11 +134,8 @@ def resolve_ref(version: str | None) -> str: def download_schema(repo: str, ref: str) -> None: SCHEMA_DIR.mkdir(parents=True, exist_ok=True) - schema_url = f"https://raw.githubusercontent.com/{repo}/{ref}/schema/schema.unstable.json" - meta_url = f"https://raw.githubusercontent.com/{repo}/{ref}/schema/meta.unstable.json" try: - schema_data = fetch_json(schema_url) - meta_data = fetch_json(meta_url) + schema_data, meta_data = fetch_schema_pair(repo, ref) except RuntimeError as exc: # pragma: no cover - network error path print(exc, file=sys.stderr) sys.exit(1) @@ -124,6 +146,26 @@ def download_schema(repo: str, ref: str) -> None: print(f"Fetched schema and meta from {repo}@{ref}") +def fetch_schema_pair(repo: str, ref: str) -> tuple[dict, dict]: + errors = [] + for schema_path, meta_path in schema_source_paths(ref): + schema_url = f"https://raw.githubusercontent.com/{repo}/{ref}/{schema_path}" + meta_url = f"https://raw.githubusercontent.com/{repo}/{ref}/{meta_path}" + try: + return fetch_json(schema_url), fetch_json(meta_url) + except RuntimeError as exc: + errors.append(str(exc)) + + attempted = "\n".join(f"- {error}" for error in errors) + raise RuntimeError(f"Failed to fetch schema and meta from {repo}@{ref}. Attempts:\n{attempted}") + + +def schema_source_paths(ref: str) -> tuple[tuple[str, str], ...]: + if re.fullmatch(r"refs/tags/schema-v\d+\.\d+\.\d+", ref): + return (V1_SCHEMA_PATHS, LEGACY_SCHEMA_PATHS) + return (LEGACY_SCHEMA_PATHS, V1_SCHEMA_PATHS) + + def fetch_json(url: str) -> dict: try: with urllib.request.urlopen(url) as response: # noqa: S310 - trusted source configured by repo diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index ce26db4..571ad34 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -2,14 +2,17 @@ from __future__ import annotations import ast +import copy import json import re import subprocess import sys +import tempfile import textwrap from collections.abc import Callable from dataclasses import dataclass from pathlib import Path +from typing import Any ROOT = Path(__file__).resolve().parents[1] SCHEMA_DIR = ROOT / "schema" @@ -78,8 +81,10 @@ "ToolCallContent1": "ContentToolCallContent", "ToolCallContent2": "FileEditToolCallContent", "ToolCallContent3": "TerminalToolCallContent", - "CreateElicitationRequest1": "CreateFormElicitationRequest", - "CreateElicitationRequest2": "CreateUrlElicitationRequest", + "CreateElicitationRequest1": "CreateFormSessionElicitationRequest", + "CreateElicitationRequest2": "CreateFormRequestElicitationRequest", + "CreateElicitationRequest3": "CreateUrlSessionElicitationRequest", + "CreateElicitationRequest4": "CreateUrlRequestElicitationRequest", "CreateElicitationResponse1": "AcceptElicitationResponse", "CreateElicitationResponse2": "DeclineElicitationResponse", "CreateElicitationResponse3": "CancelElicitationResponse", @@ -215,31 +220,197 @@ def generate_schema() -> None: ) sys.exit(1) - cmd = [ - sys.executable, - "-m", - "datamodel_code_generator", - "--input", - str(SCHEMA_JSON), - "--input-file-type", - "jsonschema", - "--output", - str(SCHEMA_OUT), - "--target-python-version", - "3.12", - "--collapse-root-models", - "--output-model-type", - "pydantic_v2.BaseModel", - "--use-annotated", - "--snake-case-field", - ] + with tempfile.TemporaryDirectory() as tmp_dir: + codegen_input = Path(tmp_dir) / "schema.codegen.json" + codegen_input.write_text(json.dumps(_preprocess_schema_for_codegen(_load_schema()), indent=2), encoding="utf-8") + + cmd = [ + sys.executable, + "-m", + "datamodel_code_generator", + "--input", + str(codegen_input), + "--input-file-type", + "jsonschema", + "--output", + str(SCHEMA_OUT), + "--target-python-version", + "3.12", + "--collapse-root-models", + "--output-model-type", + "pydantic_v2.BaseModel", + "--use-annotated", + "--snake-case-field", + ] - subprocess.check_call(cmd) # noqa: S603 + subprocess.check_call(cmd) # noqa: S603 warnings = postprocess_generated_schema(SCHEMA_OUT) for warning in warnings: print(f"Warning: {warning}", file=sys.stderr) +def _load_schema() -> dict[str, Any]: + return json.loads(SCHEMA_JSON.read_text(encoding="utf-8")) + + +COMBINATOR_KEYS = ("oneOf", "anyOf") + + +def _preprocess_schema_for_codegen(schema: dict[str, Any]) -> dict[str, Any]: + defs = schema.get("$defs", {}) + return _distribute_composed_object_schemas(schema, defs) + + +def _distribute_composed_object_schemas(node: Any, defs: dict[str, Any]) -> Any: + if isinstance(node, list): + return [_distribute_composed_object_schemas(item, defs) for item in node] + if not isinstance(node, dict): + return node + + transformed = {key: _distribute_composed_object_schemas(value, defs) for key, value in node.items()} + for combinator in COMBINATOR_KEYS: + if combinator not in transformed or "properties" not in transformed: + continue + result = {combinator: _expand_composed_object_variants(transformed, defs)} + for key in ("title", "description", "discriminator"): + if key in transformed: + result[key] = transformed[key] + return result + return transformed + + +def _expand_composed_object_variants(node: dict[str, Any], defs: dict[str, Any]) -> list[Any]: + for combinator in COMBINATOR_KEYS: + if combinator not in node or "properties" not in node: + continue + + common_schema = _without_combinators(node) + expanded: list[Any] = [] + for option in node[combinator]: + for variant in _expand_allof_union_refs(option, defs): + expanded.append(_merge_object_schema(common_schema, variant) if isinstance(variant, dict) else variant) + return expanded + + return _expand_allof_union_refs(node, defs) + + +def _expand_allof_union_refs(node: Any, defs: dict[str, Any]) -> list[Any]: + if not isinstance(node, dict): + return [node] + + variants = [{key: copy.deepcopy(value) for key, value in node.items() if key != "allOf"}] + for item in node.get("allOf", []): + ref_name = _local_def_ref_name(item.get("$ref")) if isinstance(item, dict) else None + ref_schema = defs.get(ref_name) if ref_name else None + if isinstance(ref_schema, dict) and any(key in ref_schema for key in COMBINATOR_KEYS): + ref_variants = _expand_composed_object_variants(ref_schema, defs) + else: + ref_variants = [item] + + variants = [ + _merge_object_schema(variant, ref_variant) if isinstance(ref_variant, dict) else variant + for variant in variants + for ref_variant in ref_variants + ] + return variants + + +def _without_combinators(node: dict[str, Any]) -> dict[str, Any]: + return { + key: copy.deepcopy(value) + for key, value in node.items() + if key not in COMBINATOR_KEYS and key != "discriminator" + } + + +def _local_def_ref_name(ref: Any) -> str | None: + if isinstance(ref, str) and ref.startswith("#/$defs/"): + return ref.rsplit("/", 1)[-1] + return None + + +def _pop_ref_as_allof(schema: dict[str, Any]) -> tuple[dict[str, Any], list[dict[str, Any]]]: + schema = copy.deepcopy(schema) + if "$ref" not in schema: + return schema, [] + return schema, [{"$ref": schema.pop("$ref")}] + + +def _merge_object_schema(left: dict[str, Any], right: dict[str, Any]) -> dict[str, Any]: + left, left_refs = _pop_ref_as_allof(left) + right, right_refs = _pop_ref_as_allof(right) + merged: dict[str, Any] = {} + + for key in set(left) | set(right): + if key in COMBINATOR_KEYS or key in {"allOf", "discriminator"}: + continue + if key == "properties": + merged[key] = {**left.get(key, {}), **right.get(key, {})} + elif key == "required": + required = [] + for item in left.get(key, []) + right.get(key, []): + if item not in required: + required.append(item) + if required: + merged[key] = required + elif key in right: + merged[key] = right[key] + else: + merged[key] = left[key] + + all_of = left_refs + left.get("allOf", []) + right_refs + right.get("allOf", []) + if all_of: + merged["allOf"] = all_of + return merged + + +def _required_nullable_fields(schema: dict[str, Any]) -> dict[str, list[str]]: + defs = schema.get("$defs", {}) + fields: dict[str, list[str]] = {} + for class_name, definition in defs.items(): + if not isinstance(definition, dict): + continue + + required = set(definition.get("required", [])) + if not required: + continue + + properties = definition.get("properties", {}) + nullable_fields = [ + _schema_field_name(property_name) + for property_name in sorted(required) + if _schema_allows_null(properties.get(property_name), defs) + ] + if nullable_fields: + fields[class_name] = nullable_fields + return fields + + +def _schema_allows_null(node: Any, defs: dict[str, Any]) -> bool: + if not isinstance(node, dict): + return False + + schema_type = node.get("type") + if schema_type == "null" or (isinstance(schema_type, list) and "null" in schema_type): + return True + + for combinator in COMBINATOR_KEYS: + if any(_schema_allows_null(option, defs) for option in node.get(combinator, [])): + return True + + ref_name = _local_def_ref_name(node.get("$ref")) + if ref_name is not None: + return _schema_allows_null(defs.get(ref_name), defs) + + return any(_schema_allows_null(option, defs) for option in node.get("allOf", [])) + + +def _schema_field_name(name: str) -> str: + if name.startswith("_"): + return "field" + name + return re.sub(r"(? list[str]: if not output_path.exists(): raise RuntimeError(f"Generated schema not found at {output_path}") @@ -254,9 +425,11 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: processing_steps: tuple[_ProcessingStep, ...] = ( _ProcessingStep("apply field overrides", _apply_field_overrides), _ProcessingStep("apply default overrides", _apply_default_overrides), + _ProcessingStep("restore required nullable fields", _restore_required_nullable_fields), _ProcessingStep("attach description comments", _add_description_comments), _ProcessingStep("ensure custom BaseModel", _ensure_custom_base_model), _ProcessingStep("inject field validators", _inject_field_validators), + _ProcessingStep("inject schema aliases", _inject_schema_aliases), ) for step in processing_steps: @@ -454,6 +627,64 @@ def _append_validator( return content +def _inject_schema_aliases(content: str) -> str: + if "CreateElicitationRequest = Union[" in content: + return content + + aliases = textwrap.dedent("""\ + ElicitationMode = Union[ + ElicitationFormSessionMode, + ElicitationFormRequestMode, + ElicitationUrlSessionMode, + ElicitationUrlRequestMode, + ] + CreateFormElicitationRequest = Union[ + CreateFormSessionElicitationRequest, + CreateFormRequestElicitationRequest, + ] + CreateUrlElicitationRequest = Union[ + CreateUrlSessionElicitationRequest, + CreateUrlRequestElicitationRequest, + ] + CreateElicitationRequest = Union[ + CreateFormElicitationRequest, + CreateUrlElicitationRequest, + ] + CreateElicitationResponse = Union[ + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, + ] + """) + pattern = re.compile( + r"^(class CreateFormRequestElicitationRequest\([\s\S]*?\):[\s\S]*?)(?=^class \w+\(|\Z)", + re.MULTILINE, + ) + content, count = pattern.subn(lambda match: match.group(1).rstrip() + "\n\n" + aliases + "\n", content, count=1) + if count == 0: + print("Warning: failed to insert schema aliases", file=sys.stderr) + return content + + +def _restore_required_nullable_fields(content: str, schema: dict[str, Any] | None = None) -> str: + schema = _load_schema() if schema is None else schema + for class_name, field_names in _required_nullable_fields(schema).items(): + class_pattern = re.compile( + rf"(class {re.escape(class_name)}\([^)]*\):)(.*?)(?=\nclass |\Z)", + re.DOTALL, + ) + + def restore_block(match: re.Match[str], _field_names: list[str] = field_names) -> str: + header, block = match.group(1), match.group(2) + for field_name in _field_names: + field_pattern = re.compile(rf"(\n\s+{re.escape(field_name)}:\s+Annotated\[[\s\S]*?\n\s+\]\s*)=\s*None") + block = field_pattern.sub(r"\1", block, count=1) + return header + block + + content = class_pattern.sub(restore_block, content, count=1) + return content + + def _apply_field_overrides(content: str) -> str: for class_name, field_name, new_type, optional in FIELD_TYPE_OVERRIDES: if optional: diff --git a/src/acp/__init__.py b/src/acp/__init__.py index 87afc16..d343529 100644 --- a/src/acp/__init__.py +++ b/src/acp/__init__.py @@ -38,11 +38,37 @@ PROTOCOL_VERSION, ) from .schema import ( + AcceptElicitationResponse, AuthenticateRequest, AuthenticateResponse, + CancelElicitationResponse, CancelNotification, + CompleteElicitationNotification, + CreateElicitationRequest, + CreateElicitationResponse, + CreateFormElicitationRequest, + CreateFormRequestElicitationRequest, + CreateFormSessionElicitationRequest, CreateTerminalRequest, CreateTerminalResponse, + CreateUrlElicitationRequest, + CreateUrlRequestElicitationRequest, + CreateUrlSessionElicitationRequest, + DeclineElicitationResponse, + ElicitationBooleanPropertySchema, + ElicitationCapabilities, + ElicitationFormCapabilities, + ElicitationFormRequestMode, + ElicitationFormSessionMode, + ElicitationIntegerPropertySchema, + ElicitationMode, + ElicitationMultiSelectPropertySchema, + ElicitationNumberPropertySchema, + ElicitationSchema, + ElicitationStringPropertySchema, + ElicitationUrlCapabilities, + ElicitationUrlRequestMode, + ElicitationUrlSessionMode, InitializeRequest, InitializeResponse, KillTerminalRequest, @@ -115,6 +141,33 @@ "SetSessionModeResponse", "SetSessionConfigOptionSelectRequest", "SetSessionConfigOptionResponse", + # elicitation types + "ElicitationMode", + "ElicitationSchema", + "ElicitationCapabilities", + "ElicitationFormCapabilities", + "ElicitationUrlCapabilities", + "ElicitationFormSessionMode", + "ElicitationFormRequestMode", + "ElicitationUrlSessionMode", + "ElicitationUrlRequestMode", + "ElicitationStringPropertySchema", + "ElicitationNumberPropertySchema", + "ElicitationIntegerPropertySchema", + "ElicitationBooleanPropertySchema", + "ElicitationMultiSelectPropertySchema", + "CreateElicitationRequest", + "CreateElicitationResponse", + "CreateFormElicitationRequest", + "CreateFormSessionElicitationRequest", + "CreateFormRequestElicitationRequest", + "CreateUrlElicitationRequest", + "CreateUrlSessionElicitationRequest", + "CreateUrlRequestElicitationRequest", + "AcceptElicitationResponse", + "DeclineElicitationResponse", + "CancelElicitationResponse", + "CompleteElicitationNotification", # terminal types "CreateTerminalRequest", "CreateTerminalResponse", diff --git a/src/acp/agent/connection.py b/src/acp/agent/connection.py index f775900..bd8c176 100644 --- a/src/acp/agent/connection.py +++ b/src/acp/agent/connection.py @@ -4,20 +4,38 @@ from collections.abc import Callable from typing import Any, cast, final +from pydantic import TypeAdapter + from ..connection import Connection from ..interfaces import Agent, Client from ..meta import CLIENT_METHODS from ..schema import ( + AcceptElicitationResponse, AgentMessageChunk, AgentPlanContentUpdate, AgentPlanRemovedUpdate, AgentPlanUpdate, AgentThoughtChunk, AvailableCommandsUpdate, + CancelElicitationResponse, + CompleteElicitationNotification, ConfigOptionUpdate, + CreateElicitationResponse, + CreateFormElicitationRequest, + CreateFormRequestElicitationRequest, + CreateFormSessionElicitationRequest, CreateTerminalRequest, CreateTerminalResponse, + CreateUrlElicitationRequest, + CreateUrlRequestElicitationRequest, + CreateUrlSessionElicitationRequest, CurrentModeUpdate, + DeclineElicitationResponse, + ElicitationFormRequestMode, + ElicitationFormSessionMode, + ElicitationMode, + ElicitationUrlRequestMode, + ElicitationUrlSessionMode, EnvVariable, KillTerminalRequest, KillTerminalResponse, @@ -42,11 +60,12 @@ WriteTextFileRequest, WriteTextFileResponse, ) -from ..utils import compatible_class, notify_model, param_model, request_model, request_optional_model +from ..utils import compatible_class, notify_model, param_model, request_model, request_optional_model, serialize_params from .router import build_agent_router __all__ = ["AgentSideConnection"] _AGENT_CONNECTION_ERROR = "AgentSideConnection requires asyncio StreamWriter/StreamReader" +_CREATE_ELICITATION_RESPONSE_ADAPTER = TypeAdapter(CreateElicitationResponse) @final @@ -105,7 +124,7 @@ async def session_update( @param_model(RequestPermissionRequest) async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any + self, session_id: str, tool_call: ToolCallUpdate, options: list[PermissionOption], **kwargs: Any ) -> RequestPermissionResponse: return await request_model( self._conn, @@ -118,7 +137,7 @@ async def request_permission( @param_model(ReadTextFileRequest) async def read_text_file( - self, path: str, session_id: str, limit: int | None = None, line: int | None = None, **kwargs: Any + self, session_id: str, path: str, line: int | None = None, limit: int | None = None, **kwargs: Any ) -> ReadTextFileResponse: return await request_model( self._conn, @@ -129,7 +148,7 @@ async def read_text_file( @param_model(WriteTextFileRequest) async def write_text_file( - self, content: str, path: str, session_id: str, **kwargs: Any + self, session_id: str, path: str, content: str, **kwargs: Any ) -> WriteTextFileResponse | None: return await request_optional_model( self._conn, @@ -141,11 +160,11 @@ async def write_text_file( @param_model(CreateTerminalRequest) async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: @@ -204,6 +223,21 @@ async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) KillTerminalResponse, ) + async def create_elicitation( + self, message: str, mode: ElicitationMode, **kwargs: Any + ) -> AcceptElicitationResponse | DeclineElicitationResponse | CancelElicitationResponse: + request = _create_elicitation_request(message, mode, kwargs or None) + response = await self._conn.send_request(CLIENT_METHODS["elicitation_create"], serialize_params(request)) + return _CREATE_ELICITATION_RESPONSE_ADAPTER.validate_python(response) + + @param_model(CompleteElicitationNotification) + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: + await notify_model( + self._conn, + CLIENT_METHODS["elicitation_complete"], + CompleteElicitationNotification(elicitation_id=elicitation_id, field_meta=kwargs or None), + ) + async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]: return await self._conn.send_request(f"_{method}", params) @@ -221,3 +255,18 @@ async def __aexit__(self, exc_type, exc, tb) -> None: def on_connect(self, conn: Agent) -> None: pass + + +def _create_elicitation_request( + message: str, mode: ElicitationMode, field_meta: dict[str, Any] | None +) -> CreateFormElicitationRequest | CreateUrlElicitationRequest: + mode_fields = mode.model_dump(mode="json", exclude_none=True) + if isinstance(mode, ElicitationFormSessionMode): + return CreateFormSessionElicitationRequest(message=message, mode="form", field_meta=field_meta, **mode_fields) + if isinstance(mode, ElicitationFormRequestMode): + return CreateFormRequestElicitationRequest(message=message, mode="form", field_meta=field_meta, **mode_fields) + if isinstance(mode, ElicitationUrlSessionMode): + return CreateUrlSessionElicitationRequest(message=message, mode="url", field_meta=field_meta, **mode_fields) + if isinstance(mode, ElicitationUrlRequestMode): + return CreateUrlRequestElicitationRequest(message=message, mode="url", field_meta=field_meta, **mode_fields) + raise TypeError(f"Unsupported elicitation mode: {type(mode).__name__}") diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 7e50a88..0f3b1cf 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -121,8 +121,8 @@ async def load_session( self, cwd: str, session_id: str, - additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, + additional_directories: list[str] | None = None, **kwargs: Any, ) -> LoadSessionResponse: resolved_mcp_servers = mcp_servers or [] @@ -141,7 +141,7 @@ async def load_session( @param_model(ListSessionsRequest) async def list_sessions( - self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any + self, cwd: str | None = None, cursor: str | None = None, **kwargs: Any ) -> ListSessionsResponse: return await request_model_from_dict( self._conn, @@ -151,7 +151,7 @@ async def list_sessions( ) @param_model(SetSessionModeRequest) - async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse: + async def set_session_mode(self, session_id: str, mode_id: str, **kwargs: Any) -> SetSessionModeResponse: return await request_model_from_dict( self._conn, AGENT_METHODS["session_set_mode"], @@ -188,6 +188,7 @@ async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateRespo @param_model(PromptRequest) async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -195,7 +196,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: return await request_model( @@ -208,8 +208,8 @@ async def prompt( @param_model(ForkSessionRequest) async def fork_session( self, - cwd: str, session_id: str, + cwd: str, additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, @@ -230,8 +230,8 @@ async def fork_session( @param_model(ResumeSessionRequest) async def resume_session( self, - cwd: str, session_id: str, + cwd: str, additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, diff --git a/src/acp/client/router.py b/src/acp/client/router.py index 5b9049b..c8b26bb 100644 --- a/src/acp/client/router.py +++ b/src/acp/client/router.py @@ -2,12 +2,26 @@ from typing import Any +from pydantic import TypeAdapter + from ..exceptions import RequestError from ..interfaces import Client from ..meta import CLIENT_METHODS -from ..router import MessageRouter +from ..router import MessageRouter, Route, _resolve_handler, _warn_legacy_handler from ..schema import ( + CompleteElicitationNotification, + CreateElicitationRequest, + CreateFormElicitationRequest, + CreateFormRequestElicitationRequest, + CreateFormSessionElicitationRequest, CreateTerminalRequest, + CreateUrlElicitationRequest, + CreateUrlRequestElicitationRequest, + CreateUrlSessionElicitationRequest, + ElicitationFormRequestMode, + ElicitationFormSessionMode, + ElicitationUrlRequestMode, + ElicitationUrlSessionMode, KillTerminalRequest, ReadTextFileRequest, ReleaseTerminalRequest, @@ -20,6 +34,61 @@ from ..utils import normalize_result __all__ = ["build_client_router"] +_CREATE_ELICITATION_REQUEST_ADAPTER = TypeAdapter(CreateElicitationRequest) + + +def _validate_create_elicitation_request(params: Any) -> CreateFormElicitationRequest | CreateUrlElicitationRequest: + return _CREATE_ELICITATION_REQUEST_ADAPTER.validate_python(params) + + +def _mode_from_create_elicitation_request( + request: CreateFormElicitationRequest | CreateUrlElicitationRequest, +) -> ElicitationFormSessionMode | ElicitationFormRequestMode | ElicitationUrlSessionMode | ElicitationUrlRequestMode: + if isinstance(request, CreateFormSessionElicitationRequest): + return ElicitationFormSessionMode( + session_id=request.session_id, + tool_call_id=request.tool_call_id, + requested_schema=request.requested_schema, + ) + if isinstance(request, CreateFormRequestElicitationRequest): + return ElicitationFormRequestMode( + request_id=request.request_id, + requested_schema=request.requested_schema, + ) + + if isinstance(request, CreateUrlSessionElicitationRequest): + return ElicitationUrlSessionMode( + session_id=request.session_id, + tool_call_id=request.tool_call_id, + elicitation_id=request.elicitation_id, + url=request.url, + ) + if isinstance(request, CreateUrlRequestElicitationRequest): + return ElicitationUrlRequestMode( + request_id=request.request_id, + elicitation_id=request.elicitation_id, + url=request.url, + ) + raise TypeError(f"Unsupported elicitation request: {type(request).__name__}") + + +def _make_create_elicitation_handler(client: Client) -> Any: + func, attr, legacy_api = _resolve_handler(client, "create_elicitation") + if func is None: + return None + + async def wrapper(params: Any) -> Any: + if legacy_api: + _warn_legacy_handler(client, attr) + request = _validate_create_elicitation_request(params) + if legacy_api: + return await func(request) + kwargs = {"message": request.message, "mode": _mode_from_create_elicitation_request(request)} + if request.field_meta: + kwargs.update(request.field_meta) + return await func(**kwargs) + + return wrapper def build_client_router(client: Client, use_unstable_protocol: bool = False) -> MessageRouter: @@ -76,6 +145,23 @@ def build_client_router(client: Client, use_unstable_protocol: bool = False) -> adapt_result=normalize_result, ) + router.add_route( + Route( + method=CLIENT_METHODS["elicitation_create"], + func=_make_create_elicitation_handler(client), + kind="request", + adapt_result=normalize_result, + warn_unstable=not use_unstable_protocol, + ) + ) + router.route_notification( + CLIENT_METHODS["elicitation_complete"], + CompleteElicitationNotification, + client, + "complete_elicitation", + unstable=True, + ) + router.route_notification(CLIENT_METHODS["session_update"], SessionNotification, client, "session_update") @router.handle_extension_request diff --git a/src/acp/interfaces.py b/src/acp/interfaces.py index 245cedc..72e8545 100644 --- a/src/acp/interfaces.py +++ b/src/acp/interfaces.py @@ -17,10 +17,13 @@ ClientCapabilities, CloseSessionRequest, CloseSessionResponse, + CompleteElicitationNotification, ConfigOptionUpdate, + CreateElicitationResponse, CreateTerminalRequest, CreateTerminalResponse, CurrentModeUpdate, + ElicitationMode, EmbeddedResourceContentBlock, EnvVariable, ForkSessionRequest, @@ -80,7 +83,7 @@ class Client(Protocol): @param_model(RequestPermissionRequest) async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any + self, session_id: str, tool_call: ToolCallUpdate, options: list[PermissionOption], **kwargs: Any ) -> RequestPermissionResponse: ... @param_model(SessionNotification) @@ -105,22 +108,22 @@ async def session_update( @param_model(WriteTextFileRequest) async def write_text_file( - self, content: str, path: str, session_id: str, **kwargs: Any + self, session_id: str, path: str, content: str, **kwargs: Any ) -> WriteTextFileResponse | None: ... @param_model(ReadTextFileRequest) async def read_text_file( - self, path: str, session_id: str, limit: int | None = None, line: int | None = None, **kwargs: Any + self, session_id: str, path: str, line: int | None = None, limit: int | None = None, **kwargs: Any ) -> ReadTextFileResponse: ... @param_model(CreateTerminalRequest) async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: ... @@ -141,6 +144,13 @@ async def wait_for_terminal_exit( @param_model(KillTerminalRequest) async def kill_terminal(self, session_id: str, terminal_id: str, **kwargs: Any) -> KillTerminalResponse | None: ... + async def create_elicitation( + self, message: str, mode: ElicitationMode, **kwargs: Any + ) -> CreateElicitationResponse: ... + + @param_model(CompleteElicitationNotification) + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: ... + async def ext_method(self, method: str, params: dict[str, Any]) -> dict[str, Any]: ... async def ext_notification(self, method: str, params: dict[str, Any]) -> None: ... @@ -172,18 +182,18 @@ async def load_session( self, cwd: str, session_id: str, - additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, + additional_directories: list[str] | None = None, **kwargs: Any, ) -> LoadSessionResponse | None: ... @param_model(ListSessionsRequest) async def list_sessions( - self, cursor: str | None = None, cwd: str | None = None, **kwargs: Any + self, cwd: str | None = None, cursor: str | None = None, **kwargs: Any ) -> ListSessionsResponse: ... @param_model(SetSessionModeRequest) - async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: ... + async def set_session_mode(self, session_id: str, mode_id: str, **kwargs: Any) -> SetSessionModeResponse | None: ... @param_models(SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest) async def set_config_option( @@ -196,6 +206,7 @@ async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateRespo @param_model(PromptRequest) async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -203,15 +214,14 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: ... @param_model(ForkSessionRequest) async def fork_session( self, - cwd: str, session_id: str, + cwd: str, additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, @@ -220,8 +230,8 @@ async def fork_session( @param_model(ResumeSessionRequest) async def resume_session( self, - cwd: str, session_id: str, + cwd: str, additional_directories: list[str] | None = None, mcp_servers: list[HttpMcpServer | SseMcpServer | AcpMcpServer | McpServerStdio] | None = None, **kwargs: Any, diff --git a/src/acp/meta.py b/src/acp/meta.py index c82dcb8..a7bd914 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,49 +1,49 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/v0.13.6 +# Schema ref: refs/tags/schema-v1.16.0 AGENT_METHODS = { - "authenticate": "authenticate", - "document_did_change": "document/didChange", - "document_did_close": "document/didClose", - "document_did_focus": "document/didFocus", - "document_did_open": "document/didOpen", - "document_did_save": "document/didSave", "initialize": "initialize", - "logout": "logout", - "mcp_message": "mcp/message", - "nes_accept": "nes/accept", - "nes_close": "nes/close", - "nes_reject": "nes/reject", - "nes_start": "nes/start", - "nes_suggest": "nes/suggest", - "providers_disable": "providers/disable", + "authenticate": "authenticate", "providers_list": "providers/list", "providers_set": "providers/set", + "providers_disable": "providers/disable", + "session_new": "session/new", + "session_load": "session/load", + "session_set_mode": "session/set_mode", + "session_set_config_option": "session/set_config_option", + "session_prompt": "session/prompt", "session_cancel": "session/cancel", - "session_close": "session/close", + "mcp_message": "mcp/message", + "session_list": "session/list", "session_delete": "session/delete", "session_fork": "session/fork", - "session_list": "session/list", - "session_load": "session/load", - "session_new": "session/new", - "session_prompt": "session/prompt", "session_resume": "session/resume", - "session_set_config_option": "session/set_config_option", - "session_set_mode": "session/set_mode", + "session_close": "session/close", + "logout": "logout", + "nes_start": "nes/start", + "nes_suggest": "nes/suggest", + "nes_accept": "nes/accept", + "nes_reject": "nes/reject", + "nes_close": "nes/close", + "document_did_open": "document/didOpen", + "document_did_change": "document/didChange", + "document_did_close": "document/didClose", + "document_did_save": "document/didSave", + "document_did_focus": "document/didFocus", } CLIENT_METHODS = { - "elicitation_complete": "elicitation/complete", - "elicitation_create": "elicitation/create", - "fs_read_text_file": "fs/read_text_file", - "fs_write_text_file": "fs/write_text_file", - "mcp_connect": "mcp/connect", - "mcp_disconnect": "mcp/disconnect", - "mcp_message": "mcp/message", "session_request_permission": "session/request_permission", "session_update": "session/update", + "fs_write_text_file": "fs/write_text_file", + "fs_read_text_file": "fs/read_text_file", "terminal_create": "terminal/create", - "terminal_kill": "terminal/kill", "terminal_output": "terminal/output", "terminal_release": "terminal/release", "terminal_wait_for_exit": "terminal/wait_for_exit", + "terminal_kill": "terminal/kill", + "mcp_connect": "mcp/connect", + "mcp_message": "mcp/message", + "mcp_disconnect": "mcp/disconnect", + "elicitation_create": "elicitation/create", + "elicitation_complete": "elicitation/complete", } PROTOCOL_VERSION = 1 diff --git a/src/acp/schema.py b/src/acp/schema.py index 644e1d4..6b74f46 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,5 +1,5 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/v0.13.6 +# Schema ref: refs/tags/schema-v1.16.0 from __future__ import annotations @@ -30,7 +30,18 @@ class Jsonrpc(Enum): field_2_0 = "2.0" -class AuthCapabilities(BaseModel): +class ReadTextFileRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # Absolute path to the file to read. + path: Annotated[str, Field(description="Absolute path to the file to read.")] + # Line number to start reading from (1-based). + line: Annotated[ + Optional[int], + Field(description="Line number to start reading from (1-based).", ge=0), + ] = None + # Maximum number of lines to read. + limit: Annotated[Optional[int], Field(description="Maximum number of lines to read.", ge=0)] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -43,18 +54,21 @@ class AuthCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the client supports `terminal` authentication methods. - # - # When `true`, the agent may include `terminal` entries in its authentication methods. - terminal: Annotated[ - Optional[bool], - Field( - description="Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods." - ), - ] = False -class AuthEnvVar(BaseModel): +class TextResourceContents(BaseModel): + # MIME type describing the encoded media payload. + mime_type: Annotated[ + Optional[str], + Field( + alias="mimeType", + description="MIME type describing the encoded media payload.", + ), + ] = None + # Text payload carried by this content block. + text: Annotated[str, Field(description="Text payload carried by this content block.")] + # URI associated with this resource or media payload. + uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -67,36 +81,21 @@ class AuthEnvVar(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Human-readable label for this variable, displayed in client UI. - label: Annotated[ + + +class BlobResourceContents(BaseModel): + # Base64-encoded bytes for a binary resource payload. + blob: Annotated[str, Field(description="Base64-encoded bytes for a binary resource payload.")] + # MIME type describing the encoded media payload. + mime_type: Annotated[ Optional[str], - Field(description="Human-readable label for this variable, displayed in client UI."), - ] = None - # The environment variable name (e.g. `"OPENAI_API_KEY"`). - name: Annotated[ - str, - Field(description='The environment variable name (e.g. `"OPENAI_API_KEY"`).'), - ] - # Whether this variable is optional. - # - # Defaults to `false`. - optional: Annotated[ - Optional[bool], - Field(description="Whether this variable is optional.\n\nDefaults to `false`."), - ] = False - # Whether this value is a secret (e.g. API key, token). - # Clients should use a password-style input for secret vars. - # - # Defaults to `true`. - secret: Annotated[ - Optional[bool], Field( - description="Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`." + alias="mimeType", + description="MIME type describing the encoded media payload.", ), - ] = True - - -class AuthMethodAgent(BaseModel): + ] = None + # URI associated with this resource or media payload. + uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -109,18 +108,18 @@ class AuthMethodAgent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] -class AuthMethodEnvVar(BaseModel): +class Diff(BaseModel): + # The file path being modified. + path: Annotated[str, Field(description="The file path being modified.")] + # The original content (None for new files). + old_text: Annotated[ + Optional[str], + Field(alias="oldText", description="The original content (None for new files)."), + ] = None + # The new content after modification. + new_text: Annotated[str, Field(alias="newText", description="The new content after modification.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -133,28 +132,17 @@ class AuthMethodEnvVar(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Optional link to a page where the user can obtain their credentials. - link: Annotated[ - Optional[str], - Field(description="Optional link to a page where the user can obtain their credentials."), - ] = None - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] - # The environment variables the client should set. - vars: Annotated[ - List[AuthEnvVar], - Field(description="The environment variables the client should set."), - ] -class AuthMethodTerminal(BaseModel): +class Terminal(BaseModel): + # Identifier of the terminal instance to embed in the content stream. + terminal_id: Annotated[ + str, + Field( + alias="terminalId", + description="Identifier of the terminal instance to embed in the content stream.", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -167,28 +155,13 @@ class AuthMethodTerminal(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Additional arguments to pass when running the agent binary for terminal auth. - args: Annotated[ - Optional[List[str]], - Field(description="Additional arguments to pass when running the agent binary for terminal auth."), - ] = None - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # Additional environment variables to set when running the agent binary for terminal auth. - env: Annotated[ - Optional[Dict[str, str]], - Field(description="Additional environment variables to set when running the agent binary for terminal auth."), - ] = None - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] -class AuthenticateRequest(BaseModel): +class ToolCallLocation(BaseModel): + # The file path being accessed or modified. + path: Annotated[str, Field(description="The file path being accessed or modified.")] + # Optional line number within the file. + line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -201,18 +174,13 @@ class AuthenticateRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the authentication method to use. - # Must be one of the methods advertised in the initialize response. - method_id: Annotated[ - str, - Field( - alias="methodId", - description="The ID of the authentication method to use.\nMust be one of the methods advertised in the initialize response.", - ), - ] -class AuthenticateResponse(BaseModel): +class EnvVariable(BaseModel): + # The name of the environment variable. + name: Annotated[str, Field(description="The name of the environment variable.")] + # The value to set for the environment variable. + value: Annotated[str, Field(description="The value to set for the environment variable.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -227,7 +195,14 @@ class AuthenticateResponse(BaseModel): ] = None -class BlobResourceContents(BaseModel): +class TerminalOutputRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to get output from. + terminal_id: Annotated[ + str, + Field(alias="terminalId", description="The ID of the terminal to get output from."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -240,21 +215,13 @@ class BlobResourceContents(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - blob: str - mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None - uri: str - - -class BooleanPropertySchema(BaseModel): - # Default value. - default: Annotated[Optional[bool], Field(description="Default value.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class CloseNesResponse(BaseModel): +class ReleaseTerminalRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to release. + terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to release.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -269,7 +236,14 @@ class CloseNesResponse(BaseModel): ] = None -class CloseSessionResponse(BaseModel): +class WaitForTerminalExitRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to wait for. + terminal_id: Annotated[ + str, + Field(alias="terminalId", description="The ID of the terminal to wait for."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -284,14 +258,11 @@ class CloseSessionResponse(BaseModel): ] = None -class Cost(BaseModel): - # Total cumulative cost for session. - amount: Annotated[float, Field(description="Total cumulative cost for session.")] - # ISO 4217 currency code (e.g., "USD", "EUR"). - currency: Annotated[str, Field(description='ISO 4217 currency code (e.g., "USD", "EUR").')] - - -class DeclineElicitationResponse(BaseModel): +class KillTerminalRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The ID of the terminal to kill. + terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to kill.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -304,10 +275,34 @@ class DeclineElicitationResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - action: Literal["decline"] -class CancelElicitationResponse(BaseModel): +class ElicitationSessionScope(BaseModel): + # The session this elicitation is tied to. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session this elicitation is tied to."), + ] + # Optional tool call within the session. + tool_call_id: Annotated[ + Optional[str], + Field(alias="toolCallId", description="Optional tool call within the session."), + ] = None + + +class ElicitationRequestScope(BaseModel): + # The request this elicitation is tied to. + request_id: Annotated[ + Optional[Union[int, str]], + Field(alias="requestId", description="The request this elicitation is tied to."), + ] + + +class EnumOption(BaseModel): + # The constant value for this option. + const: Annotated[str, Field(description="The constant value for this option.")] + # Human-readable title for this option. + title: Annotated[str, Field(description="Human-readable title for this option.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -320,10 +315,42 @@ class CancelElicitationResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - action: Literal["cancel"] -class CreateTerminalResponse(BaseModel): +class StringPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Minimum string length. + min_length: Annotated[ + Optional[int], + Field(alias="minLength", description="Minimum string length.", ge=0), + ] = None + # Maximum string length. + max_length: Annotated[ + Optional[int], + Field(alias="maxLength", description="Maximum string length.", ge=0), + ] = None + # Pattern the string must match. + pattern: Annotated[Optional[str], Field(description="Pattern the string must match.")] = None + # String format. + format: Annotated[Optional[str], Field(description="String format.")] = None + # Default value. + default: Annotated[Optional[str], Field(description="Default value.")] = None + # Enum values for untitled single-select enums. + enum: Annotated[ + Optional[List[str]], + Field(description="Enum values for untitled single-select enums."), + ] = None + # Titled enum options for titled single-select enums. + one_of: Annotated[ + Optional[List[EnumOption]], + Field( + alias="oneOf", + description="Titled enum options for titled single-select enums.", + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -336,17 +363,19 @@ class CreateTerminalResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The unique identifier for the created terminal. - terminal_id: Annotated[ - str, - Field( - alias="terminalId", - description="The unique identifier for the created terminal.", - ), - ] -class DeleteSessionResponse(BaseModel): +class NumberPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Minimum value (inclusive). + minimum: Annotated[Optional[float], Field(description="Minimum value (inclusive).")] = None + # Maximum value (inclusive). + maximum: Annotated[Optional[float], Field(description="Maximum value (inclusive).")] = None + # Default value. + default: Annotated[Optional[float], Field(description="Default value.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -361,7 +390,17 @@ class DeleteSessionResponse(BaseModel): ] = None -class Diff(BaseModel): +class IntegerPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Minimum value (inclusive). + minimum: Annotated[Optional[int], Field(description="Minimum value (inclusive).")] = None + # Maximum value (inclusive). + maximum: Annotated[Optional[int], Field(description="Maximum value (inclusive).")] = None + # Default value. + default: Annotated[Optional[int], Field(description="Default value.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -374,18 +413,15 @@ class Diff(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The new content after modification. - new_text: Annotated[str, Field(alias="newText", description="The new content after modification.")] - # The original content (None for new files). - old_text: Annotated[ - Optional[str], - Field(alias="oldText", description="The original content (None for new files)."), - ] = None - # The file path being modified. - path: Annotated[str, Field(description="The file path being modified.")] -class DisableProviderRequest(BaseModel): +class BooleanPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Default value. + default: Annotated[Optional[bool], Field(description="Default value.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -398,11 +434,11 @@ class DisableProviderRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Provider id to disable. - id: Annotated[str, Field(description="Provider id to disable.")] -class DisableProviderResponse(BaseModel): +class TitledMultiSelectItems(BaseModel): + # Titled enum options. + any_of: Annotated[List[EnumOption], Field(alias="anyOf", description="Titled enum options.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -417,7 +453,52 @@ class DisableProviderResponse(BaseModel): ] = None -class DisconnectMcpResponse(BaseModel): +class ElicitationUrlSessionMode(ElicitationSessionScope): + # The unique identifier for this elicitation. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The unique identifier for this elicitation.", + ), + ] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + + +class ElicitationUrlRequestMode(ElicitationRequestScope): + # The unique identifier for this elicitation. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The unique identifier for this elicitation.", + ), + ] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + + +class ElicitationUrlMode(RootModel[Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode]]): + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # URL-based elicitation mode where the client directs the user to a URL. + root: Annotated[ + Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL." + ), + ] + + +class DisconnectMcpRequest(BaseModel): + # The MCP-over-ACP connection to close. + connection_id: Annotated[ + str, + Field(alias="connectionId", description="The MCP-over-ACP connection to close."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -432,19 +513,22 @@ class DisconnectMcpResponse(BaseModel): ] = None -class ElicitationAcceptAction(BaseModel): - # The user-provided content, if any, as an object matching the requested schema. - content: Annotated[ - Optional[Dict[str, Any]], - Field(description="The user-provided content, if any, as an object matching the requested schema."), - ] = None - - -class ElicitationContentValue(RootModel[Union[str, int, float, bool, List[str]]]): - root: Union[str, int, float, bool, List[str]] - - -class ElicitationFormCapabilities(BaseModel): +class PromptCapabilities(BaseModel): + # Agent supports [`ContentBlock::Image`]. + image: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Image`].")] = False + # Agent supports [`ContentBlock::Audio`]. + audio: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Audio`].")] = False + # Agent supports embedded context in `session/prompt` requests. + # + # When enabled, the Client is allowed to include [`ContentBlock::Resource`] + # in prompt requests for pieces of context that are referenced in the message. + embedded_context: Annotated[ + Optional[bool], + Field( + alias="embeddedContext", + description="Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", + ), + ] = False # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -459,11 +543,22 @@ class ElicitationFormCapabilities(BaseModel): ] = None -class ElicitationBooleanPropertySchema(BooleanPropertySchema): - type: Literal["boolean"] - - -class ElicitationUrlCapabilities(BaseModel): +class McpCapabilities(BaseModel): + # Agent supports [`McpServer::Http`]. + http: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Http`].")] = False + # Agent supports [`McpServer::Sse`]. + sse: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Sse`].")] = False + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Agent supports [`McpServer::Acp`]. + acp: Annotated[ + Optional[bool], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`]." + ), + ] = False # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -478,14 +573,7 @@ class ElicitationUrlCapabilities(BaseModel): ] = None -class EnumOption(BaseModel): - # The constant value for this option. - const: Annotated[str, Field(description="The constant value for this option.")] - # Human-readable title for this option. - title: Annotated[str, Field(description="Human-readable title for this option.")] - - -class EnvVariable(BaseModel): +class SessionListCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -498,13 +586,9 @@ class EnvVariable(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The name of the environment variable. - name: Annotated[str, Field(description="The name of the environment variable.")] - # The value to set for the environment variable. - value: Annotated[str, Field(description="The value to set for the environment variable.")] -class FileSystemCapabilities(BaseModel): +class SessionDeleteCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -517,25 +601,9 @@ class FileSystemCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the Client supports `fs/read_text_file` requests. - read_text_file: Annotated[ - Optional[bool], - Field( - alias="readTextFile", - description="Whether the Client supports `fs/read_text_file` requests.", - ), - ] = False - # Whether the Client supports `fs/write_text_file` requests. - write_text_file: Annotated[ - Optional[bool], - Field( - alias="writeTextFile", - description="Whether the Client supports `fs/write_text_file` requests.", - ), - ] = False -class HttpHeader(BaseModel): +class SessionAdditionalDirectoriesCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -548,13 +616,9 @@ class HttpHeader(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The name of the HTTP header. - name: Annotated[str, Field(description="The name of the HTTP header.")] - # The value to set for the HTTP header. - value: Annotated[str, Field(description="The value to set for the HTTP header.")] -class Implementation(BaseModel): +class SessionForkCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -567,48 +631,9 @@ class Implementation(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Intended for programmatic or logical use, but can be used as a display - # name fallback if title isn’t present. - name: Annotated[ - str, - Field( - description="Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn’t present." - ), - ] - # Intended for UI and end-user contexts — optimized to be human-readable - # and easily understood. - # - # If not provided, the name should be used for display. - title: Annotated[ - Optional[str], - Field( - description="Intended for UI and end-user contexts — optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display." - ), - ] = None - # Version of the implementation. Can be displayed to the user or used - # for debugging or metrics purposes. (e.g. "1.0.0"). - version: Annotated[ - str, - Field( - description='Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. "1.0.0").' - ), - ] - - -class IntegerPropertySchema(BaseModel): - # Default value. - default: Annotated[Optional[int], Field(description="Default value.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Maximum value (inclusive). - maximum: Annotated[Optional[int], Field(description="Maximum value (inclusive).")] = None - # Minimum value (inclusive). - minimum: Annotated[Optional[int], Field(description="Minimum value (inclusive).")] = None - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class KillTerminalResponse(BaseModel): +class SessionResumeCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -623,7 +648,7 @@ class KillTerminalResponse(BaseModel): ] = None -class ListProvidersRequest(BaseModel): +class SessionCloseCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -638,7 +663,7 @@ class ListProvidersRequest(BaseModel): ] = None -class ListSessionsRequest(BaseModel): +class LogoutCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -651,21 +676,9 @@ class ListSessionsRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Opaque cursor token from a previous response's nextCursor field for cursor-based pagination - cursor: Annotated[ - Optional[str], - Field( - description="Opaque cursor token from a previous response's nextCursor field for cursor-based pagination" - ), - ] = None - # Filter sessions by working directory. Must be an absolute path. - cwd: Annotated[ - Optional[str], - Field(description="Filter sessions by working directory. Must be an absolute path."), - ] = None -class LogoutCapabilities(BaseModel): +class ProvidersCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -680,7 +693,7 @@ class LogoutCapabilities(BaseModel): ] = None -class LogoutRequest(BaseModel): +class NesDocumentDidOpenCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -695,7 +708,7 @@ class LogoutRequest(BaseModel): ] = None -class LogoutResponse(BaseModel): +class NesDocumentDidCloseCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -710,7 +723,7 @@ class LogoutResponse(BaseModel): ] = None -class McpCapabilities(BaseModel): +class NesDocumentDidSaveCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -723,24 +736,33 @@ class McpCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + + +class NesDocumentDidFocusCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # Agent supports [`McpServer::Acp`]. - acp: Annotated[ - Optional[bool], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`]." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] = False - # Agent supports [`McpServer::Http`]. - http: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Http`].")] = False - # Agent supports [`McpServer::Sse`]. - sse: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Sse`].")] = False + ] = None -class McpServerHttp(BaseModel): +class NesRecentFilesCapabilities(BaseModel): + # Maximum number of recent files the agent can use. + max_count: Annotated[ + Optional[int], + Field( + alias="maxCount", + description="Maximum number of recent files the agent can use.", + ge=0, + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -753,18 +775,9 @@ class McpServerHttp(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # HTTP headers to set when making requests to the MCP server. - headers: Annotated[ - List[HttpHeader], - Field(description="HTTP headers to set when making requests to the MCP server."), - ] - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # URL to the MCP server. - url: Annotated[str, Field(description="URL to the MCP server.")] -class McpServerSse(BaseModel): +class NesRelatedSnippetsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -777,18 +790,18 @@ class McpServerSse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # HTTP headers to set when making requests to the MCP server. - headers: Annotated[ - List[HttpHeader], - Field(description="HTTP headers to set when making requests to the MCP server."), - ] - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # URL to the MCP server. - url: Annotated[str, Field(description="URL to the MCP server.")] -class McpServerStdio(BaseModel): +class NesEditHistoryCapabilities(BaseModel): + # Maximum number of edit history entries the agent can use. + max_count: Annotated[ + Optional[int], + Field( + alias="maxCount", + description="Maximum number of edit history entries the agent can use.", + ge=0, + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -801,23 +814,18 @@ class McpServerStdio(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Command-line arguments to pass to the MCP server. - args: Annotated[ - List[str], - Field(description="Command-line arguments to pass to the MCP server."), - ] - # Path to the MCP server executable. - command: Annotated[str, Field(description="Path to the MCP server executable.")] - # Environment variables to set when launching the MCP server. - env: Annotated[ - List[EnvVariable], - Field(description="Environment variables to set when launching the MCP server."), - ] - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] -class MessageMcpNotification(BaseModel): +class NesUserActionsCapabilities(BaseModel): + # Maximum number of user actions the agent can use. + max_count: Annotated[ + Optional[int], + Field( + alias="maxCount", + description="Maximum number of user actions the agent can use.", + ge=0, + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -830,28 +838,24 @@ class MessageMcpNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The MCP-over-ACP connection this message is sent on. - connection_id: Annotated[ - str, - Field( - alias="connectionId", - description="The MCP-over-ACP connection this message is sent on.", - ), - ] - # The inner MCP method name. - method: Annotated[str, Field(description="The inner MCP method name.")] - # Optional inner MCP params. + + +class NesOpenFilesCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # If omitted or set to `null`, the inner MCP message has no params. - params: Annotated[ + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ Optional[Dict[str, Any]], Field( - description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None -class MessageMcpRequest(BaseModel): +class NesDiagnosticsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -864,28 +868,70 @@ class MessageMcpRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The MCP-over-ACP connection this message is sent on. - connection_id: Annotated[ + + +class AuthEnvVar(BaseModel): + # The environment variable name (e.g. `"OPENAI_API_KEY"`). + name: Annotated[ str, + Field(description='The environment variable name (e.g. `"OPENAI_API_KEY"`).'), + ] + # Human-readable label for this variable, displayed in client UI. + label: Annotated[ + Optional[str], + Field(description="Human-readable label for this variable, displayed in client UI."), + ] = None + # Whether this value is a secret (e.g. API key, token). + # Clients should use a password-style input for secret vars. + # + # Defaults to `true`. + secret: Annotated[ + Optional[bool], Field( - alias="connectionId", - description="The MCP-over-ACP connection this message is sent on.", + description="Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`." ), - ] - # The inner MCP method name. - method: Annotated[str, Field(description="The inner MCP method name.")] - # Optional inner MCP params. + ] = True + # Whether this variable is optional. # - # If omitted or set to `null`, the inner MCP message has no params. - params: Annotated[ + # Defaults to `false`. + optional: Annotated[ + Optional[bool], + Field(description="Whether this variable is optional.\n\nDefaults to `false`."), + ] = False + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ Optional[Dict[str, Any]], Field( - description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None -class NesDiagnosticsCapabilities(BaseModel): +class AuthMethodEnvVar(BaseModel): + # Unique identifier for this authentication method. + id: Annotated[str, Field(description="Unique identifier for this authentication method.")] + # Human-readable name of the authentication method. + name: Annotated[str, Field(description="Human-readable name of the authentication method.")] + # Optional description providing more details about this authentication method. + description: Annotated[ + Optional[str], + Field(description="Optional description providing more details about this authentication method."), + ] = None + # The environment variables the client should set. + vars: Annotated[ + List[AuthEnvVar], + Field(description="The environment variables the client should set."), + ] + # Optional link to a page where the user can obtain their credentials. + link: Annotated[ + Optional[str], + Field(description="Optional link to a page where the user can obtain their credentials."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -900,7 +946,26 @@ class NesDiagnosticsCapabilities(BaseModel): ] = None -class NesDocumentDidCloseCapabilities(BaseModel): +class AuthMethodTerminal(BaseModel): + # Unique identifier for this authentication method. + id: Annotated[str, Field(description="Unique identifier for this authentication method.")] + # Human-readable name of the authentication method. + name: Annotated[str, Field(description="Human-readable name of the authentication method.")] + # Optional description providing more details about this authentication method. + description: Annotated[ + Optional[str], + Field(description="Optional description providing more details about this authentication method."), + ] = None + # Additional arguments to pass when running the agent binary for terminal auth. + args: Annotated[ + Optional[List[str]], + Field(description="Additional arguments to pass when running the agent binary for terminal auth."), + ] = None + # Additional environment variables to set when running the agent binary for terminal auth. + env: Annotated[ + Optional[Dict[str, str]], + Field(description="Additional environment variables to set when running the agent binary for terminal auth."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -915,7 +980,16 @@ class NesDocumentDidCloseCapabilities(BaseModel): ] = None -class NesDocumentDidFocusCapabilities(BaseModel): +class AuthMethodAgent(BaseModel): + # Unique identifier for this authentication method. + id: Annotated[str, Field(description="Unique identifier for this authentication method.")] + # Human-readable name of the authentication method. + name: Annotated[str, Field(description="Human-readable name of the authentication method.")] + # Optional description providing more details about this authentication method. + description: Annotated[ + Optional[str], + Field(description="Optional description providing more details about this authentication method."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -930,7 +1004,33 @@ class NesDocumentDidFocusCapabilities(BaseModel): ] = None -class NesDocumentDidOpenCapabilities(BaseModel): +class Implementation(BaseModel): + # Intended for programmatic or logical use, but can be used as a display + # name fallback if title isn’t present. + name: Annotated[ + str, + Field( + description="Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn’t present." + ), + ] + # Intended for UI and end-user contexts — optimized to be human-readable + # and easily understood. + # + # If not provided, the name should be used for display. + title: Annotated[ + Optional[str], + Field( + description="Intended for UI and end-user contexts — optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display." + ), + ] = None + # Version of the implementation. Can be displayed to the user or used + # for debugging or metrics purposes. (e.g. "1.0.0"). + version: Annotated[ + str, + Field( + description='Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. "1.0.0").' + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -945,7 +1045,7 @@ class NesDocumentDidOpenCapabilities(BaseModel): ] = None -class NesDocumentDidSaveCapabilities(BaseModel): +class AuthenticateResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -960,7 +1060,17 @@ class NesDocumentDidSaveCapabilities(BaseModel): ] = None -class NesEditHistoryCapabilities(BaseModel): +class ProviderCurrentConfig(BaseModel): + # Protocol currently used by this provider. + api_type: Annotated[ + str, + Field(alias="apiType", description="Protocol currently used by this provider."), + ] + # Base URL currently used by this provider. + base_url: Annotated[ + str, + Field(alias="baseUrl", description="Base URL currently used by this provider."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -973,48 +1083,9 @@ class NesEditHistoryCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Maximum number of edit history entries the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of edit history entries the agent can use.", - ge=0, - ), - ] = None - - -class NesEditHistoryEntry(BaseModel): - # A diff representing the edit. - diff: Annotated[str, Field(description="A diff representing the edit.")] - # The URI of the edited file. - uri: Annotated[str, Field(description="The URI of the edited file.")] - - -class NesExcerpt(BaseModel): - # The end line of the excerpt (zero-based). - end_line: Annotated[ - int, - Field( - alias="endLine", - description="The end line of the excerpt (zero-based).", - ge=0, - ), - ] - # The start line of the excerpt (zero-based). - start_line: Annotated[ - int, - Field( - alias="startLine", - description="The start line of the excerpt (zero-based).", - ge=0, - ), - ] - # The text content of the excerpt. - text: Annotated[str, Field(description="The text content of the excerpt.")] -class NesJumpCapabilities(BaseModel): +class SetProviderResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1029,7 +1100,7 @@ class NesJumpCapabilities(BaseModel): ] = None -class NesOpenFilesCapabilities(BaseModel): +class DisableProviderResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1044,16 +1115,7 @@ class NesOpenFilesCapabilities(BaseModel): ] = None -class NesRecentFile(BaseModel): - # The language identifier. - language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] - # The full text content of the file. - text: Annotated[str, Field(description="The full text content of the file.")] - # The URI of the file. - uri: Annotated[str, Field(description="The URI of the file.")] - - -class NesRecentFilesCapabilities(BaseModel): +class LogoutResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1066,25 +1128,21 @@ class NesRecentFilesCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Maximum number of recent files the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of recent files the agent can use.", - ge=0, - ), - ] = None - - -class NesRelatedSnippet(BaseModel): - # The code excerpts. - excerpts: Annotated[List[NesExcerpt], Field(description="The code excerpts.")] - # The URI of the file containing the snippets. - uri: Annotated[str, Field(description="The URI of the file containing the snippets.")] -class NesRelatedSnippetsCapabilities(BaseModel): +class SessionMode(BaseModel): + # Stable identifier used to refer to this protocol object in later messages. + id: Annotated[ + str, + Field(description="Stable identifier used to refer to this protocol object in later messages."), + ] + # Human-readable name shown for this protocol object. + name: Annotated[str, Field(description="Human-readable name shown for this protocol object.")] + # Optional human-readable details shown with this protocol object. + description: Annotated[ + Optional[str], + Field(description="Optional human-readable details shown with this protocol object."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1099,7 +1157,13 @@ class NesRelatedSnippetsCapabilities(BaseModel): ] = None -class NesRenameCapabilities(BaseModel): +class SessionConfigSelectOption(BaseModel): + # Unique identifier for this option value. + value: Annotated[str, Field(description="Unique identifier for this option value.")] + # Human-readable label for this option value. + name: Annotated[str, Field(description="Human-readable label for this option value.")] + # Optional description for this option value. + description: Annotated[Optional[str], Field(description="Optional description for this option value.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1114,16 +1178,41 @@ class NesRenameCapabilities(BaseModel): ] = None -class NesRepository(BaseModel): - # The repository name. - name: Annotated[str, Field(description="The repository name.")] - # The repository owner. - owner: Annotated[str, Field(description="The repository owner.")] - # The remote URL of the repository. - remote_url: Annotated[str, Field(alias="remoteUrl", description="The remote URL of the repository.")] +class SessionConfigBoolean(BaseModel): + # The current value of the boolean option. + current_value: Annotated[ + bool, + Field(alias="currentValue", description="The current value of the boolean option."), + ] -class NesSearchAndReplaceCapabilities(BaseModel): +class SessionInfo(BaseModel): + # Unique identifier for the session + session_id: Annotated[str, Field(alias="sessionId", description="Unique identifier for the session")] + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] + # Additional workspace roots reported for this session. Each path must be absolute. + # + # When present, this is the complete ordered additional-root list reported + # by the Agent. Omitted and empty values are equivalent: the response + # reports no additional roots. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", + ), + ] = None + # Human-readable title for the session + title: Annotated[Optional[str], Field(description="Human-readable title for the session")] = None + # ISO 8601 timestamp of last activity + updated_at: Annotated[ + Optional[str], + Field(alias="updatedAt", description="ISO 8601 timestamp of last activity"), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1138,30 +1227,22 @@ class NesSearchAndReplaceCapabilities(BaseModel): ] = None -class NesSearchAndReplaceSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # Whether `search` is a regular expression. Defaults to `false`. - is_regex: Annotated[ - Optional[bool], +class DeleteSessionResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="isRegex", - description="Whether `search` is a regular expression. Defaults to `false`.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The replacement text. - replace: Annotated[str, Field(description="The replacement text.")] - # The text or pattern to find. - search: Annotated[str, Field(description="The text or pattern to find.")] - # The file URI to search within. - uri: Annotated[str, Field(description="The file URI to search within.")] - -class NesSearchAndReplaceSuggestionVariant(NesSearchAndReplaceSuggestion): - kind: Literal["searchAndReplace"] - -class NesUserActionsCapabilities(BaseModel): +class CloseSessionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1174,31 +1255,9 @@ class NesUserActionsCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Maximum number of user actions the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of user actions the agent can use.", - ge=0, - ), - ] = None - - -class NumberPropertySchema(BaseModel): - # Default value. - default: Annotated[Optional[float], Field(description="Default value.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Maximum value (inclusive). - maximum: Annotated[Optional[float], Field(description="Maximum value (inclusive).")] = None - # Minimum value (inclusive). - minimum: Annotated[Optional[float], Field(description="Minimum value (inclusive).")] = None - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class PlanCapabilities(BaseModel): +class SetSessionModeResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1213,7 +1272,49 @@ class PlanCapabilities(BaseModel): ] = None -class PlanMarkdown(BaseModel): +class Usage(BaseModel): + # Sum of all token types across session. + total_tokens: Annotated[ + int, + Field( + alias="totalTokens", + description="Sum of all token types across session.", + ge=0, + ), + ] + # Total input tokens across all turns. + input_tokens: Annotated[ + int, + Field( + alias="inputTokens", + description="Total input tokens across all turns.", + ge=0, + ), + ] + # Total output tokens across all turns. + output_tokens: Annotated[ + int, + Field( + alias="outputTokens", + description="Total output tokens across all turns.", + ge=0, + ), + ] + # Total thought/reasoning tokens + thought_tokens: Annotated[ + Optional[int], + Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), + ] = None + # Total cache read tokens. + cached_read_tokens: Annotated[ + Optional[int], + Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), + ] = None + # Total cache write tokens. + cached_write_tokens: Annotated[ + Optional[int], + Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1226,13 +1327,17 @@ class PlanMarkdown(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Markdown content for the plan. - content: Annotated[str, Field(description="Markdown content for the plan.")] - # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] -class PlanRemoved(BaseModel): +class StartNesResponse(BaseModel): + # The session ID for the newly started NES session. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The session ID for the newly started NES session.", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1245,25 +1350,16 @@ class PlanRemoved(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The plan ID to remove. - id: Annotated[str, Field(description="The plan ID to remove.")] - - -class PlanUpdateMarkdown(PlanMarkdown): - type: Literal["markdown"] class Position(BaseModel): + # Zero-based line number. + line: Annotated[int, Field(description="Zero-based line number.", ge=0)] # Zero-based character offset (encoding-dependent). character: Annotated[ int, Field(description="Zero-based character offset (encoding-dependent).", ge=0), ] - # Zero-based line number. - line: Annotated[int, Field(description="Zero-based line number.", ge=0)] - - -class PromptCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1276,37 +1372,15 @@ class PromptCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Agent supports [`ContentBlock::Audio`]. - audio: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Audio`].")] = False - # Agent supports embedded context in `session/prompt` requests. - # - # When enabled, the Client is allowed to include [`ContentBlock::Resource`] - # in prompt requests for pieces of context that are referenced in the message. - embedded_context: Annotated[ - Optional[bool], - Field( - alias="embeddedContext", - description="Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", - ), - ] = False - # Agent supports [`ContentBlock::Image`]. - image: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Image`].")] = False - - -class ProviderCurrentConfig(BaseModel): - # Protocol currently used by this provider. - api_type: Annotated[ - str, - Field(alias="apiType", description="Protocol currently used by this provider."), - ] - # Base URL currently used by this provider. - base_url: Annotated[ - str, - Field(alias="baseUrl", description="Base URL currently used by this provider."), - ] -class ProviderInfo(BaseModel): +class NesJumpSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The file to navigate to. + uri: Annotated[str, Field(description="The file to navigate to.")] + # The target position within the file. + position: Annotated[Position, Field(description="The target position within the file.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1319,27 +1393,17 @@ class ProviderInfo(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Current effective non-secret routing config. - # Null or omitted means provider is disabled. - current: Annotated[ - Optional[ProviderCurrentConfig], - Field(description="Current effective non-secret routing config.\nNull or omitted means provider is disabled."), - ] = None - # Provider identifier, for example "main" or "openai". - id: Annotated[str, Field(description='Provider identifier, for example "main" or "openai".')] - # Whether this provider is mandatory and cannot be disabled via `providers/disable`. - # If true, clients must not call `providers/disable` for this id. - required: Annotated[ - bool, - Field( - description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id." - ), - ] - # Supported protocol types for this provider. - supported: Annotated[List[str], Field(description="Supported protocol types for this provider.")] -class ProvidersCapabilities(BaseModel): +class NesRenameSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The file URI containing the symbol. + uri: Annotated[str, Field(description="The file URI containing the symbol.")] + # The position of the symbol to rename. + position: Annotated[Position, Field(description="The position of the symbol to rename.")] + # The new name for the symbol. + new_name: Annotated[str, Field(alias="newName", description="The new name for the symbol.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1354,30 +1418,23 @@ class ProvidersCapabilities(BaseModel): ] = None -class Range(BaseModel): - # The end position (exclusive). - end: Annotated[Position, Field(description="The end position (exclusive).")] - # The start position (inclusive). - start: Annotated[Position, Field(description="The start position (inclusive).")] - - -class ReadTextFileResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], +class NesSearchAndReplaceSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The file URI to search within. + uri: Annotated[str, Field(description="The file URI to search within.")] + # The text or pattern to find. + search: Annotated[str, Field(description="The text or pattern to find.")] + # The replacement text. + replace: Annotated[str, Field(description="The replacement text.")] + # Whether `search` is a regular expression. Defaults to `false`. + is_regex: Annotated[ + Optional[bool], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + alias="isRegex", + description="Whether `search` is a regular expression. Defaults to `false`.", ), ] = None - content: str - - -class ReleaseTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1392,16 +1449,7 @@ class ReleaseTerminalResponse(BaseModel): ] = None -class DeniedOutcome(BaseModel): - outcome: Literal["cancelled"] - - -class Role(Enum): - assistant = "assistant" - user = "user" - - -class SelectedPermissionOutcome(BaseModel): +class CloseNesResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1414,14 +1462,13 @@ class SelectedPermissionOutcome(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the option the user selected. - option_id: Annotated[ - str, - Field(alias="optionId", description="The ID of the option the user selected."), - ] -class SessionAdditionalDirectoriesCapabilities(BaseModel): +class PlanFile(BaseModel): + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + # The URI of the file containing the plan. + uri: Annotated[str, Field(description="The URI of the file containing the plan.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1436,7 +1483,11 @@ class SessionAdditionalDirectoriesCapabilities(BaseModel): ] = None -class SessionCloseCapabilities(BaseModel): +class PlanMarkdown(BaseModel): + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + # Markdown content for the plan. + content: Annotated[str, Field(description="Markdown content for the plan.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1451,15 +1502,9 @@ class SessionCloseCapabilities(BaseModel): ] = None -class SessionConfigBoolean(BaseModel): - # The current value of the boolean option. - current_value: Annotated[ - bool, - Field(alias="currentValue", description="The current value of the boolean option."), - ] - - -class SessionDeleteCapabilities(BaseModel): +class PlanRemoved(BaseModel): + # The plan ID to remove. + id: Annotated[str, Field(description="The plan ID to remove.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1474,7 +1519,12 @@ class SessionDeleteCapabilities(BaseModel): ] = None -class SessionForkCapabilities(BaseModel): +class UnstructuredCommandInput(BaseModel): + # A hint to display when the input hasn't been provided yet + hint: Annotated[ + str, + Field(description="A hint to display when the input hasn't been provided yet"), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1489,7 +1539,9 @@ class SessionForkCapabilities(BaseModel): ] = None -class SessionInfo(BaseModel): +class _CurrentModeUpdate(BaseModel): + # The ID of the current mode + current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1502,47 +1554,9 @@ class SessionInfo(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Additional workspace roots reported for this session. Each path must be absolute. - # - # When present, this is the complete ordered additional-root list reported - # by the Agent. Omitted and empty values are equivalent: the response - # reports no additional roots. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", - ), - ] = None - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Unique identifier for the session - session_id: Annotated[str, Field(alias="sessionId", description="Unique identifier for the session")] - # Human-readable title for the session - title: Annotated[Optional[str], Field(description="Human-readable title for the session")] = None - # ISO 8601 timestamp of last activity - updated_at: Annotated[ - Optional[str], - Field(alias="updatedAt", description="ISO 8601 timestamp of last activity"), - ] = None class _SessionInfoUpdate(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None # Human-readable title for the session. Set to null to clear. title: Annotated[ Optional[str], @@ -1556,9 +1570,6 @@ class _SessionInfoUpdate(BaseModel): description="ISO 8601 timestamp of last activity. Set to null to clear.", ), ] = None - - -class SessionListCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1573,7 +1584,11 @@ class SessionListCapabilities(BaseModel): ] = None -class SessionResumeCapabilities(BaseModel): +class Cost(BaseModel): + # Total cumulative cost for session. + amount: Annotated[float, Field(description="Total cumulative cost for session.")] + # ISO 4217 currency code (e.g., "USD", "EUR"). + currency: Annotated[str, Field(description='ISO 4217 currency code (e.g., "USD", "EUR").')] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1588,15 +1603,13 @@ class SessionResumeCapabilities(BaseModel): ] = None -class AgentPlanRemovedUpdate(PlanRemoved): - session_update: Annotated[Literal["plan_removed"], Field(alias="sessionUpdate")] - - -class SessionInfoUpdate(_SessionInfoUpdate): - session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] - - -class SetProviderRequest(BaseModel): +class _UsageUpdate(BaseModel): + # Tokens currently in context. + used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] + # Total context window size in tokens. + size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] + # Cumulative session cost (optional). + cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1609,29 +1622,17 @@ class SetProviderRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Protocol type for this provider. - api_type: Annotated[str, Field(alias="apiType", description="Protocol type for this provider.")] - # Base URL for requests sent through this provider. - base_url: Annotated[ + + +class CompleteElicitationNotification(BaseModel): + # The ID of the elicitation that completed. + elicitation_id: Annotated[ str, Field( - alias="baseUrl", - description="Base URL for requests sent through this provider.", + alias="elicitationId", + description="The ID of the elicitation that completed.", ), ] - # Full headers map for this provider. - # May include authorization, routing, or other integration-specific headers. - headers: Annotated[ - Optional[Dict[str, str]], - Field( - description="Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers." - ), - ] = None - # Provider id to configure. - id: Annotated[str, Field(description="Provider id to configure.")] - - -class SetProviderResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1646,7 +1647,26 @@ class SetProviderResponse(BaseModel): ] = None -class SetSessionConfigOptionBooleanRequest(BaseModel): +class MessageMcpNotification(BaseModel): + # The MCP-over-ACP connection this message is sent on. + connection_id: Annotated[ + str, + Field( + alias="connectionId", + description="The MCP-over-ACP connection this message is sent on.", + ), + ] + # The inner MCP method name. + method: Annotated[str, Field(description="The inner MCP method name.")] + # Optional inner MCP params. + # + # If omitted or set to `null`, the inner MCP message has no params. + params: Annotated[ + Optional[Dict[str, Any]], + Field( + description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1659,25 +1679,25 @@ class SetSessionConfigOptionBooleanRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the configuration option to set. - config_id: Annotated[ - str, - Field(alias="configId", description="The ID of the configuration option to set."), - ] - # The ID of the session to set the configuration option for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", - ), - ] - type: Literal["boolean"] - # The boolean value. - value: Annotated[bool, Field(description="The boolean value.")] -class SetSessionConfigOptionSelectRequest(BaseModel): +class FileSystemCapabilities(BaseModel): + # Whether the Client supports `fs/read_text_file` requests. + read_text_file: Annotated[ + Optional[bool], + Field( + alias="readTextFile", + description="Whether the Client supports `fs/read_text_file` requests.", + ), + ] = False + # Whether the Client supports `fs/write_text_file` requests. + write_text_file: Annotated[ + Optional[bool], + Field( + alias="writeTextFile", + description="Whether the Client supports `fs/write_text_file` requests.", + ), + ] = False # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1690,24 +1710,9 @@ class SetSessionConfigOptionSelectRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the configuration option to set. - config_id: Annotated[ - str, - Field(alias="configId", description="The ID of the configuration option to set."), - ] - # The ID of the session to set the configuration option for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", - ), - ] - # The value ID. - value: Annotated[str, Field(description="The value ID.")] -class SetSessionModeRequest(BaseModel): +class BooleanConfigOptionCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1720,16 +1725,9 @@ class SetSessionModeRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the mode to set. - mode_id: Annotated[str, Field(alias="modeId", description="The ID of the mode to set.")] - # The ID of the session to set the mode for. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The ID of the session to set the mode for."), - ] -class SetSessionModeResponse(BaseModel): +class PlanCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1744,7 +1742,16 @@ class SetSessionModeResponse(BaseModel): ] = None -class StartNesResponse(BaseModel): +class AuthCapabilities(BaseModel): + # Whether the client supports `terminal` authentication methods. + # + # When `true`, the agent may include `terminal` entries in its authentication methods. + terminal: Annotated[ + Optional[bool], + Field( + description="Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods." + ), + ] = False # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1757,53 +1764,24 @@ class StartNesResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for the newly started NES session. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The session ID for the newly started NES session.", - ), - ] -class StringPropertySchema(BaseModel): - # Default value. - default: Annotated[Optional[str], Field(description="Default value.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Enum values for untitled single-select enums. - enum: Annotated[ - Optional[List[str]], - Field(description="Enum values for untitled single-select enums."), - ] = None - # String format. - format: Annotated[Optional[str], Field(description="String format.")] = None - # Maximum string length. - max_length: Annotated[ - Optional[int], - Field(alias="maxLength", description="Maximum string length.", ge=0), - ] = None - # Minimum string length. - min_length: Annotated[ - Optional[int], - Field(alias="minLength", description="Minimum string length.", ge=0), - ] = None - # Titled enum options for titled single-select enums. - one_of: Annotated[ - Optional[List[EnumOption]], +class ElicitationFormCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="oneOf", - description="Titled enum options for titled single-select enums.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Pattern the string must match. - pattern: Annotated[Optional[str], Field(description="Pattern the string must match.")] = None - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class Terminal(BaseModel): +class ElicitationUrlCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1816,10 +1794,9 @@ class Terminal(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - terminal_id: Annotated[str, Field(alias="terminalId")] -class TerminalExitStatus(BaseModel): +class NesJumpCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1832,23 +1809,24 @@ class TerminalExitStatus(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], + + +class NesRenameCapabilities(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None -class TerminalOutputRequest(BaseModel): +class NesSearchAndReplaceCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1861,16 +1839,33 @@ class TerminalOutputRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to get output from. - terminal_id: Annotated[ + + +class AuthenticateRequest(BaseModel): + # The ID of the authentication method to use. + # Must be one of the methods advertised in the initialize response. + method_id: Annotated[ str, - Field(alias="terminalId", description="The ID of the terminal to get output from."), + Field( + alias="methodId", + description="The ID of the authentication method to use.\nMust be one of the methods advertised in the initialize response.", + ), ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None -class TerminalOutputResponse(BaseModel): +class ListProvidersRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1883,31 +1878,29 @@ class TerminalOutputResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Exit status if the command has completed. - exit_status: Annotated[ - Optional[TerminalExitStatus], - Field(alias="exitStatus", description="Exit status if the command has completed."), - ] = None - # The terminal output captured so far. - output: Annotated[str, Field(description="The terminal output captured so far.")] - # Whether the output was truncated due to byte limits. - truncated: Annotated[bool, Field(description="Whether the output was truncated due to byte limits.")] -class TextDocumentContentChangeEvent(BaseModel): - # The range of the document that changed. If `None`, the entire content is replaced. - range: Annotated[ - Optional[Range], - Field(description="The range of the document that changed. If `None`, the entire content is replaced."), - ] = None - # The new text for the range, or the full document content if `range` is `None`. - text: Annotated[ +class SetProviderRequest(BaseModel): + # Provider id to configure. + id: Annotated[str, Field(description="Provider id to configure.")] + # Protocol type for this provider. + api_type: Annotated[str, Field(alias="apiType", description="Protocol type for this provider.")] + # Base URL for requests sent through this provider. + base_url: Annotated[ str, - Field(description="The new text for the range, or the full document content if `range` is `None`."), + Field( + alias="baseUrl", + description="Base URL for requests sent through this provider.", + ), ] - - -class TextResourceContents(BaseModel): + # Full headers map for this provider. + # May include authorization, routing, or other integration-specific headers. + headers: Annotated[ + Optional[Dict[str, str]], + Field( + description="Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers." + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1920,25 +1913,26 @@ class TextResourceContents(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None - text: str - uri: str - - -class TitledMultiSelectItems(BaseModel): - # Titled enum options. - any_of: Annotated[List[EnumOption], Field(alias="anyOf", description="Titled enum options.")] - - -class FileEditToolCallContent(Diff): - type: Literal["diff"] -class TerminalToolCallContent(Terminal): - type: Literal["terminal"] +class DisableProviderRequest(BaseModel): + # Provider id to disable. + id: Annotated[str, Field(description="Provider id to disable.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None -class ToolCallLocation(BaseModel): +class LogoutRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1951,13 +1945,13 @@ class ToolCallLocation(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional line number within the file. - line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None - # The file path being accessed or modified. - path: Annotated[str, Field(description="The file path being accessed or modified.")] -class UnstructuredCommandInput(BaseModel): +class HttpHeader(BaseModel): + # The name of the HTTP header. + name: Annotated[str, Field(description="The name of the HTTP header.")] + # The value to set for the HTTP header. + value: Annotated[str, Field(description="The value to set for the HTTP header.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1970,66 +1964,18 @@ class UnstructuredCommandInput(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # A hint to display when the input hasn't been provided yet - hint: Annotated[ - str, - Field(description="A hint to display when the input hasn't been provided yet"), - ] -class UntitledMultiSelectItems(BaseModel): - # Allowed enum values. - enum: Annotated[List[str], Field(description="Allowed enum values.")] - # Item type discriminator. Must be `"string"`. - type: Annotated[str, Field(description='Item type discriminator. Must be `"string"`.')] - - -class Usage(BaseModel): - # Total cache read tokens. - cached_read_tokens: Annotated[ - Optional[int], - Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), - ] = None - # Total cache write tokens. - cached_write_tokens: Annotated[ - Optional[int], - Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), - ] = None - # Total input tokens across all turns. - input_tokens: Annotated[ - int, - Field( - alias="inputTokens", - description="Total input tokens across all turns.", - ge=0, - ), - ] - # Total output tokens across all turns. - output_tokens: Annotated[ - int, - Field( - alias="outputTokens", - description="Total output tokens across all turns.", - ge=0, - ), - ] - # Total thought/reasoning tokens - thought_tokens: Annotated[ - Optional[int], - Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), - ] = None - # Sum of all token types across session. - total_tokens: Annotated[ - int, - Field( - alias="totalTokens", - description="Sum of all token types across session.", - ge=0, - ), +class McpServerHttp(BaseModel): + # Human-readable name identifying this MCP server. + name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] + # URL to the MCP server. + url: Annotated[str, Field(description="URL to the MCP server.")] + # HTTP headers to set when making requests to the MCP server. + headers: Annotated[ + List[HttpHeader], + Field(description="HTTP headers to set when making requests to the MCP server."), ] - - -class _UsageUpdate(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2042,15 +1988,18 @@ class _UsageUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Cumulative session cost (optional). - cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None - # Total context window size in tokens. - size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] - # Tokens currently in context. - used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] -class WaitForTerminalExitRequest(BaseModel): +class McpServerSse(BaseModel): + # Human-readable name identifying this MCP server. + name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] + # URL to the MCP server. + url: Annotated[str, Field(description="URL to the MCP server.")] + # HTTP headers to set when making requests to the MCP server. + headers: Annotated[ + List[HttpHeader], + Field(description="HTTP headers to set when making requests to the MCP server."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2063,16 +2012,21 @@ class WaitForTerminalExitRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to wait for. - terminal_id: Annotated[ - str, - Field(alias="terminalId", description="The ID of the terminal to wait for."), - ] -class WaitForTerminalExitResponse(BaseModel): +class McpServerAcp(BaseModel): + # Human-readable name identifying this MCP server. + name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] + # Unique identifier for this MCP server, generated by the component providing it. + # + # Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible + # on the same ACP connection. + id: Annotated[ + str, + Field( + description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2085,30 +2039,23 @@ class WaitForTerminalExitResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], - Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, - ), - ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None - - -class WorkspaceFolder(BaseModel): - # The display name of the folder. - name: Annotated[str, Field(description="The display name of the folder.")] - # The URI of the folder. - uri: Annotated[str, Field(description="The URI of the folder.")] -class WriteTextFileRequest(BaseModel): +class McpServerStdio(BaseModel): + # Human-readable name identifying this MCP server. + name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] + # Path to the MCP server executable. + command: Annotated[str, Field(description="Path to the MCP server executable.")] + # Command-line arguments to pass to the MCP server. + args: Annotated[ + List[str], + Field(description="Command-line arguments to pass to the MCP server."), + ] + # Environment variables to set when launching the MCP server. + env: Annotated[ + List[EnvVariable], + Field(description="Environment variables to set when launching the MCP server."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2121,15 +2068,21 @@ class WriteTextFileRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The text content to write to the file. - content: Annotated[str, Field(description="The text content to write to the file.")] - # Absolute path to the file to write. - path: Annotated[str, Field(description="Absolute path to the file to write.")] - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] -class WriteTextFileResponse(BaseModel): +class ListSessionsRequest(BaseModel): + # Filter sessions by working directory. Must be an absolute path. + cwd: Annotated[ + Optional[str], + Field(description="Filter sessions by working directory. Must be an absolute path."), + ] = None + # Opaque cursor token from a previous response's nextCursor field for cursor-based pagination + cursor: Annotated[ + Optional[str], + Field( + description="Opaque cursor token from a previous response's nextCursor field for cursor-based pagination" + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2144,7 +2097,9 @@ class WriteTextFileResponse(BaseModel): ] = None -class AcceptNesNotification(BaseModel): +class DeleteSessionRequest(BaseModel): + # The ID of the session to delete. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to delete.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2157,16 +2112,11 @@ class AcceptNesNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the accepted suggestion. - id: Annotated[str, Field(description="The ID of the accepted suggestion.")] - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] -class AgentAuthCapabilities(BaseModel): +class CloseSessionRequest(BaseModel): + # The ID of the session to close. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2179,18 +2129,16 @@ class AgentAuthCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the agent supports the logout method. - # - # By supplying `{}` it means that the agent supports the logout method. - logout: Annotated[ - Optional[LogoutCapabilities], - Field( - description="Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." - ), - ] = None -class Annotations(BaseModel): +class SetSessionModeRequest(BaseModel): + # The ID of the session to set the mode for. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The ID of the session to set the mode for."), + ] + # The ID of the mode to set. + mode_id: Annotated[str, Field(alias="modeId", description="The ID of the mode to set.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2203,12 +2151,22 @@ class Annotations(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - audience: Optional[List[Role]] = None - last_modified: Annotated[Optional[str], Field(alias="lastModified")] = None - priority: Optional[float] = None -class AudioContent(BaseModel): +class SetSessionConfigOptionBooleanRequest(BaseModel): + # The ID of the session to set the configuration option for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to set the configuration option for.", + ), + ] + # The ID of the configuration option to set. + config_id: Annotated[ + str, + Field(alias="configId", description="The ID of the configuration option to set."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2221,28 +2179,25 @@ class AudioContent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - data: str - mime_type: Annotated[str, Field(alias="mimeType")] - - -class EnvVarAuthMethod(AuthMethodEnvVar): - type: Literal["env_var"] - - -class TerminalAuthMethod(AuthMethodTerminal): - type: Literal["terminal"] + # The boolean value. + value: Annotated[bool, Field(description="The boolean value.")] + type: Literal["boolean"] -class AvailableCommandInput(RootModel[UnstructuredCommandInput]): - # The input specification for a command. - root: Annotated[ - UnstructuredCommandInput, - Field(description="The input specification for a command."), +class SetSessionConfigOptionSelectRequest(BaseModel): + # The ID of the session to set the configuration option for. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to set the configuration option for.", + ), + ] + # The ID of the configuration option to set. + config_id: Annotated[ + str, + Field(alias="configId", description="The ID of the configuration option to set."), ] - - -class CancelNotification(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2255,17 +2210,15 @@ class CancelNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the session to cancel operations for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to cancel operations for.", - ), - ] + # The value ID. + value: Annotated[str, Field(description="The value ID.")] -class CancelRequestNotification(BaseModel): +class WorkspaceFolder(BaseModel): + # The URI of the folder. + uri: Annotated[str, Field(description="The URI of the folder.")] + # The display name of the folder. + name: Annotated[str, Field(description="The display name of the folder.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2278,14 +2231,15 @@ class CancelRequestNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the request to cancel. - request_id: Annotated[ - Optional[Union[int, str]], - Field(alias="requestId", description="The ID of the request to cancel."), - ] = None -class ClientNesCapabilities(BaseModel): +class NesRepository(BaseModel): + # The repository name. + name: Annotated[str, Field(description="The repository name.")] + # The repository owner. + owner: Annotated[str, Field(description="The repository owner.")] + # The remote URL of the repository. + remote_url: Annotated[str, Field(alias="remoteUrl", description="The remote URL of the repository.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2298,27 +2252,15 @@ class ClientNesCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the client supports the `jump` suggestion kind. - jump: Annotated[ - Optional[NesJumpCapabilities], - Field(description="Whether the client supports the `jump` suggestion kind."), - ] = None - # Whether the client supports the `rename` suggestion kind. - rename: Annotated[ - Optional[NesRenameCapabilities], - Field(description="Whether the client supports the `rename` suggestion kind."), - ] = None - # Whether the client supports the `searchAndReplace` suggestion kind. - search_and_replace: Annotated[ - Optional[NesSearchAndReplaceCapabilities], - Field( - alias="searchAndReplace", - description="Whether the client supports the `searchAndReplace` suggestion kind.", - ), - ] = None -class CloseNesRequest(BaseModel): +class NesRecentFile(BaseModel): + # The URI of the file. + uri: Annotated[str, Field(description="The URI of the file.")] + # The language identifier. + language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] + # The full text content of the file. + text: Annotated[str, Field(description="The full text content of the file.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2331,11 +2273,29 @@ class CloseNesRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the NES session to close. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the NES session to close.")] -class CloseSessionRequest(BaseModel): +class NesExcerpt(BaseModel): + # The start line of the excerpt (zero-based). + start_line: Annotated[ + int, + Field( + alias="startLine", + description="The start line of the excerpt (zero-based).", + ge=0, + ), + ] + # The end line of the excerpt (zero-based). + end_line: Annotated[ + int, + Field( + alias="endLine", + description="The end line of the excerpt (zero-based).", + ge=0, + ), + ] + # The text content of the excerpt. + text: Annotated[str, Field(description="The text content of the excerpt.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2348,11 +2308,13 @@ class CloseSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the session to close. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] -class CompleteElicitationNotification(BaseModel): +class NesEditHistoryEntry(BaseModel): + # The URI of the edited file. + uri: Annotated[str, Field(description="The URI of the edited file.")] + # A diff representing the edit. + diff: Annotated[str, Field(description="A diff representing the edit.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2365,17 +2327,27 @@ class CompleteElicitationNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the elicitation that completed. - elicitation_id: Annotated[ + + +class NesUserAction(BaseModel): + # The kind of action (e.g., "insertChar", "cursorMovement"). + action: Annotated[ str, + Field(description='The kind of action (e.g., "insertChar", "cursorMovement").'), + ] + # The URI of the file where the action occurred. + uri: Annotated[str, Field(description="The URI of the file where the action occurred.")] + # The position where the action occurred. + position: Annotated[Position, Field(description="The position where the action occurred.")] + # Timestamp in milliseconds since epoch. + timestamp_ms: Annotated[ + int, Field( - alias="elicitationId", - description="The ID of the elicitation that completed.", + alias="timestampMs", + description="Timestamp in milliseconds since epoch.", + ge=0, ), ] - - -class ConnectMcpRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2388,17 +2360,11 @@ class ConnectMcpRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ACP MCP server ID that was provided by the component declaring the MCP server. - acp_id: Annotated[ - str, - Field( - alias="acpId", - description="The ACP MCP server ID that was provided by the component declaring the MCP server.", - ), - ] -class ConnectMcpResponse(BaseModel): +class CloseNesRequest(BaseModel): + # The ID of the NES session to close. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the NES session to close.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2411,21 +2377,9 @@ class ConnectMcpResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The unique identifier for this MCP-over-ACP connection. - connection_id: Annotated[ - str, - Field( - alias="connectionId", - description="The unique identifier for this MCP-over-ACP connection.", - ), - ] - -class AudioContentBlock(AudioContent): - type: Literal["audio"] - -class AcceptElicitationResponse(ElicitationAcceptAction): +class WriteTextFileResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2438,10 +2392,11 @@ class AcceptElicitationResponse(ElicitationAcceptAction): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - action: Literal["accept"] -class CreateTerminalRequest(BaseModel): +class ReadTextFileResponse(BaseModel): + # Content payload returned by this response. + content: Annotated[str, Field(description="Content payload returned by this response.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2454,41 +2409,18 @@ class CreateTerminalRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Array of command arguments. - args: Annotated[Optional[List[str]], Field(description="Array of command arguments.")] = None - # The command to execute. - command: Annotated[str, Field(description="The command to execute.")] - # Working directory for the command (absolute path). - cwd: Annotated[ - Optional[str], - Field(description="Working directory for the command (absolute path)."), - ] = None - # Environment variables for the command. - env: Annotated[ - Optional[List[EnvVariable]], - Field(description="Environment variables for the command."), - ] = None - # Maximum number of output bytes to retain. - # - # When the limit is exceeded, the Client truncates from the beginning of the output - # to stay within the limit. - # - # The Client MUST ensure truncation happens at a character boundary to maintain valid - # string output, even if this means the retained output is slightly less than the - # specified limit. - output_byte_limit: Annotated[ - Optional[int], - Field( - alias="outputByteLimit", - description="Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", - ge=0, - ), - ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] -class _CurrentModeUpdate(BaseModel): +class DeniedOutcome(BaseModel): + outcome: Literal["cancelled"] + + +class SelectedPermissionOutcome(BaseModel): + # The ID of the option the user selected. + option_id: Annotated[ + str, + Field(alias="optionId", description="The ID of the option the user selected."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2501,11 +2433,17 @@ class _CurrentModeUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the current mode - current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] -class DeleteSessionRequest(BaseModel): +class CreateTerminalResponse(BaseModel): + # The unique identifier for the created terminal. + terminal_id: Annotated[ + str, + Field( + alias="terminalId", + description="The unique identifier for the created terminal.", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2518,11 +2456,23 @@ class DeleteSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the session to delete. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to delete.")] -class DidChangeDocumentNotification(BaseModel): +class TerminalExitStatus(BaseModel): + # The process exit code (may be null if terminated by signal). + exit_code: Annotated[ + Optional[int], + Field( + alias="exitCode", + description="The process exit code (may be null if terminated by signal).", + ge=0, + ), + ] = None + # The signal that terminated the process (may be null if exited normally). + signal: Annotated[ + Optional[str], + Field(description="The signal that terminated the process (may be null if exited normally)."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2535,23 +2485,9 @@ class DidChangeDocumentNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The content changes. - content_changes: Annotated[ - List[TextDocumentContentChangeEvent], - Field(alias="contentChanges", description="The content changes."), - ] - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the changed document. - uri: Annotated[str, Field(description="The URI of the changed document.")] - # The new version number of the document. - version: Annotated[int, Field(description="The new version number of the document.")] -class DidCloseDocumentNotification(BaseModel): +class ReleaseTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2564,16 +2500,23 @@ class DidCloseDocumentNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the closed document. - uri: Annotated[str, Field(description="The URI of the closed document.")] -class DidFocusDocumentNotification(BaseModel): +class WaitForTerminalExitResponse(BaseModel): + # The process exit code (may be null if terminated by signal). + exit_code: Annotated[ + Optional[int], + Field( + alias="exitCode", + description="The process exit code (may be null if terminated by signal).", + ge=0, + ), + ] = None + # The signal that terminated the process (may be null if exited normally). + signal: Annotated[ + Optional[str], + Field(description="The signal that terminated the process (may be null if exited normally)."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2586,28 +2529,9 @@ class DidFocusDocumentNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The current cursor position. - position: Annotated[Position, Field(description="The current cursor position.")] - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the focused document. - uri: Annotated[str, Field(description="The URI of the focused document.")] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] - # The portion of the file currently visible in the editor viewport. - visible_range: Annotated[ - Range, - Field( - alias="visibleRange", - description="The portion of the file currently visible in the editor viewport.", - ), - ] -class DidOpenDocumentNotification(BaseModel): +class KillTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2620,28 +2544,9 @@ class DidOpenDocumentNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The language identifier of the document (e.g., "rust", "python"). - language_id: Annotated[ - str, - Field( - alias="languageId", - description='The language identifier of the document (e.g., "rust", "python").', - ), - ] - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The full text content of the document. - text: Annotated[str, Field(description="The full text content of the document.")] - # The URI of the opened document. - uri: Annotated[str, Field(description="The URI of the opened document.")] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] -class DidSaveDocumentNotification(BaseModel): +class DeclineElicitationResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2654,16 +2559,10 @@ class DidSaveDocumentNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the saved document. - uri: Annotated[str, Field(description="The URI of the saved document.")] + action: Literal["decline"] -class DisconnectMcpRequest(BaseModel): +class CancelElicitationResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2676,14 +2575,34 @@ class DisconnectMcpRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The MCP-over-ACP connection to close. - connection_id: Annotated[ - str, - Field(alias="connectionId", description="The MCP-over-ACP connection to close."), + action: Literal["cancel"] + + +class ElicitationContentValue(RootModel[Union[str, int, float, bool, List[str]]]): + # Allowed wire representations for [`ElicitationContentValue`]. + root: Annotated[ + Union[str, int, float, bool, List[str]], + Field(description="Allowed wire representations for [`ElicitationContentValue`]."), ] -class ElicitationCapabilities(BaseModel): +class ElicitationAcceptAction(BaseModel): + # The user-provided content, if any, as an object matching the requested schema. + content: Annotated[ + Optional[Dict[str, Any]], + Field(description="The user-provided content, if any, as an object matching the requested schema."), + ] = None + + +class ConnectMcpResponse(BaseModel): + # The unique identifier for this MCP-over-ACP connection. + connection_id: Annotated[ + str, + Field( + alias="connectionId", + description="The unique identifier for this MCP-over-ACP connection.", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2696,119 +2615,66 @@ class ElicitationCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the client supports form-based elicitation. - form: Annotated[ - Optional[ElicitationFormCapabilities], - Field(description="Whether the client supports form-based elicitation."), - ] = None - # Whether the client supports URL-based elicitation. - url: Annotated[ - Optional[ElicitationUrlCapabilities], - Field(description="Whether the client supports URL-based elicitation."), - ] = None - - -class ElicitationStringPropertySchema(StringPropertySchema): - type: Literal["string"] - - -class ElicitationNumberPropertySchema(NumberPropertySchema): - type: Literal["number"] - - -class ElicitationIntegerPropertySchema(IntegerPropertySchema): - type: Literal["integer"] - - -class ElicitationRequestScope(BaseModel): - # The request this elicitation is tied to. - request_id: Annotated[ - Optional[Union[int, str]], - Field(alias="requestId", description="The request this elicitation is tied to."), - ] = None - - -class ElicitationSessionScope(BaseModel): - # The session this elicitation is tied to. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session this elicitation is tied to."), - ] - # Optional tool call within the session. - tool_call_id: Annotated[ - Optional[str], - Field(alias="toolCallId", description="Optional tool call within the session."), - ] = None -class ElicitationUrlSessionMode(ElicitationSessionScope): - # The unique identifier for this elicitation. - elicitation_id: Annotated[ - str, +class DisconnectMcpResponse(BaseModel): + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + ] = None -class ElicitationUrlRequestMode(ElicitationRequestScope): - # The unique identifier for this elicitation. - elicitation_id: Annotated[ +class CancelNotification(BaseModel): + # The ID of the session to cancel operations for. + session_id: Annotated[ str, Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", + alias="sessionId", + description="The ID of the session to cancel operations for.", ), ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] - - -class ElicitationUrlMode(RootModel[Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode]]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # URL-based elicitation mode where the client directs the user to a URL. - root: Annotated[ - Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] + ] = None -class Error(BaseModel): - # A number indicating the error type that occurred. - # This must be an integer as defined in the JSON-RPC specification. - code: Annotated[ - int, - Field( - description="A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." - ), +class DidOpenDocumentNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), ] - # Optional primitive or structured value that contains additional information about the error. - # This may include debugging information or context-specific details. - data: Annotated[ - Optional[Any], - Field( - description="Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." - ), - ] = None - # A string providing a short description of the error. - # The message should be limited to a concise single sentence. - message: Annotated[ + # The URI of the opened document. + uri: Annotated[str, Field(description="The URI of the opened document.")] + # The language identifier of the document (e.g., "rust", "python"). + language_id: Annotated[ str, Field( - description="A string providing a short description of the error.\nThe message should be limited to a concise single sentence." + alias="languageId", + description='The language identifier of the document (e.g., "rust", "python").', ), ] - - -class ImageContent(BaseModel): + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + # The full text content of the document. + text: Annotated[str, Field(description="The full text content of the document.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2821,13 +2687,16 @@ class ImageContent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - data: str - mime_type: Annotated[str, Field(alias="mimeType")] - uri: Optional[str] = None -class KillTerminalRequest(BaseModel): +class DidCloseDocumentNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the closed document. + uri: Annotated[str, Field(description="The URI of the closed document.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2840,13 +2709,16 @@ class KillTerminalRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to kill. - terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to kill.")] -class ListProvidersResponse(BaseModel): +class DidSaveDocumentNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the saved document. + uri: Annotated[str, Field(description="The URI of the saved document.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2859,14 +2731,16 @@ class ListProvidersResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Configurable providers with current routing info suitable for UI display. - providers: Annotated[ - List[ProviderInfo], - Field(description="Configurable providers with current routing info suitable for UI display."), - ] -class ListSessionsResponse(BaseModel): +class AcceptNesNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The ID of the accepted suggestion. + id: Annotated[str, Field(description="The ID of the accepted suggestion.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2879,28 +2753,14 @@ class ListSessionsResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Opaque cursor token. If present, pass this in the next request's cursor parameter - # to fetch the next page. If absent, there are no more results. - next_cursor: Annotated[ - Optional[str], - Field( - alias="nextCursor", - description="Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", - ), - ] = None - # Array of session information objects - sessions: Annotated[List[SessionInfo], Field(description="Array of session information objects")] - - -class HttpMcpServer(McpServerHttp): - type: Literal["http"] - -class SseMcpServer(McpServerSse): - type: Literal["sse"] - -class McpServerAcp(BaseModel): +class CancelRequestNotification(BaseModel): + # The ID of the request to cancel. + request_id: Annotated[ + Optional[Union[int, str]], + Field(alias="requestId", description="The ID of the request to cancel."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2913,45 +2773,15 @@ class McpServerAcp(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Unique identifier for this MCP server, generated by the component providing it. - # - # Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible - # on the same ACP connection. - id: Annotated[ - str, - Field( - description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." - ), - ] - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - - -class MultiSelectPropertySchema(BaseModel): - # Default selected values. - default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # The items definition describing allowed values. - items: Annotated[ - Union[UntitledMultiSelectItems, TitledMultiSelectItems], - Field(description="The items definition describing allowed values."), - ] - # Maximum number of items to select. - max_items: Annotated[ - Optional[int], - Field(alias="maxItems", description="Maximum number of items to select.", ge=0), - ] = None - # Minimum number of items to select. - min_items: Annotated[ - Optional[int], - Field(alias="minItems", description="Minimum number of items to select.", ge=0), - ] = None - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None -class NesContextCapabilities(BaseModel): +class WriteTextFileRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # Absolute path to the file to write. + path: Annotated[str, Field(description="Absolute path to the file to write.")] + # The text content to write to the file. + content: Annotated[str, Field(description="The text content to write to the file.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2964,62 +2794,92 @@ class NesContextCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the agent wants diagnostics context. - diagnostics: Annotated[ - Optional[NesDiagnosticsCapabilities], - Field(description="Whether the agent wants diagnostics context."), + + +class FileEditToolCallContent(Diff): + type: Literal["diff"] + + +class TerminalToolCallContent(Terminal): + type: Literal["terminal"] + + +class Annotations(BaseModel): + # Intended recipients for this content, such as the user or assistant. + audience: Annotated[ + Optional[List[str]], + Field(description="Intended recipients for this content, such as the user or assistant."), ] = None - # Whether the agent wants edit history context. - edit_history: Annotated[ - Optional[NesEditHistoryCapabilities], + # Timestamp indicating when the underlying resource was last modified. + last_modified: Annotated[ + Optional[str], Field( - alias="editHistory", - description="Whether the agent wants edit history context.", + alias="lastModified", + description="Timestamp indicating when the underlying resource was last modified.", ), ] = None - # Whether the agent wants open files context. - open_files: Annotated[ - Optional[NesOpenFilesCapabilities], - Field(alias="openFiles", description="Whether the agent wants open files context."), + # Relative importance of this content when clients choose what to surface. + priority: Annotated[ + Optional[float], + Field(description="Relative importance of this content when clients choose what to surface."), ] = None - # Whether the agent wants recent files context. - recent_files: Annotated[ - Optional[NesRecentFilesCapabilities], + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="recentFiles", - description="Whether the agent wants recent files context.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the agent wants related snippets context. - related_snippets: Annotated[ - Optional[NesRelatedSnippetsCapabilities], - Field( - alias="relatedSnippets", - description="Whether the agent wants related snippets context.", - ), + + +class TextContent(BaseModel): + # Optional annotations that help clients decide how to display or route this content. + annotations: Annotated[ + Optional[Annotations], + Field(description="Optional annotations that help clients decide how to display or route this content."), ] = None - # Whether the agent wants user actions context. - user_actions: Annotated[ - Optional[NesUserActionsCapabilities], + # Text payload carried by this content block. + text: Annotated[str, Field(description="Text payload carried by this content block.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="userActions", - description="Whether the agent wants user actions context.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None -class NesDiagnostic(BaseModel): - # The diagnostic message. - message: Annotated[str, Field(description="The diagnostic message.")] - # The range of the diagnostic. - range: Annotated[Range, Field(description="The range of the diagnostic.")] - # The severity of the diagnostic. - severity: Annotated[str, Field(description="The severity of the diagnostic.")] - # The URI of the file containing the diagnostic. - uri: Annotated[str, Field(description="The URI of the file containing the diagnostic.")] - - -class NesDocumentDidChangeCapabilities(BaseModel): +class ImageContent(BaseModel): + # Optional annotations that help clients decide how to display or route this content. + annotations: Annotated[ + Optional[Annotations], + Field(description="Optional annotations that help clients decide how to display or route this content."), + ] = None + # Base64-encoded media payload. + data: Annotated[str, Field(description="Base64-encoded media payload.")] + # MIME type describing the encoded media payload. + mime_type: Annotated[ + str, + Field( + alias="mimeType", + description="MIME type describing the encoded media payload.", + ), + ] + # URI associated with this resource or media payload. + uri: Annotated[ + Optional[str], + Field(description="URI associated with this resource or media payload."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3032,17 +2892,24 @@ class NesDocumentDidChangeCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The sync kind the agent wants: `"full"` or `"incremental"`. - sync_kind: Annotated[ + + +class AudioContent(BaseModel): + # Optional annotations that help clients decide how to display or route this content. + annotations: Annotated[ + Optional[Annotations], + Field(description="Optional annotations that help clients decide how to display or route this content."), + ] = None + # Base64-encoded media payload. + data: Annotated[str, Field(description="Base64-encoded media payload.")] + # MIME type describing the encoded media payload. + mime_type: Annotated[ str, Field( - alias="syncKind", - description='The sync kind the agent wants: `"full"` or `"incremental"`.', + alias="mimeType", + description="MIME type describing the encoded media payload.", ), ] - - -class NesDocumentEventCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3055,49 +2922,63 @@ class NesDocumentEventCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the agent wants `document/didChange` events, and the sync kind. - did_change: Annotated[ - Optional[NesDocumentDidChangeCapabilities], - Field( - alias="didChange", - description="Whether the agent wants `document/didChange` events, and the sync kind.", - ), + + +class ResourceLink(BaseModel): + # Optional annotations that help clients decide how to display or route this content. + annotations: Annotated[ + Optional[Annotations], + Field(description="Optional annotations that help clients decide how to display or route this content."), ] = None - # Whether the agent wants `document/didClose` events. - did_close: Annotated[ - Optional[NesDocumentDidCloseCapabilities], - Field( - alias="didClose", - description="Whether the agent wants `document/didClose` events.", - ), + # Optional human-readable details shown with this protocol object. + description: Annotated[ + Optional[str], + Field(description="Optional human-readable details shown with this protocol object."), ] = None - # Whether the agent wants `document/didFocus` events. - did_focus: Annotated[ - Optional[NesDocumentDidFocusCapabilities], + # MIME type describing the encoded media payload. + mime_type: Annotated[ + Optional[str], Field( - alias="didFocus", - description="Whether the agent wants `document/didFocus` events.", + alias="mimeType", + description="MIME type describing the encoded media payload.", ), ] = None - # Whether the agent wants `document/didOpen` events. - did_open: Annotated[ - Optional[NesDocumentDidOpenCapabilities], - Field( - alias="didOpen", - description="Whether the agent wants `document/didOpen` events.", - ), + # Human-readable name shown for this protocol object. + name: Annotated[str, Field(description="Human-readable name shown for this protocol object.")] + # Optional size of the linked resource in bytes, if known. + size: Annotated[ + Optional[int], + Field(description="Optional size of the linked resource in bytes, if known."), ] = None - # Whether the agent wants `document/didSave` events. - did_save: Annotated[ - Optional[NesDocumentDidSaveCapabilities], + # Optional display title for end-user UI. + title: Annotated[Optional[str], Field(description="Optional display title for end-user UI.")] = None + # URI associated with this resource or media payload. + uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="didSave", - description="Whether the agent wants `document/didSave` events.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None -class NesEventCapabilities(BaseModel): +class EmbeddedResource(BaseModel): + # Optional annotations that help clients decide how to display or route this content. + annotations: Annotated[ + Optional[Annotations], + Field(description="Optional annotations that help clients decide how to display or route this content."), + ] = None + # Embedded resource payload, either text or binary data. + resource: Annotated[ + Union[TextResourceContents, BlobResourceContents], + Field(description="Embedded resource payload, either text or binary data."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3110,91 +2991,68 @@ class NesEventCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Document event capabilities. - document: Annotated[ - Optional[NesDocumentEventCapabilities], - Field(description="Document event capabilities."), - ] = None - - -class NesJumpSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The target position within the file. - position: Annotated[Position, Field(description="The target position within the file.")] - # The file to navigate to. - uri: Annotated[str, Field(description="The file to navigate to.")] -class NesOpenFile(BaseModel): - # The language identifier. - language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] - # Timestamp in milliseconds since epoch of when the file was last focused. - last_focused_ms: Annotated[ - Optional[int], +class PermissionOption(BaseModel): + # Unique identifier for this permission option. + option_id: Annotated[ + str, Field( - alias="lastFocusedMs", - description="Timestamp in milliseconds since epoch of when the file was last focused.", - ge=0, + alias="optionId", + description="Unique identifier for this permission option.", + ), + ] + # Human-readable label to display to the user. + name: Annotated[str, Field(description="Human-readable label to display to the user.")] + # Hint about the nature of this permission option. + kind: Annotated[PermissionOptionKind, Field(description="Hint about the nature of this permission option.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The URI of the file. - uri: Annotated[str, Field(description="The URI of the file.")] - # The visible range in the editor, if any. - visible_range: Annotated[ - Optional[Range], - Field(alias="visibleRange", description="The visible range in the editor, if any."), - ] = None - - -class NesRenameSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The new name for the symbol. - new_name: Annotated[str, Field(alias="newName", description="The new name for the symbol.")] - # The position of the symbol to rename. - position: Annotated[Position, Field(description="The position of the symbol to rename.")] - # The file URI containing the symbol. - uri: Annotated[str, Field(description="The file URI containing the symbol.")] - - -class NesJumpSuggestionVariant(NesJumpSuggestion): - kind: Literal["jump"] - - -class NesRenameSuggestionVariant(NesRenameSuggestion): - kind: Literal["rename"] -class NesTextEdit(BaseModel): - # The replacement text. - new_text: Annotated[str, Field(alias="newText", description="The replacement text.")] - # The range to replace. - range: Annotated[Range, Field(description="The range to replace.")] - - -class NesUserAction(BaseModel): - # The kind of action (e.g., "insertChar", "cursorMovement"). - action: Annotated[ - str, - Field(description='The kind of action (e.g., "insertChar", "cursorMovement").'), - ] - # The position where the action occurred. - position: Annotated[Position, Field(description="The position where the action occurred.")] - # Timestamp in milliseconds since epoch. - timestamp_ms: Annotated[ - int, +class CreateTerminalRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The command to execute. + command: Annotated[str, Field(description="The command to execute.")] + # Array of command arguments. + args: Annotated[Optional[List[str]], Field(description="Array of command arguments.")] = None + # Environment variables for the command. + env: Annotated[ + Optional[List[EnvVariable]], + Field(description="Environment variables for the command."), + ] = None + # Working directory for the command (absolute path). + cwd: Annotated[ + Optional[str], + Field(description="Working directory for the command (absolute path)."), + ] = None + # Maximum number of output bytes to retain. + # + # When the limit is exceeded, the Client truncates from the beginning of the output + # to stay within the limit. + # + # The Client MUST ensure truncation happens at a character boundary to maintain valid + # string output, even if this means the retained output is slightly less than the + # specified limit. + output_byte_limit: Annotated[ + Optional[int], Field( - alias="timestampMs", - description="Timestamp in milliseconds since epoch.", + alias="outputByteLimit", + description="Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", ge=0, ), - ] - # The URI of the file where the action occurred. - uri: Annotated[str, Field(description="The URI of the file where the action occurred.")] - - -class PermissionOption(BaseModel): + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3207,21 +3065,14 @@ class PermissionOption(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Hint about the nature of this permission option. - kind: Annotated[PermissionOptionKind, Field(description="Hint about the nature of this permission option.")] - # Human-readable label to display to the user. - name: Annotated[str, Field(description="Human-readable label to display to the user.")] - # Unique identifier for this permission option. - option_id: Annotated[ - str, - Field( - alias="optionId", - description="Unique identifier for this permission option.", - ), - ] -class PlanEntry(BaseModel): +class CreateUrlSessionElicitationRequest(ElicitationSessionScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3234,24 +3085,25 @@ class PlanEntry(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Human-readable description of what this task aims to accomplish. - content: Annotated[ + mode: Literal["url"] + # The unique identifier for this elicitation. + elicitation_id: Annotated[ str, - Field(description="Human-readable description of what this task aims to accomplish."), - ] - # The relative importance of this task. - # Used to indicate which tasks are most critical to the overall goal. - priority: Annotated[ - PlanEntryPriority, Field( - description="The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." + alias="elicitationId", + description="The unique identifier for this elicitation.", ), ] - # Current execution status of this task. - status: Annotated[PlanEntryStatus, Field(description="Current execution status of this task.")] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] -class PlanFile(BaseModel): +class CreateUrlRequestElicitationRequest(ElicitationRequestScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3264,13 +3116,40 @@ class PlanFile(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] - # The URI of the file containing the plan. - uri: Annotated[str, Field(description="The URI of the file containing the plan.")] + mode: Literal["url"] + # The unique identifier for this elicitation. + elicitation_id: Annotated[ + str, + Field( + alias="elicitationId", + description="The unique identifier for this elicitation.", + ), + ] + # The URL to direct the user to. + url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] -class PlanItems(BaseModel): +class ElicitationStringPropertySchema(StringPropertySchema): + type: Literal["string"] + + +class ElicitationNumberPropertySchema(NumberPropertySchema): + type: Literal["number"] + + +class ElicitationIntegerPropertySchema(IntegerPropertySchema): + type: Literal["integer"] + + +class ElicitationBooleanPropertySchema(BooleanPropertySchema): + type: Literal["boolean"] + + +class UntitledMultiSelectItems(BaseModel): + # Item type discriminator. Must be `"string"`. + type: Annotated[str, Field(description='Item type discriminator. Must be `"string"`.')] + # Allowed enum values. + enum: Annotated[List[str], Field(description="Allowed enum values.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3283,29 +3162,17 @@ class PlanItems(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The list of tasks to be accomplished. - # - # When updating an item-based plan, the agent must send a complete list of all entries - # with their current status. The client replaces that plan with each update. - entries: Annotated[ - List[PlanEntry], + + +class ConnectMcpRequest(BaseModel): + # The ACP MCP server ID that was provided by the component declaring the MCP server. + acp_id: Annotated[ + str, Field( - description="The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update." + alias="acpId", + description="The ACP MCP server ID that was provided by the component declaring the MCP server.", ), ] - # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] - - -class PlanUpdateItems(PlanItems): - type: Literal["items"] - - -class PlanUpdateFile(PlanFile): - type: Literal["file"] - - -class PromptResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3318,28 +3185,28 @@ class PromptResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Indicates why the agent stopped processing the turn. - stop_reason: Annotated[ - StopReason, + + +class MessageMcpRequest(BaseModel): + # The MCP-over-ACP connection this message is sent on. + connection_id: Annotated[ + str, Field( - alias="stopReason", - description="Indicates why the agent stopped processing the turn.", + alias="connectionId", + description="The MCP-over-ACP connection this message is sent on.", ), ] - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + # The inner MCP method name. + method: Annotated[str, Field(description="The inner MCP method name.")] + # Optional inner MCP params. # - # Token usage for this turn (optional). - usage: Annotated[ - Optional[Usage], + # If omitted or set to `null`, the inner MCP message has no params. + params: Annotated[ + Optional[Dict[str, Any]], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." + description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." ), ] = None - - -class ReadTextFileRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3352,20 +3219,57 @@ class ReadTextFileRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Maximum number of lines to read. - limit: Annotated[Optional[int], Field(description="Maximum number of lines to read.", ge=0)] = None - # Line number to start reading from (1-based). - line: Annotated[ - Optional[int], - Field(description="Line number to start reading from (1-based).", ge=0), - ] = None - # Absolute path to the file to read. - path: Annotated[str, Field(description="Absolute path to the file to read.")] - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] -class RejectNesNotification(BaseModel): +class SessionCapabilities(BaseModel): + # Whether the agent supports `session/list`. + list: Annotated[ + Optional[SessionListCapabilities], + Field(description="Whether the agent supports `session/list`."), + ] = None + # Whether the agent supports `session/delete`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports deleting sessions from `session/list`. + delete: Annotated[ + Optional[SessionDeleteCapabilities], + Field( + description="Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." + ), + ] = None + # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. + # + # Agents that also support `session/list` may return + # `SessionInfo.additionalDirectories` to report the complete ordered + # additional-root list associated with a listed session. + additional_directories: Annotated[ + Optional[SessionAdditionalDirectoriesCapabilities], + Field( + alias="additionalDirectories", + description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Whether the agent supports `session/fork`. + fork: Annotated[ + Optional[SessionForkCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + ), + ] = None + # Whether the agent supports `session/resume`. + resume: Annotated[ + Optional[SessionResumeCapabilities], + Field(description="Whether the agent supports `session/resume`."), + ] = None + # Whether the agent supports `session/close`. + close: Annotated[ + Optional[SessionCloseCapabilities], + Field(description="Whether the agent supports `session/close`."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3378,41 +3282,18 @@ class RejectNesNotification(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The ID of the rejected suggestion. - id: Annotated[str, Field(description="The ID of the rejected suggestion.")] - # The reason for rejection. - reason: Annotated[Optional[str], Field(description="The reason for rejection.")] = None - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] -class ReleaseTerminalRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. +class AgentAuthCapabilities(BaseModel): + # Whether the agent supports the logout method. # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], + # By supplying `{}` it means that the agent supports the logout method. + logout: Annotated[ + Optional[LogoutCapabilities], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + description="Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." ), ] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to release. - terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to release.")] - - -class AllowedOutcome(SelectedPermissionOutcome): - outcome: Literal["selected"] - - -class RequestPermissionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3425,17 +3306,17 @@ class RequestPermissionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The user's decision on the permission request. - outcome: Annotated[ - Union[DeniedOutcome, AllowedOutcome], + + +class NesDocumentDidChangeCapabilities(BaseModel): + # The sync kind the agent wants: `"full"` or `"incremental"`. + sync_kind: Annotated[ + str, Field( - description="The user's decision on the permission request.", - discriminator="outcome", + alias="syncKind", + description='The sync kind the agent wants: `"full"` or `"incremental"`.', ), ] - - -class ResourceLink(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3448,79 +3329,51 @@ class ResourceLink(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - description: Optional[str] = None - mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None - name: str - size: Optional[int] = None - title: Optional[str] = None - uri: str -class SessionCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], +class NesContextCapabilities(BaseModel): + # Whether the agent wants recent files context. + recent_files: Annotated[ + Optional[NesRecentFilesCapabilities], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + alias="recentFiles", + description="Whether the agent wants recent files context.", ), ] = None - # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. - # - # Agents that also support `session/list` may return - # `SessionInfo.additionalDirectories` to report the complete ordered - # additional-root list associated with a listed session. - additional_directories: Annotated[ - Optional[SessionAdditionalDirectoriesCapabilities], + # Whether the agent wants related snippets context. + related_snippets: Annotated[ + Optional[NesRelatedSnippetsCapabilities], Field( - alias="additionalDirectories", - description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + alias="relatedSnippets", + description="Whether the agent wants related snippets context.", ), ] = None - # Whether the agent supports `session/close`. - close: Annotated[ - Optional[SessionCloseCapabilities], - Field(description="Whether the agent supports `session/close`."), - ] = None - # Whether the agent supports `session/delete`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports deleting sessions from `session/list`. - delete: Annotated[ - Optional[SessionDeleteCapabilities], + # Whether the agent wants edit history context. + edit_history: Annotated[ + Optional[NesEditHistoryCapabilities], Field( - description="Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." + alias="editHistory", + description="Whether the agent wants edit history context.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Whether the agent supports `session/fork`. - fork: Annotated[ - Optional[SessionForkCapabilities], + # Whether the agent wants user actions context. + user_actions: Annotated[ + Optional[NesUserActionsCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + alias="userActions", + description="Whether the agent wants user actions context.", ), ] = None - # Whether the agent supports `session/list`. - list: Annotated[ - Optional[SessionListCapabilities], - Field(description="Whether the agent supports `session/list`."), + # Whether the agent wants open files context. + open_files: Annotated[ + Optional[NesOpenFilesCapabilities], + Field(alias="openFiles", description="Whether the agent wants open files context."), ] = None - # Whether the agent supports `session/resume`. - resume: Annotated[ - Optional[SessionResumeCapabilities], - Field(description="Whether the agent supports `session/resume`."), + # Whether the agent wants diagnostics context. + diagnostics: Annotated[ + Optional[NesDiagnosticsCapabilities], + Field(description="Whether the agent wants diagnostics context."), ] = None - - -class SessionConfigOptionBoolean(SessionConfigBoolean): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3533,24 +3386,35 @@ class SessionConfigOptionBoolean(SessionConfigBoolean): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional semantic category for this option (UX only). - category: Annotated[ - Optional[str], - Field(description="Optional semantic category for this option (UX only)."), - ] = None - # Optional description for the Client to display to the user. - description: Annotated[ - Optional[str], - Field(description="Optional description for the Client to display to the user."), - ] = None - # Unique identifier for the configuration option. - id: Annotated[str, Field(description="Unique identifier for the configuration option.")] - # Human-readable label for the option. - name: Annotated[str, Field(description="Human-readable label for the option.")] - type: Literal["boolean"] -class SessionConfigSelectOption(BaseModel): +class EnvVarAuthMethod(AuthMethodEnvVar): + type: Literal["env_var"] + + +class TerminalAuthMethod(AuthMethodTerminal): + type: Literal["terminal"] + + +class ProviderInfo(BaseModel): + # Provider identifier, for example "main" or "openai". + id: Annotated[str, Field(description='Provider identifier, for example "main" or "openai".')] + # Supported protocol types for this provider. + supported: Annotated[List[str], Field(description="Supported protocol types for this provider.")] + # Whether this provider is mandatory and cannot be disabled via `providers/disable`. + # If true, clients must not call `providers/disable` for this id. + required: Annotated[ + bool, + Field( + description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id." + ), + ] + # Current effective non-secret routing config. + # Null or omitted means provider is disabled. + current: Annotated[ + Optional[ProviderCurrentConfig], + Field(description="Current effective non-secret routing config.\nNull or omitted means provider is disabled."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3563,15 +3427,22 @@ class SessionConfigSelectOption(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Optional description for this option value. - description: Annotated[Optional[str], Field(description="Optional description for this option value.")] = None - # Human-readable label for this option value. - name: Annotated[str, Field(description="Human-readable label for this option value.")] - # Unique identifier for this option value. - value: Annotated[str, Field(description="Unique identifier for this option value.")] -class SessionMode(BaseModel): +class SessionModeState(BaseModel): + # The current mode the Agent is in. + current_mode_id: Annotated[ + str, + Field(alias="currentModeId", description="The current mode the Agent is in."), + ] + # The set of modes that the Agent can operate in + available_modes: Annotated[ + List[SessionMode], + Field( + alias="availableModes", + description="The set of modes that the Agent can operate in", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3584,13 +3455,23 @@ class SessionMode(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - description: Optional[str] = None - # Unique identifier for a Session Mode. - id: Annotated[str, Field(description="Unique identifier for a Session Mode.")] - name: str -class SessionModeState(BaseModel): +class SessionConfigOptionBoolean(SessionConfigBoolean): + # Unique identifier for the configuration option. + id: Annotated[str, Field(description="Unique identifier for the configuration option.")] + # Human-readable label for the option. + name: Annotated[str, Field(description="Human-readable label for the option.")] + # Optional description for the Client to display to the user. + description: Annotated[ + Optional[str], + Field(description="Optional description for the Client to display to the user."), + ] = None + # Optional semantic category for this option (UX only). + category: Annotated[ + Optional[str], + Field(description="Optional semantic category for this option (UX only)."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3603,30 +3484,19 @@ class SessionModeState(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The set of modes that the Agent can operate in - available_modes: Annotated[ - List[SessionMode], - Field( - alias="availableModes", - description="The set of modes that the Agent can operate in", - ), - ] - # The current mode the Agent is in. - current_mode_id: Annotated[ - str, - Field(alias="currentModeId", description="The current mode the Agent is in."), - ] - - -class CurrentModeUpdate(_CurrentModeUpdate): - session_update: Annotated[Literal["current_mode_update"], Field(alias="sessionUpdate")] - - -class UsageUpdate(_UsageUpdate): - session_update: Annotated[Literal["usage_update"], Field(alias="sessionUpdate")] + type: Literal["boolean"] -class StartNesRequest(BaseModel): +class SessionConfigSelectGroup(BaseModel): + # Unique identifier for this group. + group: Annotated[str, Field(description="Unique identifier for this group.")] + # Human-readable label for this group. + name: Annotated[str, Field(description="Human-readable label for this group.")] + # The set of option values in this group. + options: Annotated[ + List[SessionConfigSelectOption], + Field(description="The set of option values in this group."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3639,24 +3509,20 @@ class StartNesRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Repository metadata, if the workspace is a git repository. - repository: Annotated[ - Optional[NesRepository], - Field(description="Repository metadata, if the workspace is a git repository."), - ] = None - # The workspace folders. - workspace_folders: Annotated[ - Optional[List[WorkspaceFolder]], - Field(alias="workspaceFolders", description="The workspace folders."), - ] = None - # The root URI of the workspace. - workspace_uri: Annotated[ - Optional[str], - Field(alias="workspaceUri", description="The root URI of the workspace."), - ] = None -class TextContent(BaseModel): +class ListSessionsResponse(BaseModel): + # Array of session information objects + sessions: Annotated[List[SessionInfo], Field(description="Array of session information objects")] + # Opaque cursor token. If present, pass this in the next request's cursor parameter + # to fetch the next page. If absent, there are no more results. + next_cursor: Annotated[ + Optional[str], + Field( + alias="nextCursor", + description="Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3669,30 +3535,28 @@ class TextContent(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - text: str -class AgentErrorMessage(BaseModel): - error: Error - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. +class PromptResponse(BaseModel): + # Indicates why the agent stopped processing the turn. + stop_reason: Annotated[ + StopReason, + Field( + alias="stopReason", + description="Indicates why the agent stopped processing the turn.", + ), + ] + # **UNSTABLE** # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # This capability is not part of the spec yet, and may be removed or changed at any point. # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. - id: Annotated[ - Optional[Union[int, str]], + # Token usage for this turn (optional). + usage: Annotated[ + Optional[Usage], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." ), ] = None - - -class AvailableCommand(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3705,21 +3569,25 @@ class AvailableCommand(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Human-readable description of what the command does. - description: Annotated[str, Field(description="Human-readable description of what the command does.")] - # Input for the command if required - input: Annotated[ - Optional[AvailableCommandInput], - Field(description="Input for the command if required"), - ] = None - # Command name (e.g., `create_plan`, `research_codebase`). - name: Annotated[ - str, - Field(description="Command name (e.g., `create_plan`, `research_codebase`)."), - ] -class _AvailableCommandsUpdate(BaseModel): +class NesJumpSuggestionVariant(NesJumpSuggestion): + kind: Literal["jump"] + + +class NesRenameSuggestionVariant(NesRenameSuggestion): + kind: Literal["rename"] + + +class NesSearchAndReplaceSuggestionVariant(NesSearchAndReplaceSuggestion): + kind: Literal["searchAndReplace"] + + +class Range(BaseModel): + # The start position (inclusive). + start: Annotated[Position, Field(description="The start position (inclusive).")] + # The end position (exclusive). + end: Annotated[Position, Field(description="The end position (exclusive).")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3732,14 +3600,67 @@ class _AvailableCommandsUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Commands the agent can execute - available_commands: Annotated[ - List[AvailableCommand], - Field(alias="availableCommands", description="Commands the agent can execute"), + + +class Error(BaseModel): + # A number indicating the error type that occurred. + # This must be an integer as defined in the JSON-RPC specification. + code: Annotated[ + int, + Field( + description="A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." + ), ] + # A string providing a short description of the error. + # The message should be limited to a concise single sentence. + message: Annotated[ + str, + Field( + description="A string providing a short description of the error.\nThe message should be limited to a concise single sentence." + ), + ] + # Optional primitive or structured value that contains additional information about the error. + # This may include debugging information or context-specific details. + data: Annotated[ + Optional[Any], + Field( + description="Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." + ), + ] = None -class ClientCapabilities(BaseModel): +class AgentPlanRemovedUpdate(PlanRemoved): + session_update: Annotated[Literal["plan_removed"], Field(alias="sessionUpdate")] + + +class CurrentModeUpdate(_CurrentModeUpdate): + session_update: Annotated[Literal["current_mode_update"], Field(alias="sessionUpdate")] + + +class SessionInfoUpdate(_SessionInfoUpdate): + session_update: Annotated[Literal["session_info_update"], Field(alias="sessionUpdate")] + + +class UsageUpdate(_UsageUpdate): + session_update: Annotated[Literal["usage_update"], Field(alias="sessionUpdate")] + + +class PlanEntry(BaseModel): + # Human-readable description of what this task aims to accomplish. + content: Annotated[ + str, + Field(description="Human-readable description of what this task aims to accomplish."), + ] + # The relative importance of this task. + # Used to indicate which tasks are most critical to the overall goal. + priority: Annotated[ + PlanEntryPriority, + Field( + description="The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." + ), + ] + # Current execution status of this task. + status: Annotated[PlanEntryStatus, Field(description="Current execution status of this task.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3752,184 +3673,147 @@ class ClientCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + + +class Plan(BaseModel): + # The list of tasks to be accomplished. # - # Authentication capabilities supported by the client. - # Determines which authentication method types the agent may include - # in its `InitializeResponse`. - auth: Annotated[ - Optional[AuthCapabilities], + # When updating a plan, the agent must send a complete list of all entries + # with their current status. The client replaces the entire plan with each update. + entries: Annotated[ + List[PlanEntry], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." + description="The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update." ), - ] = {"terminal": False} - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # Elicitation capabilities supported by the client. - # Determines which elicitation modes the agent may use. - elicitation: Annotated[ - Optional[ElicitationCapabilities], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # File system capabilities supported by the client. - # Determines which file operations the agent can request. - fs: Annotated[ - Optional[FileSystemCapabilities], + + +class PlanUpdateFile(PlanFile): + type: Literal["file"] + + +class PlanUpdateMarkdown(PlanMarkdown): + type: Literal["markdown"] + + +class PlanItems(BaseModel): + # The plan ID to update. + id: Annotated[str, Field(description="The plan ID to update.")] + # The list of tasks to be accomplished. + # + # When updating an item-based plan, the agent must send a complete list of all entries + # with their current status. The client replaces that plan with each update. + entries: Annotated[ + List[PlanEntry], Field( - description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." + description="The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update." ), - ] = FileSystemCapabilities() - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # NES (Next Edit Suggestions) capabilities supported by the client. - nes: Annotated[ - Optional[ClientNesCapabilities], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Whether the client supports `plan_update` and `plan_removed` session updates. + + +class AvailableCommandInput(RootModel[UnstructuredCommandInput]): + # The input specification for a command. + root: Annotated[ + UnstructuredCommandInput, + Field(description="The input specification for a command."), + ] + + +class SessionConfigOptionsCapabilities(BaseModel): + # Whether the client supports boolean session configuration options. # - # Optional. Omitted means the client does not advertise support. - # Supplying `{}` means the client can receive both update types. - plan: Annotated[ - Optional[PlanCapabilities], + # Omitted or `null` means the client does not advertise support. + # Supplying `{}` means agents may include `type: "boolean"` entries in + # `configOptions`, and the client may send `session/set_config_option` + # requests with `type: "boolean"` and a boolean `value`. + boolean: Annotated[ + Optional[BooleanConfigOptionCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types." + description='Whether the client supports boolean session configuration options.\n\nOmitted or `null` means the client does not advertise support.\nSupplying `{}` means agents may include `type: "boolean"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: "boolean"` and a boolean `value`.' ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # The position encodings supported by the client, in order of preference. - position_encodings: Annotated[ - Optional[List[str]], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="positionEncodings", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Whether the Client support all `terminal/*` methods. - terminal: Annotated[ - Optional[bool], - Field(description="Whether the Client support all `terminal/*` methods."), - ] = False -class ClientNotification(BaseModel): - method: str - params: Optional[ - Union[ - CancelNotification, - DidOpenDocumentNotification, - DidChangeDocumentNotification, - DidCloseDocumentNotification, - DidSaveDocumentNotification, - DidFocusDocumentNotification, - AcceptNesNotification, - RejectNesNotification, - MessageMcpNotification, - Any, - ] +class ElicitationCapabilities(BaseModel): + # Whether the client supports form-based elicitation. + form: Annotated[ + Optional[ElicitationFormCapabilities], + Field(description="Whether the client supports form-based elicitation."), ] = None - - -class ClientResponseMessage(BaseModel): - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. - # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. - # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. - id: Annotated[ - Optional[Union[int, str]], - Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." - ), + # Whether the client supports URL-based elicitation. + url: Annotated[ + Optional[ElicitationUrlCapabilities], + Field(description="Whether the client supports URL-based elicitation."), ] = None - # All possible responses that a client can send to an agent. - # - # This enum is used internally for routing RPC responses. You typically won't need - # to use this directly - the responses are handled automatically by the connection. + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # These are responses to the corresponding `AgentRequest` variants. - result: Annotated[ - Union[ - WriteTextFileResponse, - ReadTextFileResponse, - RequestPermissionResponse, - CreateTerminalResponse, - TerminalOutputResponse, - ReleaseTerminalResponse, - WaitForTerminalExitResponse, - KillTerminalResponse, - ConnectMcpResponse, - DisconnectMcpResponse, - Union[ - AcceptElicitationResponse, - DeclineElicitationResponse, - CancelElicitationResponse, - ], - Any, - ], + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - description="All possible responses that a client can send to an agent.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `AgentRequest` variants." + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] + ] = None -class ClientErrorMessage(BaseModel): - error: Error - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. - # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. - # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. - id: Annotated[ - Optional[Union[int, str]], +class ClientNesCapabilities(BaseModel): + # Whether the client supports the `jump` suggestion kind. + jump: Annotated[ + Optional[NesJumpCapabilities], + Field(description="Whether the client supports the `jump` suggestion kind."), + ] = None + # Whether the client supports the `rename` suggestion kind. + rename: Annotated[ + Optional[NesRenameCapabilities], + Field(description="Whether the client supports the `rename` suggestion kind."), + ] = None + # Whether the client supports the `searchAndReplace` suggestion kind. + search_and_replace: Annotated[ + Optional[NesSearchAndReplaceCapabilities], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + alias="searchAndReplace", + description="Whether the client supports the `searchAndReplace` suggestion kind.", ), ] = None - - -class ClientResponse(RootModel[Union[ClientResponseMessage, ClientErrorMessage]]): - root: Union[ClientResponseMessage, ClientErrorMessage] - - -class TextContentBlock(TextContent): - type: Literal["text"] - - -class ImageContentBlock(ImageContent): - type: Literal["image"] - - -class ResourceContentBlock(ResourceLink): - type: Literal["resource_link"] - - -class CreateUrlElicitationRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3942,49 +3826,46 @@ class CreateUrlElicitationRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - mode: Literal["url"] -class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): - type: Literal["array"] +class HttpMcpServer(McpServerHttp): + type: Literal["http"] -class ElicitationSchema(BaseModel): - # Optional description of what this schema represents. - description: Annotated[ - Optional[str], - Field(description="Optional description of what this schema represents."), - ] = None - # Property definitions (must be primitive types). - properties: Annotated[ - Optional[ - Dict[ - str, - Union[ - ElicitationStringPropertySchema, - ElicitationNumberPropertySchema, - ElicitationIntegerPropertySchema, - ElicitationBooleanPropertySchema, - ElicitationMultiSelectPropertySchema, - ], - ] - ], - Field(description="Property definitions (must be primitive types)."), - ] = {} - # List of required property names. - required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None - # Optional title for the schema. - title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None - # Type discriminator. Always `"object"`. - type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" +class SseMcpServer(McpServerSse): + type: Literal["sse"] -class EmbeddedResource(BaseModel): +class AcpMcpServer(McpServerAcp): + type: Literal["acp"] + + +class LoadSessionRequest(BaseModel): + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], + Field( + alias="mcpServers", + description="List of MCP servers to connect to for this session.", + ), + ] + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the loaded + # session. It may differ from any previously used or reported list as long as + # the request `cwd` matches the session's `cwd`. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", + ), + ] = None + # The ID of the session to load. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3997,15 +3878,33 @@ class EmbeddedResource(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - annotations: Optional[Annotations] = None - # Resource content that can be embedded in a message. - resource: Annotated[ - Union[TextResourceContents, BlobResourceContents], - Field(description="Resource content that can be embedded in a message."), - ] -class InitializeRequest(BaseModel): +class ForkSessionRequest(BaseModel): + # The ID of the session to fork. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # Additional workspace roots to activate for this session. Each path must be absolute. + # + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the forked + # session. + additional_directories: Annotated[ + Optional[List[str]], + Field( + alias="additionalDirectories", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + ), + ] = None + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], + Field( + alias="mcpServers", + description="List of MCP servers to connect to for this session.", + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4018,55 +3917,34 @@ class InitializeRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Capabilities supported by the client. - client_capabilities: Annotated[ - Optional[ClientCapabilities], - Field( - alias="clientCapabilities", - description="Capabilities supported by the client.", - ), - ] = ClientCapabilities() - # Information about the Client name and version sent to the Agent. + + +class ResumeSessionRequest(BaseModel): + # The ID of the session to resume. + session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] + # The working directory for this session. + cwd: Annotated[str, Field(description="The working directory for this session.")] + # Additional workspace roots to activate for this session. Each path must be absolute. # - # Note: in future versions of the protocol, this will be required. - client_info: Annotated[ - Optional[Implementation], + # When omitted or empty, no additional roots are activated. When non-empty, + # this is the complete resulting additional-root list for the resumed + # session. It may differ from any previously used or reported list as long as + # the request `cwd` matches the session's `cwd`. + additional_directories: Annotated[ + Optional[List[str]], Field( - alias="clientInfo", - description="Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", + alias="additionalDirectories", + description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", ), ] = None - # The latest protocol version supported by the client. - protocol_version: Annotated[ - int, + # List of MCP servers to connect to for this session. + mcp_servers: Annotated[ + Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], Field( - alias="protocolVersion", - description="The latest protocol version supported by the client.", - ge=0, - le=65535, + alias="mcpServers", + description="List of MCP servers to connect to for this session.", ), - ] - - @field_validator("protocol_version", mode="before") - @classmethod - def _coerce_protocol_version(cls, value: Any) -> int: - # Some clients (e.g. Zed) send a date string like "2024-11-05" instead - # of an integer. The Rust SDK treats legacy strings as version 0; this - # SDK maps unparsable values to 1 so the connection is not rejected. - # See: https://github.com/agentclientprotocol/rust-sdk/blob/main/crates/agent-client-protocol-schema/src/version.rs - if isinstance(value, int): - return value - try: - return int(value) - except (TypeError, ValueError): - return 1 - - -class AcpMcpServer(McpServerAcp): - type: Literal["acp"] - - -class NesCapabilities(BaseModel): + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4079,36 +3957,43 @@ class NesCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Context the agent wants attached to each suggestion request. - context: Annotated[ - Optional[NesContextCapabilities], - Field(description="Context the agent wants attached to each suggestion request."), - ] = None - # Events the agent wants to receive. - events: Annotated[ - Optional[NesEventCapabilities], - Field(description="Events the agent wants to receive."), - ] = None -class NesEditSuggestion(BaseModel): - # Optional suggested cursor position after applying edits. - cursor_position: Annotated[ - Optional[Position], +class StartNesRequest(BaseModel): + # The root URI of the workspace. + workspace_uri: Annotated[ + Optional[str], + Field(alias="workspaceUri", description="The root URI of the workspace."), + ] = None + # The workspace folders. + workspace_folders: Annotated[ + Optional[List[WorkspaceFolder]], + Field(alias="workspaceFolders", description="The workspace folders."), + ] = None + # Repository metadata, if the workspace is a git repository. + repository: Annotated[ + Optional[NesRepository], + Field(description="Repository metadata, if the workspace is a git repository."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="cursorPosition", - description="Optional suggested cursor position after applying edits.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The text edits to apply. - edits: Annotated[List[NesTextEdit], Field(description="The text edits to apply.")] - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The URI of the file to edit. - uri: Annotated[str, Field(description="The URI of the file to edit.")] -class NesSuggestContext(BaseModel): +class NesRelatedSnippet(BaseModel): + # The URI of the file containing the snippets. + uri: Annotated[str, Field(description="The URI of the file containing the snippets.")] + # The code excerpts. + excerpts: Annotated[List[NesExcerpt], Field(description="The code excerpts.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4121,46 +4006,27 @@ class NesSuggestContext(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Current diagnostics (errors, warnings). - diagnostics: Annotated[ - Optional[List[NesDiagnostic]], - Field(description="Current diagnostics (errors, warnings)."), - ] = None - # Recent edit history. - edit_history: Annotated[ - Optional[List[NesEditHistoryEntry]], - Field(alias="editHistory", description="Recent edit history."), - ] = None - # Currently open files in the editor. - open_files: Annotated[ - Optional[List[NesOpenFile]], - Field(alias="openFiles", description="Currently open files in the editor."), - ] = None - # Recently accessed files. - recent_files: Annotated[ - Optional[List[NesRecentFile]], - Field(alias="recentFiles", description="Recently accessed files."), - ] = None - # Related code snippets. - related_snippets: Annotated[ - Optional[List[NesRelatedSnippet]], - Field(alias="relatedSnippets", description="Related code snippets."), + + +class NesOpenFile(BaseModel): + # The URI of the file. + uri: Annotated[str, Field(description="The URI of the file.")] + # The language identifier. + language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] + # The visible range in the editor, if any. + visible_range: Annotated[ + Optional[Range], + Field(alias="visibleRange", description="The visible range in the editor, if any."), ] = None - # Recent user actions (typing, navigation, etc.). - user_actions: Annotated[ - Optional[List[NesUserAction]], + # Timestamp in milliseconds since epoch of when the file was last focused. + last_focused_ms: Annotated[ + Optional[int], Field( - alias="userActions", - description="Recent user actions (typing, navigation, etc.).", + alias="lastFocusedMs", + description="Timestamp in milliseconds since epoch of when the file was last focused.", + ge=0, ), ] = None - - -class NesEditSuggestionVariant(NesEditSuggestion): - kind: Literal["edit"] - - -class NewSessionRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4173,34 +4039,17 @@ class NewSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Additional workspace roots for this session. Each path must be absolute. - # - # These expand the session's filesystem scope without changing `cwd`, which - # remains the base for relative paths. When omitted or empty, no - # additional roots are activated for the new session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", - ), - ] = None - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # List of MCP (Model Context Protocol) servers the agent should connect to. - mcp_servers: Annotated[ - List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], - Field( - alias="mcpServers", - description="List of MCP (Model Context Protocol) servers the agent should connect to.", - ), - ] -class Plan(BaseModel): +class NesDiagnostic(BaseModel): + # The URI of the file containing the diagnostic. + uri: Annotated[str, Field(description="The URI of the file containing the diagnostic.")] + # The range of the diagnostic. + range: Annotated[Range, Field(description="The range of the diagnostic.")] + # The severity of the diagnostic. + severity: Annotated[str, Field(description="The severity of the diagnostic.")] + # The diagnostic message. + message: Annotated[str, Field(description="The diagnostic message.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4213,19 +4062,32 @@ class Plan(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The list of tasks to be accomplished. - # - # When updating a plan, the agent must send a complete list of all entries - # with their current status. The client replaces the entire plan with each update. - entries: Annotated[ - List[PlanEntry], - Field( - description="The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update." - ), - ] -class PlanUpdate(BaseModel): +class ClientErrorMessage(BaseModel): + # The id of the request this response answers. + id: Annotated[ + Optional[Union[int, str]], + Field(description="The id of the request this response answers."), + ] = None + # Method-specific error data. + error: Annotated[Error, Field(description="Method-specific error data.")] + + +class AllowedOutcome(SelectedPermissionOutcome): + outcome: Literal["selected"] + + +class TerminalOutputResponse(BaseModel): + # The terminal output captured so far. + output: Annotated[str, Field(description="The terminal output captured so far.")] + # Whether the output was truncated due to byte limits. + truncated: Annotated[bool, Field(description="Whether the output was truncated due to byte limits.")] + # Exit status if the command has completed. + exit_status: Annotated[ + Optional[TerminalExitStatus], + Field(alias="exitStatus", description="Exit status if the command has completed."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4238,14 +4100,9 @@ class PlanUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The updated plan content. - plan: Annotated[ - Union[PlanUpdateItems, PlanUpdateFile, PlanUpdateMarkdown], - Field(description="The updated plan content.", discriminator="type"), - ] -class ResumeSessionRequest(BaseModel): +class AcceptElicitationResponse(ElicitationAcceptAction): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4258,34 +4115,20 @@ class ResumeSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the resumed - # session. It may differ from any previously used or reported list as long as - # the request `cwd` matches the session's `cwd`. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - ), - ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. - mcp_servers: Annotated[ - Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] = None - # The ID of the session to resume. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] + action: Literal["accept"] -class SessionConfigSelectGroup(BaseModel): +class TextDocumentContentChangeEvent(BaseModel): + # The range of the document that changed. If `None`, the entire content is replaced. + range: Annotated[ + Optional[Range], + Field(description="The range of the document that changed. If `None`, the entire content is replaced."), + ] = None + # The new text for the range, or the full document content if `range` is `None`. + text: Annotated[ + str, + Field(description="The new text for the range, or the full document content if `range` is `None`."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4298,30 +4141,28 @@ class SessionConfigSelectGroup(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Unique identifier for this group. - group: Annotated[str, Field(description="Unique identifier for this group.")] - # Human-readable label for this group. - name: Annotated[str, Field(description="Human-readable label for this group.")] - # The set of option values in this group. - options: Annotated[ - List[SessionConfigSelectOption], - Field(description="The set of option values in this group."), - ] - - -class AgentPlanUpdate(Plan): - session_update: Annotated[Literal["plan"], Field(alias="sessionUpdate")] -class AgentPlanContentUpdate(PlanUpdate): - session_update: Annotated[Literal["plan_update"], Field(alias="sessionUpdate")] - - -class AvailableCommandsUpdate(_AvailableCommandsUpdate): - session_update: Annotated[Literal["available_commands_update"], Field(alias="sessionUpdate")] - - -class SuggestNesRequest(BaseModel): +class DidFocusDocumentNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the focused document. + uri: Annotated[str, Field(description="The URI of the focused document.")] + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + # The current cursor position. + position: Annotated[Position, Field(description="The current cursor position.")] + # The portion of the file currently visible in the editor viewport. + visible_range: Annotated[ + Range, + Field( + alias="visibleRange", + description="The portion of the file currently visible in the editor viewport.", + ), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4334,29 +4175,18 @@ class SuggestNesRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Context for the suggestion, included based on agent capabilities. - context: Annotated[ - Optional[NesSuggestContext], - Field(description="Context for the suggestion, included based on agent capabilities."), - ] = None - # The current cursor position. - position: Annotated[Position, Field(description="The current cursor position.")] - # The current text selection range, if any. - selection: Annotated[Optional[Range], Field(description="The current text selection range, if any.")] = None - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # What triggered this suggestion request. - trigger_kind: Annotated[ - str, - Field(alias="triggerKind", description="What triggered this suggestion request."), - ] - # The URI of the document to suggest for. - uri: Annotated[str, Field(description="The URI of the document to suggest for.")] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] -class SuggestNesResponse(BaseModel): +class RejectNesNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The ID of the rejected suggestion. + id: Annotated[str, Field(description="The ID of the rejected suggestion.")] + # The reason for rejection. + reason: Annotated[Optional[str], Field(description="The reason for rejection.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4369,21 +4199,36 @@ class SuggestNesResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The list of suggestions. - suggestions: Annotated[ - List[ - Union[ - NesEditSuggestionVariant, - NesJumpSuggestionVariant, - NesRenameSuggestionVariant, - NesSearchAndReplaceSuggestionVariant, - ] - ], - Field(description="The list of suggestions."), - ] -class AgentCapabilities(BaseModel): +class TextContentBlock(TextContent): + type: Literal["text"] + + +class ImageContentBlock(ImageContent): + type: Literal["image"] + + +class AudioContentBlock(AudioContent): + type: Literal["audio"] + + +class ResourceContentBlock(ResourceLink): + type: Literal["resource_link"] + + +class EmbeddedResourceContentBlock(EmbeddedResource): + type: Literal["resource"] + + +class Content(BaseModel): + # The actual content block. + content: Annotated[ + Union[ + TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock + ], + Field(description="The actual content block.", discriminator="type"), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4396,81 +4241,95 @@ class AgentCapabilities(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Authentication-related capabilities supported by the agent. - auth: Annotated[ - Optional[AgentAuthCapabilities], - Field(description="Authentication-related capabilities supported by the agent."), - ] = {} - # Whether the agent supports `session/load`. - load_session: Annotated[ - Optional[bool], + + +class MultiSelectPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Minimum number of items to select. + min_items: Annotated[ + Optional[int], + Field(alias="minItems", description="Minimum number of items to select.", ge=0), + ] = None + # Maximum number of items to select. + max_items: Annotated[ + Optional[int], + Field(alias="maxItems", description="Maximum number of items to select.", ge=0), + ] = None + # The items definition describing allowed values. + items: Annotated[ + Union[UntitledMultiSelectItems, TitledMultiSelectItems], + Field(description="The items definition describing allowed values."), + ] + # Default selected values. + default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], Field( - alias="loadSession", - description="Whether the agent supports `session/load`.", + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), - ] = False - # MCP capabilities supported by the agent. - mcp_capabilities: Annotated[ - Optional[McpCapabilities], + ] = None + + +class AgentErrorMessage(BaseModel): + # The id of the request this response answers. + id: Annotated[ + Optional[Union[int, str]], + Field(description="The id of the request this response answers."), + ] = None + # Method-specific error data. + error: Annotated[Error, Field(description="Method-specific error data.")] + + +class NesDocumentEventCapabilities(BaseModel): + # Whether the agent wants `document/didOpen` events. + did_open: Annotated[ + Optional[NesDocumentDidOpenCapabilities], Field( - alias="mcpCapabilities", - description="MCP capabilities supported by the agent.", + alias="didOpen", + description="Whether the agent wants `document/didOpen` events.", ), - ] = McpCapabilities() - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # NES (Next Edit Suggestions) capabilities supported by the agent. - nes: Annotated[ - Optional[NesCapabilities], + ] = None + # Whether the agent wants `document/didChange` events, and the sync kind. + did_change: Annotated[ + Optional[NesDocumentDidChangeCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." + alias="didChange", + description="Whether the agent wants `document/didChange` events, and the sync kind.", ), ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # The position encoding selected by the agent from the client's supported encodings. - position_encoding: Annotated[ - Optional[str], + # Whether the agent wants `document/didClose` events. + did_close: Annotated[ + Optional[NesDocumentDidCloseCapabilities], Field( - alias="positionEncoding", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", + alias="didClose", + description="Whether the agent wants `document/didClose` events.", ), ] = None - # Prompt capabilities supported by the agent. - prompt_capabilities: Annotated[ - Optional[PromptCapabilities], + # Whether the agent wants `document/didSave` events. + did_save: Annotated[ + Optional[NesDocumentDidSaveCapabilities], Field( - alias="promptCapabilities", - description="Prompt capabilities supported by the agent.", + alias="didSave", + description="Whether the agent wants `document/didSave` events.", ), - ] = PromptCapabilities() - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Provider configuration capabilities supported by the agent. - # - # By supplying `{}` it means that the agent supports provider configuration methods. - providers: Annotated[ - Optional[ProvidersCapabilities], + ] = None + # Whether the agent wants `document/didFocus` events. + did_focus: Annotated[ + Optional[NesDocumentDidFocusCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." + alias="didFocus", + description="Whether the agent wants `document/didFocus` events.", ), ] = None - session_capabilities: Annotated[Optional[SessionCapabilities], Field(alias="sessionCapabilities")] = ( - SessionCapabilities() - ) - - -class EmbeddedResourceContentBlock(EmbeddedResource): - type: Literal["resource"] - - -class ContentChunk(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4483,63 +4342,14 @@ class ContentChunk(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # A single item of content - content: Annotated[ - Union[ - TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock - ], - Field(description="A single item of content", discriminator="type"), - ] - # A unique identifier for the message this chunk belongs to. - # - # All chunks belonging to the same message share the same `messageId`. - # A change in `messageId` indicates a new message has started. - message_id: Annotated[ - Optional[str], - Field( - alias="messageId", - description="A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.", - ), - ] = None - - -class ElicitationFormSessionMode(ElicitationSessionScope): - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] - - -class ElicitationFormRequestMode(ElicitationRequestScope): - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] -class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Form-based elicitation mode where the client renders a form from the provided schema. - root: Annotated[ - Union[ElicitationFormSessionMode, ElicitationFormRequestMode], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." - ), +class ListProvidersResponse(BaseModel): + # Configurable providers with current routing info suitable for UI display. + providers: Annotated[ + List[ProviderInfo], + Field(description="Configurable providers with current routing info suitable for UI display."), ] - - -class ForkSessionRequest(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4552,33 +4362,946 @@ class ForkSessionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Additional workspace roots to activate for this session. Each path must be absolute. + + +class SessionConfigSelect(BaseModel): + # The currently selected value. + current_value: Annotated[str, Field(alias="currentValue", description="The currently selected value.")] + # The set of selectable options. + options: Annotated[ + Union[List[SessionConfigSelectOption], List[SessionConfigSelectGroup]], + Field(description="The set of selectable options."), + ] + + +class NesTextEdit(BaseModel): + # The range to replace. + range: Annotated[Range, Field(description="The range to replace.")] + # The replacement text. + new_text: Annotated[str, Field(alias="newText", description="The replacement text.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the forked - # session. + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class NesEditSuggestion(BaseModel): + # Unique identifier for accept/reject tracking. + id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] + # The URI of the file to edit. + uri: Annotated[str, Field(description="The URI of the file to edit.")] + # The text edits to apply. + edits: Annotated[List[NesTextEdit], Field(description="The text edits to apply.")] + # Optional suggested cursor position after applying edits. + cursor_position: Annotated[ + Optional[Position], + Field( + alias="cursorPosition", + description="Optional suggested cursor position after applying edits.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class AgentPlanUpdate(Plan): + session_update: Annotated[Literal["plan"], Field(alias="sessionUpdate")] + + +class ContentChunk(BaseModel): + # A single item of content + content: Annotated[ + Union[ + TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock + ], + Field(description="A single item of content", discriminator="type"), + ] + # A unique identifier for the message this chunk belongs to. + # + # All chunks belonging to the same message share the same `messageId`. + # A change in `messageId` indicates a new message has started. + message_id: Annotated[ + Optional[str], + Field( + alias="messageId", + description="A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class PlanUpdateItems(PlanItems): + type: Literal["items"] + + +class PlanUpdate(BaseModel): + # The updated plan content. + plan: Annotated[ + Union[PlanUpdateItems, PlanUpdateFile, PlanUpdateMarkdown], + Field(description="The updated plan content.", discriminator="type"), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class AvailableCommand(BaseModel): + # Command name (e.g., `create_plan`, `research_codebase`). + name: Annotated[ + str, + Field(description="Command name (e.g., `create_plan`, `research_codebase`)."), + ] + # Human-readable description of what the command does. + description: Annotated[str, Field(description="Human-readable description of what the command does.")] + # Input for the command if required + input: Annotated[ + Optional[AvailableCommandInput], + Field(description="Input for the command if required"), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class _AvailableCommandsUpdate(BaseModel): + # Commands the agent can execute + available_commands: Annotated[ + List[AvailableCommand], + Field(alias="availableCommands", description="Commands the agent can execute"), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ClientSessionCapabilities(BaseModel): + # Config option capabilities supported by the client. + # + # Omitted or `null` means the client does not advertise support for any + # config option extensions. + config_options: Annotated[ + Optional[SessionConfigOptionsCapabilities], + Field( + alias="configOptions", + description="Config option capabilities supported by the client.\n\nOmitted or `null` means the client does not advertise support for any\nconfig option extensions.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class NewSessionRequest(BaseModel): + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] + # Additional workspace roots for this session. Each path must be absolute. + # + # These expand the session's filesystem scope without changing `cwd`, which + # remains the base for relative paths. When omitted or empty, no + # additional roots are activated for the new session. additional_directories: Annotated[ Optional[List[str]], Field( alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", + description="Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", ), ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. + # List of MCP (Model Context Protocol) servers the agent should connect to. mcp_servers: Annotated[ - Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], + List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], Field( alias="mcpServers", - description="List of MCP servers to connect to for this session.", + description="List of MCP (Model Context Protocol) servers the agent should connect to.", + ), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class PromptRequest(BaseModel): + # The ID of the session to send this user message to + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="The ID of the session to send this user message to", ), + ] + # The blocks of content that compose the user's message. + # + # As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], + # while other variants are optionally enabled via [`PromptCapabilities`]. + # + # The Client MUST adapt its interface according to [`PromptCapabilities`]. + # + # The client MAY include referenced pieces of context as either + # [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`]. + # + # When available, [`ContentBlock::Resource`] is preferred + # as it avoids extra round-trips and allows the message to include + # pieces of context from sources the agent may not have access to. + prompt: Annotated[ + List[ + Union[ + TextContentBlock, + ImageContentBlock, + AudioContentBlock, + ResourceContentBlock, + EmbeddedResourceContentBlock, + ] + ], + Field( + description="The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to." + ), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class NesSuggestContext(BaseModel): + # Recently accessed files. + recent_files: Annotated[ + Optional[List[NesRecentFile]], + Field(alias="recentFiles", description="Recently accessed files."), + ] = None + # Related code snippets. + related_snippets: Annotated[ + Optional[List[NesRelatedSnippet]], + Field(alias="relatedSnippets", description="Related code snippets."), + ] = None + # Recent edit history. + edit_history: Annotated[ + Optional[List[NesEditHistoryEntry]], + Field(alias="editHistory", description="Recent edit history."), + ] = None + # Recent user actions (typing, navigation, etc.). + user_actions: Annotated[ + Optional[List[NesUserAction]], + Field( + alias="userActions", + description="Recent user actions (typing, navigation, etc.).", + ), + ] = None + # Currently open files in the editor. + open_files: Annotated[ + Optional[List[NesOpenFile]], + Field(alias="openFiles", description="Currently open files in the editor."), + ] = None + # Current diagnostics (errors, warnings). + diagnostics: Annotated[ + Optional[List[NesDiagnostic]], + Field(description="Current diagnostics (errors, warnings)."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class RequestPermissionResponse(BaseModel): + # The user's decision on the permission request. + outcome: Annotated[ + Union[DeniedOutcome, AllowedOutcome], + Field( + description="The user's decision on the permission request.", + discriminator="outcome", + ), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class DidChangeDocumentNotification(BaseModel): + # The session ID for this notification. + session_id: Annotated[ + str, + Field(alias="sessionId", description="The session ID for this notification."), + ] + # The URI of the changed document. + uri: Annotated[str, Field(description="The URI of the changed document.")] + # The new version number of the document. + version: Annotated[int, Field(description="The new version number of the document.")] + # The content changes. + content_changes: Annotated[ + List[TextDocumentContentChangeEvent], + Field(alias="contentChanges", description="The content changes."), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ContentToolCallContent(Content): + type: Literal["content"] + + +class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): + type: Literal["array"] + + +class NesEventCapabilities(BaseModel): + # Document event capabilities. + document: Annotated[ + Optional[NesDocumentEventCapabilities], + Field(description="Document event capabilities."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class SessionConfigOptionSelect(SessionConfigSelect): + # Unique identifier for the configuration option. + id: Annotated[str, Field(description="Unique identifier for the configuration option.")] + # Human-readable label for the option. + name: Annotated[str, Field(description="Human-readable label for the option.")] + # Optional description for the Client to display to the user. + description: Annotated[ + Optional[str], + Field(description="Optional description for the Client to display to the user."), + ] = None + # Optional semantic category for this option (UX only). + category: Annotated[ + Optional[str], + Field(description="Optional semantic category for this option (UX only)."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + type: Literal["select"] + + +class LoadSessionResponse(BaseModel): + # Initial mode state if supported by the Agent + # + # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + modes: Annotated[ + Optional[SessionModeState], + Field( + description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + ), + ] = None + # Initial session configuration options if supported by the Agent. + config_options: Annotated[ + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + Field( + alias="configOptions", + description="Initial session configuration options if supported by the Agent.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ForkSessionResponse(BaseModel): + # Unique identifier for the newly created forked session. + session_id: Annotated[ + str, + Field( + alias="sessionId", + description="Unique identifier for the newly created forked session.", + ), + ] + # Initial mode state if supported by the Agent + # + # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + modes: Annotated[ + Optional[SessionModeState], + Field( + description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + ), + ] = None + # Initial session configuration options if supported by the Agent. + config_options: Annotated[ + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + Field( + alias="configOptions", + description="Initial session configuration options if supported by the Agent.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ResumeSessionResponse(BaseModel): + # Initial mode state if supported by the Agent + # + # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + modes: Annotated[ + Optional[SessionModeState], + Field( + description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + ), + ] = None + # Initial session configuration options if supported by the Agent. + config_options: Annotated[ + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + Field( + alias="configOptions", + description="Initial session configuration options if supported by the Agent.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class SetSessionConfigOptionResponse(BaseModel): + # The full set of configuration options and their current values. + config_options: Annotated[ + List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], + Field( + alias="configOptions", + description="The full set of configuration options and their current values.", + ), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class NesEditSuggestionVariant(NesEditSuggestion): + kind: Literal["edit"] + + +class UserMessageChunk(ContentChunk): + session_update: Annotated[Literal["user_message_chunk"], Field(alias="sessionUpdate")] + + +class AgentMessageChunk(ContentChunk): + session_update: Annotated[Literal["agent_message_chunk"], Field(alias="sessionUpdate")] + + +class AgentThoughtChunk(ContentChunk): + session_update: Annotated[Literal["agent_thought_chunk"], Field(alias="sessionUpdate")] + + +class AgentPlanContentUpdate(PlanUpdate): + session_update: Annotated[Literal["plan_update"], Field(alias="sessionUpdate")] + + +class AvailableCommandsUpdate(_AvailableCommandsUpdate): + session_update: Annotated[Literal["available_commands_update"], Field(alias="sessionUpdate")] + + +class ToolCall(BaseModel): + # Unique identifier for this tool call within the session. + tool_call_id: Annotated[ + str, + Field( + alias="toolCallId", + description="Unique identifier for this tool call within the session.", + ), + ] + # Human-readable title describing what the tool is doing. + title: Annotated[ + str, + Field(description="Human-readable title describing what the tool is doing."), + ] + # The category of tool being invoked. + # Helps clients choose appropriate icons and UI treatment. + kind: Annotated[ + Optional[ToolKind], + Field( + description="The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment." + ), + ] = None + # Current execution status of the tool call. + status: Annotated[Optional[ToolCallStatus], Field(description="Current execution status of the tool call.")] = None + # Content produced by the tool call. + content: Annotated[ + Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], + Field(description="Content produced by the tool call."), + ] = None + # File locations affected by this tool call. + # Enables "follow-along" features in clients. + locations: Annotated[ + Optional[List[ToolCallLocation]], + Field(description='File locations affected by this tool call.\nEnables "follow-along" features in clients.'), + ] = None + # Raw input parameters sent to the tool. + raw_input: Annotated[ + Optional[Any], + Field(alias="rawInput", description="Raw input parameters sent to the tool."), + ] = None + # Raw output returned by the tool. + raw_output: Annotated[ + Optional[Any], + Field(alias="rawOutput", description="Raw output returned by the tool."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class _ConfigOptionUpdate(BaseModel): + # The full set of configuration options and their current values. + config_options: Annotated[ + List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], + Field( + alias="configOptions", + description="The full set of configuration options and their current values.", + ), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ClientCapabilities(BaseModel): + # File system capabilities supported by the client. + # Determines which file operations the agent can request. + fs: Annotated[ + Optional[FileSystemCapabilities], + Field( + description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." + ), + ] = FileSystemCapabilities() + # Whether the Client support all `terminal/*` methods. + terminal: Annotated[ + Optional[bool], + Field(description="Whether the Client support all `terminal/*` methods."), + ] = False + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Session-related capabilities supported by the client. + session: Annotated[ + Optional[ClientSessionCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Whether the client supports `plan_update` and `plan_removed` session updates. + # + # Optional. Omitted means the client does not advertise support. + # Supplying `{}` means the client can receive both update types. + plan: Annotated[ + Optional[PlanCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Authentication capabilities supported by the client. + # Determines which authentication method types the agent may include + # in its `InitializeResponse`. + auth: Annotated[ + Optional[AuthCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." + ), + ] = {"terminal": False} + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Elicitation capabilities supported by the client. + # Determines which elicitation modes the agent may use. + elicitation: Annotated[ + Optional[ElicitationCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # NES (Next Edit Suggestions) capabilities supported by the client. + nes: Annotated[ + Optional[ClientNesCapabilities], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + ), + ] = None + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # The position encodings supported by the client, in order of preference. + position_encodings: Annotated[ + Optional[List[str]], + Field( + alias="positionEncodings", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", + ), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class SuggestNesRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # The URI of the document to suggest for. + uri: Annotated[str, Field(description="The URI of the document to suggest for.")] + # The version number of the document. + version: Annotated[int, Field(description="The version number of the document.")] + # The current cursor position. + position: Annotated[Position, Field(description="The current cursor position.")] + # The current text selection range, if any. + selection: Annotated[Optional[Range], Field(description="The current text selection range, if any.")] = None + # What triggered this suggestion request. + trigger_kind: Annotated[ + str, + Field(alias="triggerKind", description="What triggered this suggestion request."), + ] + # Context for the suggestion, included based on agent capabilities. + context: Annotated[ + Optional[NesSuggestContext], + Field(description="Context for the suggestion, included based on agent capabilities."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ClientResponseMessage(BaseModel): + # The id of the request this response answers. + id: Annotated[ + Optional[Union[int, str]], + Field(description="The id of the request this response answers."), + ] = None + # Method-specific response data. + result: Annotated[ + Union[ + WriteTextFileResponse, + ReadTextFileResponse, + RequestPermissionResponse, + CreateTerminalResponse, + TerminalOutputResponse, + ReleaseTerminalResponse, + WaitForTerminalExitResponse, + KillTerminalResponse, + ConnectMcpResponse, + DisconnectMcpResponse, + Union[ + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, + ], + Any, + ], + Field(description="Method-specific response data."), + ] + + +class ClientResponse(RootModel[Union[ClientResponseMessage, ClientErrorMessage]]): + # A JSON-RPC response object. + root: Annotated[ + Union[ClientResponseMessage, ClientErrorMessage], + Field(description="A JSON-RPC response object."), + ] + + +class ClientNotification(BaseModel): + # The notification method name. + method: Annotated[str, Field(description="The notification method name.")] + # Method-specific notification parameters. + params: Annotated[ + Optional[ + Union[ + CancelNotification, + DidOpenDocumentNotification, + DidChangeDocumentNotification, + DidCloseDocumentNotification, + DidSaveDocumentNotification, + DidFocusDocumentNotification, + AcceptNesNotification, + RejectNesNotification, + MessageMcpNotification, + Any, + ] + ], + Field(description="Method-specific notification parameters."), + ] = None + + +class ToolCallUpdate(BaseModel): + # The ID of the tool call being updated. + tool_call_id: Annotated[ + str, + Field(alias="toolCallId", description="The ID of the tool call being updated."), + ] + # Update the tool kind. + kind: Annotated[Optional[ToolKind], Field(description="Update the tool kind.")] = None + # Update the execution status. + status: Annotated[Optional[ToolCallStatus], Field(description="Update the execution status.")] = None + # Update the human-readable title. + title: Annotated[Optional[str], Field(description="Update the human-readable title.")] = None + # Replace the content collection. + content: Annotated[ + Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], + Field(description="Replace the content collection."), + ] = None + # Replace the locations collection. + locations: Annotated[ + Optional[List[ToolCallLocation]], + Field(description="Replace the locations collection."), + ] = None + # Update the raw input. + raw_input: Annotated[Optional[Any], Field(alias="rawInput", description="Update the raw input.")] = None + # Update the raw output. + raw_output: Annotated[Optional[Any], Field(alias="rawOutput", description="Update the raw output.")] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + +class ElicitationSchema(BaseModel): + # Type discriminator. Always `"object"`. + type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" + # Optional title for the schema. + title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None + # Property definitions (must be primitive types). + properties: Annotated[ + Optional[ + Dict[ + str, + Union[ + ElicitationStringPropertySchema, + ElicitationNumberPropertySchema, + ElicitationIntegerPropertySchema, + ElicitationBooleanPropertySchema, + ElicitationMultiSelectPropertySchema, + ], + ] + ], + Field(description="Property definitions (must be primitive types)."), + ] = {} + # List of required property names. + required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None + # Optional description of what this schema represents. + description: Annotated[ + Optional[str], + Field(description="Optional description of what this schema represents."), ] = None - # The ID of the session to fork. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] - - -class InitializeResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4591,88 +5314,55 @@ class InitializeResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Capabilities supported by the agent. - agent_capabilities: Annotated[ - Optional[AgentCapabilities], - Field( - alias="agentCapabilities", - description="Capabilities supported by the agent.", - ), - ] = AgentCapabilities() - # Information about the Agent name and version sent to the Client. - # - # Note: in future versions of the protocol, this will be required. - agent_info: Annotated[ - Optional[Implementation], - Field( - alias="agentInfo", - description="Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", - ), - ] = None - # Authentication methods supported by the agent. - auth_methods: Annotated[ - Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], + + +class ElicitationFormSessionMode(ElicitationSessionScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, Field( - alias="authMethods", - description="Authentication methods supported by the agent.", + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", ), - ] = [] - # The protocol version the client specified if supported by the agent, - # or the latest protocol version supported by the agent. - # - # The client should disconnect, if it doesn't support this version. - protocol_version: Annotated[ - int, + ] + + +class ElicitationFormRequestMode(ElicitationRequestScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, Field( - alias="protocolVersion", - description="The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", - ge=0, - le=65535, + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", ), ] -class LoadSessionRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. +class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): + # **UNSTABLE** # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # Additional workspace roots to activate for this session. Each path must be absolute. + # This capability is not part of the spec yet, and may be removed or changed at any point. # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the loaded - # session. It may differ from any previously used or reported list as long as - # the request `cwd` matches the session's `cwd`. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - ), - ] = None - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] - # List of MCP servers to connect to for this session. - mcp_servers: Annotated[ - List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], + # Form-based elicitation mode where the client renders a form from the provided schema. + root: Annotated[ + Union[ElicitationFormSessionMode, ElicitationFormRequestMode], Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." ), ] - # The ID of the session to load. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] -class PromptRequest(BaseModel): +class NesCapabilities(BaseModel): + # Events the agent wants to receive. + events: Annotated[ + Optional[NesEventCapabilities], + Field(description="Events the agent wants to receive."), + ] = None + # Context the agent wants attached to each suggestion request. + context: Annotated[ + Optional[NesContextCapabilities], + Field(description="Context the agent wants attached to each suggestion request."), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4685,110 +5375,36 @@ class PromptRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The blocks of content that compose the user's message. - # - # As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], - # while other variants are optionally enabled via [`PromptCapabilities`]. - # - # The Client MUST adapt its interface according to [`PromptCapabilities`]. - # - # The client MAY include referenced pieces of context as either - # [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`]. + + +class NewSessionResponse(BaseModel): + # Unique identifier for the created session. # - # When available, [`ContentBlock::Resource`] is preferred - # as it avoids extra round-trips and allows the message to include - # pieces of context from sources the agent may not have access to. - prompt: Annotated[ - List[ - Union[ - TextContentBlock, - ImageContentBlock, - AudioContentBlock, - ResourceContentBlock, - EmbeddedResourceContentBlock, - ] - ], - Field( - description="The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to." - ), - ] - # The ID of the session to send this user message to + # Used in all subsequent requests for this conversation. session_id: Annotated[ str, Field( alias="sessionId", - description="The ID of the session to send this user message to", + description="Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation.", ), ] - - -class SessionConfigSelect(BaseModel): - # The currently selected value. - current_value: Annotated[str, Field(alias="currentValue", description="The currently selected value.")] - # The set of selectable options. - options: Annotated[ - Union[List[SessionConfigSelectOption], List[SessionConfigSelectGroup]], - Field(description="The set of selectable options."), - ] - - -class UserMessageChunk(ContentChunk): - session_update: Annotated[Literal["user_message_chunk"], Field(alias="sessionUpdate")] - - -class AgentMessageChunk(ContentChunk): - session_update: Annotated[Literal["agent_message_chunk"], Field(alias="sessionUpdate")] - - -class AgentThoughtChunk(ContentChunk): - session_update: Annotated[Literal["agent_thought_chunk"], Field(alias="sessionUpdate")] - - -class ClientRequest(BaseModel): - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. - # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. + # Initial mode state if supported by the Agent # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. - id: Annotated[ - Optional[Union[int, str]], + # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + modes: Annotated[ + Optional[SessionModeState], Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." + description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" ), ] = None - method: str - params: Optional[ - Union[ - InitializeRequest, - AuthenticateRequest, - ListProvidersRequest, - SetProviderRequest, - DisableProviderRequest, - LogoutRequest, - NewSessionRequest, - LoadSessionRequest, - ListSessionsRequest, - DeleteSessionRequest, - ForkSessionRequest, - ResumeSessionRequest, - CloseSessionRequest, - SetSessionModeRequest, - PromptRequest, - StartNesRequest, - SuggestNesRequest, - CloseNesRequest, - MessageMcpRequest, - Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], - Any, - ] + # Initial session configuration options if supported by the Agent. + config_options: Annotated[ + Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + Field( + alias="configOptions", + description="Initial session configuration options if supported by the Agent.", + ), ] = None - - -class Content(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4801,16 +5417,21 @@ class Content(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The actual content block. - content: Annotated[ - Union[ - TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock - ], - Field(description="The actual content block.", discriminator="type"), - ] -class CreateFormElicitationRequest(BaseModel): +class SuggestNesResponse(BaseModel): + # The list of suggestions. + suggestions: Annotated[ + List[ + Union[ + NesEditSuggestionVariant, + NesJumpSuggestionVariant, + NesRenameSuggestionVariant, + NesSearchAndReplaceSuggestionVariant, + ] + ], + Field(description="The list of suggestions."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4823,45 +5444,49 @@ class CreateFormElicitationRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - mode: Literal["form"] -class SessionConfigOptionSelect(SessionConfigSelect): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. +class ToolCallStart(ToolCall): + session_update: Annotated[Literal["tool_call"], Field(alias="sessionUpdate")] + + +class ToolCallProgress(ToolCallUpdate): + session_update: Annotated[Literal["tool_call_update"], Field(alias="sessionUpdate")] + + +class ConfigOptionUpdate(_ConfigOptionUpdate): + session_update: Annotated[Literal["config_option_update"], Field(alias="sessionUpdate")] + + +class InitializeRequest(BaseModel): + # The latest protocol version supported by the client. + protocol_version: Annotated[ + int, + Field( + alias="protocolVersion", + description="The latest protocol version supported by the client.", + ge=0, + le=65535, + ), + ] + # Capabilities supported by the client. + client_capabilities: Annotated[ + Optional[ClientCapabilities], + Field( + alias="clientCapabilities", + description="Capabilities supported by the client.", + ), + ] = ClientCapabilities() + # Information about the Client name and version sent to the Agent. # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], + # Note: in future versions of the protocol, this will be required. + client_info: Annotated[ + Optional[Implementation], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + alias="clientInfo", + description="Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", ), ] = None - # Optional semantic category for this option (UX only). - category: Annotated[ - Optional[str], - Field(description="Optional semantic category for this option (UX only)."), - ] = None - # Optional description for the Client to display to the user. - description: Annotated[ - Optional[str], - Field(description="Optional description for the Client to display to the user."), - ] = None - # Unique identifier for the configuration option. - id: Annotated[str, Field(description="Unique identifier for the configuration option.")] - # Human-readable label for the option. - name: Annotated[str, Field(description="Human-readable label for the option.")] - type: Literal["select"] - - -class SetSessionConfigOptionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4874,21 +5499,38 @@ class SetSessionConfigOptionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The full set of configuration options and their current values. - config_options: Annotated[ - List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], - Field( - alias="configOptions", - description="The full set of configuration options and their current values.", - ), - ] - -class ContentToolCallContent(Content): - type: Literal["content"] + @field_validator("protocol_version", mode="before") + @classmethod + def _coerce_protocol_version(cls, value: Any) -> int: + # Some clients (e.g. Zed) send a date string like "2024-11-05" instead + # of an integer. The Rust SDK treats legacy strings as version 0; this + # SDK maps unparsable values to 1 so the connection is not rejected. + # See: https://github.com/agentclientprotocol/rust-sdk/blob/main/crates/agent-client-protocol-schema/src/version.rs + if isinstance(value, int): + return value + try: + return int(value) + except (TypeError, ValueError): + return 1 -class ToolCallUpdate(BaseModel): +class RequestPermissionRequest(BaseModel): + # The session ID for this request. + session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] + # Details about the tool call requiring permission. + tool_call: Annotated[ + ToolCallUpdate, + Field( + alias="toolCall", + description="Details about the tool call requiring permission.", + ), + ] + # Available permission options for the user to choose from. + options: Annotated[ + List[PermissionOption], + Field(description="Available permission options for the user to choose from."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4901,34 +5543,14 @@ class ToolCallUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Replace the content collection. - content: Annotated[ - Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], - Field(description="Replace the content collection."), - ] = None - # Update the tool kind. - kind: Annotated[Optional[ToolKind], Field(description="Update the tool kind.")] = None - # Replace the locations collection. - locations: Annotated[ - Optional[List[ToolCallLocation]], - Field(description="Replace the locations collection."), - ] = None - # Update the raw input. - raw_input: Annotated[Optional[Any], Field(alias="rawInput", description="Update the raw input.")] = None - # Update the raw output. - raw_output: Annotated[Optional[Any], Field(alias="rawOutput", description="Update the raw output.")] = None - # Update the execution status. - status: Annotated[Optional[ToolCallStatus], Field(description="Update the execution status.")] = None - # Update the human-readable title. - title: Annotated[Optional[str], Field(description="Update the human-readable title.")] = None - # The ID of the tool call being updated. - tool_call_id: Annotated[ - str, - Field(alias="toolCallId", description="The ID of the tool call being updated."), - ] -class _ConfigOptionUpdate(BaseModel): +class CreateFormSessionElicitationRequest(ElicitationSessionScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4941,17 +5563,23 @@ class _ConfigOptionUpdate(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # The full set of configuration options and their current values. - config_options: Annotated[ - List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], + mode: Literal["form"] + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, Field( - alias="configOptions", - description="The full set of configuration options and their current values.", + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", ), ] -class ForkSessionResponse(BaseModel): +class CreateFormRequestElicitationRequest(ElicitationRequestScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -4964,108 +5592,116 @@ class ForkSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Initial session configuration options if supported by the Agent. - config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None - # Unique identifier for the newly created forked session. - session_id: Annotated[ - str, + mode: Literal["form"] + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, Field( - alias="sessionId", - description="Unique identifier for the newly created forked session.", + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", ), ] -class LoadSessionResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], +ElicitationMode = Union[ + ElicitationFormSessionMode, + ElicitationFormRequestMode, + ElicitationUrlSessionMode, + ElicitationUrlRequestMode, +] +CreateFormElicitationRequest = Union[ + CreateFormSessionElicitationRequest, + CreateFormRequestElicitationRequest, +] +CreateUrlElicitationRequest = Union[ + CreateUrlSessionElicitationRequest, + CreateUrlRequestElicitationRequest, +] +CreateElicitationRequest = Union[ + CreateFormElicitationRequest, + CreateUrlElicitationRequest, +] +CreateElicitationResponse = Union[ + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, +] + + +class AgentCapabilities(BaseModel): + # Whether the agent supports `session/load`. + load_session: Annotated[ + Optional[bool], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + alias="loadSession", + description="Whether the agent supports `session/load`.", ), - ] = None - # Initial session configuration options if supported by the Agent. - config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + ] = False + # Prompt capabilities supported by the agent. + prompt_capabilities: Annotated[ + Optional[PromptCapabilities], Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", + alias="promptCapabilities", + description="Prompt capabilities supported by the agent.", ), - ] = None - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], + ] = PromptCapabilities() + # MCP capabilities supported by the agent. + mcp_capabilities: Annotated[ + Optional[McpCapabilities], Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + alias="mcpCapabilities", + description="MCP capabilities supported by the agent.", ), - ] = None - - -class NewSessionResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], + ] = McpCapabilities() + # Session lifecycle and prompt capabilities advertised by the agent. + session_capabilities: Annotated[ + Optional[SessionCapabilities], Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + alias="sessionCapabilities", + description="Session lifecycle and prompt capabilities advertised by the agent.", ), - ] = None - # Initial session configuration options if supported by the Agent. - config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], + ] = SessionCapabilities() + # Authentication-related capabilities supported by the agent. + auth: Annotated[ + Optional[AgentAuthCapabilities], + Field(description="Authentication-related capabilities supported by the agent."), + ] = {} + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Provider configuration capabilities supported by the agent. + # + # By supplying `{}` it means that the agent supports provider configuration methods. + providers: Annotated[ + Optional[ProvidersCapabilities], Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." ), ] = None - # Initial mode state if supported by the Agent + # **UNSTABLE** # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # NES (Next Edit Suggestions) capabilities supported by the agent. + nes: Annotated[ + Optional[NesCapabilities], Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." ), ] = None - # Unique identifier for the created session. + # **UNSTABLE** # - # Used in all subsequent requests for this conversation. - session_id: Annotated[ - str, + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # The position encoding selected by the agent from the client's supported encodings. + position_encoding: Annotated[ + Optional[str], Field( - alias="sessionId", - description="Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation.", + alias="positionEncoding", + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", ), - ] - - -class RequestPermissionRequest(BaseModel): + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -5078,24 +5714,36 @@ class RequestPermissionRequest(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Available permission options for the user to choose from. - options: Annotated[ - List[PermissionOption], - Field(description="Available permission options for the user to choose from."), - ] - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # Details about the tool call requiring permission. - tool_call: Annotated[ - ToolCallUpdate, + + +class SessionNotification(BaseModel): + # The ID of the session this update pertains to. + session_id: Annotated[ + str, Field( - alias="toolCall", - description="Details about the tool call requiring permission.", + alias="sessionId", + description="The ID of the session this update pertains to.", ), ] - - -class ResumeSessionResponse(BaseModel): + # The actual update content. + update: Annotated[ + Union[ + UserMessageChunk, + AgentMessageChunk, + AgentThoughtChunk, + ToolCallStart, + ToolCallProgress, + AgentPlanUpdate, + AgentPlanContentUpdate, + AgentPlanRemovedUpdate, + AvailableCommandsUpdate, + CurrentModeUpdate, + ConfigOptionUpdate, + SessionInfoUpdate, + UsageUpdate, + ], + Field(description="The actual update content.", discriminator="session_update"), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -5108,34 +5756,123 @@ class ResumeSessionResponse(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Initial session configuration options if supported by the Agent. - config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None -class ToolCallProgress(ToolCallUpdate): - session_update: Annotated[Literal["tool_call_update"], Field(alias="sessionUpdate")] +class ClientRequest(BaseModel): + # The request id used to correlate the matching response. + id: Annotated[ + Optional[Union[int, str]], + Field(description="The request id used to correlate the matching response."), + ] + # The method name to invoke. + method: Annotated[str, Field(description="The method name to invoke.")] + # Method-specific request parameters. + params: Annotated[ + Optional[ + Union[ + InitializeRequest, + AuthenticateRequest, + ListProvidersRequest, + SetProviderRequest, + DisableProviderRequest, + LogoutRequest, + NewSessionRequest, + LoadSessionRequest, + ListSessionsRequest, + DeleteSessionRequest, + ForkSessionRequest, + ResumeSessionRequest, + CloseSessionRequest, + SetSessionModeRequest, + PromptRequest, + StartNesRequest, + SuggestNesRequest, + CloseNesRequest, + MessageMcpRequest, + Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], + Any, + ] + ], + Field(description="Method-specific request parameters."), + ] = None -class ConfigOptionUpdate(_ConfigOptionUpdate): - session_update: Annotated[Literal["config_option_update"], Field(alias="sessionUpdate")] +class AgentRequest(BaseModel): + # The request id used to correlate the matching response. + id: Annotated[ + Optional[Union[int, str]], + Field(description="The request id used to correlate the matching response."), + ] + # The method name to invoke. + method: Annotated[str, Field(description="The method name to invoke.")] + # Method-specific request parameters. + params: Annotated[ + Optional[ + Union[ + WriteTextFileRequest, + ReadTextFileRequest, + RequestPermissionRequest, + CreateTerminalRequest, + TerminalOutputRequest, + ReleaseTerminalRequest, + WaitForTerminalExitRequest, + KillTerminalRequest, + ConnectMcpRequest, + MessageMcpRequest, + DisconnectMcpRequest, + Union[ + CreateFormSessionElicitationRequest, + CreateFormRequestElicitationRequest, + CreateUrlSessionElicitationRequest, + CreateUrlRequestElicitationRequest, + ], + Any, + ] + ], + Field(description="Method-specific request parameters."), + ] = None -class ToolCall(BaseModel): +class InitializeResponse(BaseModel): + # The protocol version the client specified if supported by the agent, + # or the latest protocol version supported by the agent. + # + # The client should disconnect, if it doesn't support this version. + protocol_version: Annotated[ + int, + Field( + alias="protocolVersion", + description="The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", + ge=0, + le=65535, + ), + ] + # Capabilities supported by the agent. + agent_capabilities: Annotated[ + Optional[AgentCapabilities], + Field( + alias="agentCapabilities", + description="Capabilities supported by the agent.", + ), + ] = AgentCapabilities() + # Authentication methods supported by the agent. + auth_methods: Annotated[ + Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], + Field( + alias="authMethods", + description="Authentication methods supported by the agent.", + ), + ] = [] + # Information about the Agent name and version sent to the Client. + # + # Note: in future versions of the protocol, this will be required. + agent_info: Annotated[ + Optional[Implementation], + Field( + alias="agentInfo", + description="Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", + ), + ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -5148,110 +5885,32 @@ class ToolCall(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - # Content produced by the tool call. - content: Annotated[ - Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], - Field(description="Content produced by the tool call."), - ] = None - # The category of tool being invoked. - # Helps clients choose appropriate icons and UI treatment. - kind: Annotated[ - Optional[ToolKind], - Field( - description="The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment." - ), - ] = None - # File locations affected by this tool call. - # Enables "follow-along" features in clients. - locations: Annotated[ - Optional[List[ToolCallLocation]], - Field(description='File locations affected by this tool call.\nEnables "follow-along" features in clients.'), - ] = None - # Raw input parameters sent to the tool. - raw_input: Annotated[ - Optional[Any], - Field(alias="rawInput", description="Raw input parameters sent to the tool."), - ] = None - # Raw output returned by the tool. - raw_output: Annotated[ - Optional[Any], - Field(alias="rawOutput", description="Raw output returned by the tool."), - ] = None - # Current execution status of the tool call. - status: Annotated[Optional[ToolCallStatus], Field(description="Current execution status of the tool call.")] = None - # Human-readable title describing what the tool is doing. - title: Annotated[ - str, - Field(description="Human-readable title describing what the tool is doing."), - ] - # Unique identifier for this tool call within the session. - tool_call_id: Annotated[ - str, - Field( - alias="toolCallId", - description="Unique identifier for this tool call within the session.", - ), - ] -class AgentRequest(BaseModel): - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. - # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. - # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. - id: Annotated[ - Optional[Union[int, str]], - Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." - ), - ] = None - method: str - params: Optional[ - Union[ - WriteTextFileRequest, - ReadTextFileRequest, - RequestPermissionRequest, - CreateTerminalRequest, - TerminalOutputRequest, - ReleaseTerminalRequest, - WaitForTerminalExitRequest, - KillTerminalRequest, - ConnectMcpRequest, - MessageMcpRequest, - DisconnectMcpRequest, - Union[CreateFormElicitationRequest, CreateUrlElicitationRequest], - Any, - ] +class AgentNotification(BaseModel): + # The notification method name. + method: Annotated[str, Field(description="The notification method name.")] + # Method-specific notification parameters. + params: Annotated[ + Optional[ + Union[ + SessionNotification, + CompleteElicitationNotification, + MessageMcpNotification, + Any, + ] + ], + Field(description="Method-specific notification parameters."), ] = None class AgentResponseMessage(BaseModel): - # JSON RPC Request Id - # - # An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \[1\] and Numbers SHOULD NOT contain fractional parts \[2\] - # - # The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. - # - # \[1\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling. - # - # \[2\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions. + # The id of the request this response answers. id: Annotated[ Optional[Union[int, str]], - Field( - description="JSON RPC Request Id\n\nAn identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null \\[1\\] and Numbers SHOULD NOT contain fractional parts \\[2\\]\n\nThe Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.\n\n\\[1\\] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.\n\n\\[2\\] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions." - ), + Field(description="The id of the request this response answers."), ] = None - # All possible responses that an agent can send to a client. - # - # This enum is used internally for routing RPC responses. You typically won't need - # to use this directly - the responses are handled automatically by the connection. - # - # These are responses to the corresponding `ClientRequest` variants. + # Method-specific response data. result: Annotated[ Union[ InitializeResponse, @@ -5275,69 +5934,13 @@ class AgentResponseMessage(BaseModel): CloseNesResponse, Any, ], - Field( - description="All possible responses that an agent can send to a client.\n\nThis enum is used internally for routing RPC responses. You typically won't need\nto use this directly - the responses are handled automatically by the connection.\n\nThese are responses to the corresponding `ClientRequest` variants." - ), + Field(description="Method-specific response data."), ] class AgentResponse(RootModel[Union[AgentResponseMessage, AgentErrorMessage]]): - root: Union[AgentResponseMessage, AgentErrorMessage] - - -class ToolCallStart(ToolCall): - session_update: Annotated[Literal["tool_call"], Field(alias="sessionUpdate")] - - -class SessionNotification(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # The ID of the session this update pertains to. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session this update pertains to.", - ), - ] - # The actual update content. - update: Annotated[ - Union[ - UserMessageChunk, - AgentMessageChunk, - AgentThoughtChunk, - ToolCallStart, - ToolCallProgress, - AgentPlanUpdate, - AgentPlanContentUpdate, - AgentPlanRemovedUpdate, - AvailableCommandsUpdate, - CurrentModeUpdate, - ConfigOptionUpdate, - SessionInfoUpdate, - UsageUpdate, - ], - Field(description="The actual update content.", discriminator="session_update"), + # A JSON-RPC response object. + root: Annotated[ + Union[AgentResponseMessage, AgentErrorMessage], + Field(description="A JSON-RPC response object."), ] - - -class AgentNotification(BaseModel): - method: str - params: Optional[ - Union[ - SessionNotification, - CompleteElicitationNotification, - MessageMcpNotification, - Any, - ] - ] = None diff --git a/src/acp/utils.py b/src/acp/utils.py index 3d62496..fc78af8 100644 --- a/src/acp/utils.py +++ b/src/acp/utils.py @@ -53,7 +53,7 @@ def model_to_kwargs(model_obj: BaseModel, models: MultiParamModelSpec) -> dict[s def serialize_params(params: BaseModel) -> dict[str, Any]: """Return a JSON-serializable representation used for RPC calls.""" - return params.model_dump(by_alias=True, exclude_none=True, exclude_defaults=True) + return params.model_dump(mode="json", by_alias=True, exclude_none=True, exclude_defaults=True) def normalize_result(payload: Any) -> dict[str, Any]: diff --git a/tests/conftest.py b/tests/conftest.py index b4990c9..2dc476b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,8 +7,12 @@ import pytest_asyncio from acp import ( + AcceptElicitationResponse, AuthenticateResponse, + CompleteElicitationNotification, + CreateElicitationResponse, CreateTerminalResponse, + ElicitationMode, InitializeResponse, KillTerminalResponse, LoadSessionResponse, @@ -131,6 +135,8 @@ def __init__(self) -> None: self.permission_outcomes: list[RequestPermissionResponse] = [] self.files: dict[str, str] = {} self.notifications: list[SessionNotification] = [] + self.elicitation_requests: list[tuple[str, ElicitationMode, dict[str, Any]]] = [] + self.completed_elicitations: list[CompleteElicitationNotification] = [] self.ext_calls: list[tuple[str, dict]] = [] self.ext_notes: list[tuple[str, dict]] = [] self._agent_conn = None @@ -147,20 +153,20 @@ def queue_permission_selected(self, option_id: str) -> None: ) async def request_permission( - self, options: list[PermissionOption], session_id: str, tool_call: ToolCallUpdate, **kwargs: Any + self, session_id: str, tool_call: ToolCallUpdate, options: list[PermissionOption], **kwargs: Any ) -> RequestPermissionResponse: if self.permission_outcomes: return self.permission_outcomes.pop() return RequestPermissionResponse(outcome=DeniedOutcome(outcome="cancelled")) async def write_text_file( - self, content: str, path: str, session_id: str, **kwargs: Any + self, session_id: str, path: str, content: str, **kwargs: Any ) -> WriteTextFileResponse | None: self.files[str(path)] = content return WriteTextFileResponse() async def read_text_file( - self, path: str, session_id: str, limit: int | None = None, line: int | None = None, **kwargs: Any + self, session_id: str, path: str, line: int | None = None, limit: int | None = None, **kwargs: Any ) -> ReadTextFileResponse: content = self.files.get(str(path), "default content") return ReadTextFileResponse(content=content) @@ -185,11 +191,11 @@ async def session_update( # Optional terminal methods (not implemented in this test client) async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: @@ -215,6 +221,20 @@ async def kill_terminal( ) -> KillTerminalResponse | None: raise NotImplementedError + async def create_elicitation( + self, + message: str, + mode: ElicitationMode, + **kwargs: Any, + ) -> CreateElicitationResponse: + self.elicitation_requests.append((message, mode, kwargs)) + return AcceptElicitationResponse(action="accept", content={}) + + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: + self.completed_elicitations.append( + CompleteElicitationNotification(elicitation_id=elicitation_id, field_meta=kwargs or None) + ) + async def ext_method(self, method: str, params: dict) -> dict: self.ext_calls.append((method, params)) if method == "example.com/ping": @@ -246,12 +266,21 @@ async def initialize( return InitializeResponse(protocol_version=protocol_version, agent_capabilities=None, auth_methods=[]) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: return NewSessionResponse(session_id="test-session-123") async def load_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], session_id: str, **kwargs: Any + self, + cwd: str, + session_id: str, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + additional_directories: list[str] | None = None, + **kwargs: Any, ) -> LoadSessionResponse | None: return LoadSessionResponse() @@ -260,6 +289,7 @@ async def authenticate(self, method_id: str, **kwargs: Any) -> AuthenticateRespo async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -267,7 +297,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: self.prompts.append( @@ -287,7 +316,7 @@ async def list_sessions( ) -> ListSessionsResponse: return ListSessionsResponse(sessions=[]) - async def set_session_mode(self, mode_id: str, session_id: str, **kwargs: Any) -> SetSessionModeResponse | None: + async def set_session_mode(self, session_id: str, mode_id: str, **kwargs: Any) -> SetSessionModeResponse | None: return SetSessionModeResponse() async def set_config_option( diff --git a/tests/real_user/test_permission_flow.py b/tests/real_user/test_permission_flow.py index 95b10ce..5d872dd 100644 --- a/tests/real_user/test_permission_flow.py +++ b/tests/real_user/test_permission_flow.py @@ -29,6 +29,7 @@ def __init__(self, conn: AgentSideConnection) -> None: async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -36,7 +37,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: permission = await self._conn.request_permission( @@ -48,7 +48,7 @@ async def prompt( tool_call=ToolCallUpdate(tool_call_id="call-1", title="Write File"), ) self.permission_responses.append(permission) - return await super().prompt(prompt, session_id, **kwargs) + return await super().prompt(session_id=session_id, prompt=prompt, **kwargs) @pytest.mark.asyncio diff --git a/tests/test_gen_all.py b/tests/test_gen_all.py new file mode 100644 index 0000000..2cc95b5 --- /dev/null +++ b/tests/test_gen_all.py @@ -0,0 +1,119 @@ +from scripts.gen_all import resolve_ref, schema_source_paths +from scripts.gen_schema import _preprocess_schema_for_codegen, _restore_required_nullable_fields + + +def test_resolve_ref_accepts_schema_release_tags() -> None: + assert resolve_ref("schema-v1.16.0") == "refs/tags/schema-v1.16.0" + + +def test_resolve_ref_keeps_legacy_version_tags() -> None: + assert resolve_ref("0.13.6") == "refs/tags/v0.13.6" + assert resolve_ref("v0.13.6") == "refs/tags/v0.13.6" + + +def test_schema_release_tags_prefer_v1_schema_layout() -> None: + assert schema_source_paths("refs/tags/schema-v1.16.0")[0] == ( + "schema/v1/schema.unstable.json", + "schema/v1/meta.unstable.json", + ) + + +def test_legacy_tags_keep_legacy_schema_layout_first() -> None: + assert schema_source_paths("refs/tags/v0.13.6")[0] == ( + "schema/schema.unstable.json", + "schema/meta.unstable.json", + ) + + +def test_parse_args_formats_output_by_default(monkeypatch) -> None: + from scripts import gen_all + + monkeypatch.setattr("sys.argv", ["gen_all.py"]) + assert gen_all.parse_args().format_output is True + + +def test_parse_args_can_skip_format(monkeypatch) -> None: + from scripts import gen_all + + monkeypatch.setattr("sys.argv", ["gen_all.py", "--no-format"]) + assert gen_all.parse_args().format_output is False + + +def test_codegen_preprocess_distributes_common_object_properties() -> None: + schema = { + "$defs": { + "ScopeA": { + "type": "object", + "properties": {"scopeA": {"type": "string"}}, + "required": ["scopeA"], + }, + "ScopeB": { + "type": "object", + "properties": {"scopeB": {"type": "string"}}, + "required": ["scopeB"], + }, + "Mode": { + "type": "object", + "properties": {"payload": {"type": "string"}}, + "required": ["payload"], + "anyOf": [ + {"allOf": [{"$ref": "#/$defs/ScopeA"}]}, + {"allOf": [{"$ref": "#/$defs/ScopeB"}]}, + ], + }, + "Request": { + "type": "object", + "properties": {"message": {"type": "string"}}, + "required": ["message"], + "oneOf": [ + { + "type": "object", + "properties": {"kind": {"type": "string", "const": "mode"}}, + "required": ["kind"], + "allOf": [{"$ref": "#/$defs/Mode"}], + } + ], + }, + }, + "$ref": "#/$defs/Request", + } + + request = _preprocess_schema_for_codegen(schema)["$defs"]["Request"] + + assert len(request["oneOf"]) == 2 + assert request["oneOf"][0]["required"] == ["message", "kind", "payload"] + assert request["oneOf"][0]["properties"].keys() >= {"message", "kind", "payload"} + assert request["oneOf"][0]["allOf"] == [{"$ref": "#/$defs/ScopeA"}] + assert request["oneOf"][1]["allOf"] == [{"$ref": "#/$defs/ScopeB"}] + + +def test_codegen_postprocess_preserves_required_nullable_fields() -> None: + schema = { + "$defs": { + "Example": { + "type": "object", + "properties": { + "requiredId": {"anyOf": [{"type": "null"}, {"type": "string"}]}, + "optionalId": {"anyOf": [{"type": "null"}, {"type": "string"}]}, + }, + "required": ["requiredId"], + } + } + } + content = """\ +class Example(BaseModel): + required_id: Annotated[ + Optional[str], + Field(alias="requiredId"), + ] = None + optional_id: Annotated[ + Optional[str], + Field(alias="optionalId"), + ] = None +""" + + processed = _restore_required_nullable_fields(content, schema) + + assert 'Field(alias="requiredId"),\n ] = None' not in processed + assert 'Field(alias="requiredId"),\n ]' in processed + assert 'Field(alias="optionalId"),\n ] = None' in processed diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 6720076..4bdc0a9 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -5,12 +5,18 @@ from typing import Any, cast import pytest +from pydantic import AnyUrl from acp import ( + AcceptElicitationResponse, Agent, AuthenticateResponse, Client, CreateTerminalResponse, + ElicitationFormSessionMode, + ElicitationSchema, + ElicitationStringPropertySchema, + ElicitationUrlRequestMode, InitializeResponse, LoadSessionResponse, NewSessionResponse, @@ -152,8 +158,8 @@ def on_connect(self, conn: Client) -> None: async def prompt( self, - prompt: list[TextContentBlock], session_id: str, + prompt: list[TextContentBlock], **kwargs: Any, ) -> PromptResponse: assert self._conn is not None @@ -166,11 +172,11 @@ class _TerminalClient(TestClient): async def create_terminal( self, - command: str, session_id: str, + command: str, args: list[str] | None = None, - cwd: str | None = None, env: list[EnvVariable] | None = None, + cwd: str | None = None, output_byte_limit: int | None = None, **kwargs: Any, ) -> CreateTerminalResponse: @@ -188,6 +194,68 @@ async def create_terminal( await agent_conn.close() +@pytest.mark.asyncio +async def test_create_form_elicitation_roundtrip(connect, client): + agent_conn, _ = connect(use_unstable_protocol=True) + requested_schema = ElicitationSchema( + properties={"target": ElicitationStringPropertySchema(type="string")}, + required=["target"], + ) + + response = await agent_conn.create_elicitation( + message="Need deployment target", + mode=ElicitationFormSessionMode( + session_id="sess", + tool_call_id="tool-1", + requested_schema=requested_schema, + ), + trace_id="trace-1", + ) + + assert isinstance(response, AcceptElicitationResponse) + assert len(client.elicitation_requests) == 1 + message, mode, metadata = client.elicitation_requests[0] + assert message == "Need deployment target" + assert isinstance(mode, ElicitationFormSessionMode) + assert mode.session_id == "sess" + assert mode.tool_call_id == "tool-1" + assert mode.requested_schema.required == ["target"] + assert metadata == {"trace_id": "trace-1"} + + +@pytest.mark.asyncio +async def test_create_url_elicitation_and_complete_roundtrip(connect, client): + agent_conn, _ = connect(use_unstable_protocol=True) + + response = await agent_conn.create_elicitation( + message="Open authorization page", + mode=ElicitationUrlRequestMode( + request_id="req-1", + elicitation_id="elicitation-1", + url=AnyUrl("https://example.com/auth"), + ), + ) + await agent_conn.complete_elicitation(elicitation_id="elicitation-1", source="browser") + + assert isinstance(response, AcceptElicitationResponse) + assert len(client.elicitation_requests) == 1 + message, mode, metadata = client.elicitation_requests[0] + assert message == "Open authorization page" + assert isinstance(mode, ElicitationUrlRequestMode) + assert mode.request_id == "req-1" + assert mode.elicitation_id == "elicitation-1" + assert str(mode.url) == "https://example.com/auth" + assert metadata == {} + + for _ in range(50): + if client.completed_elicitations: + break + await asyncio.sleep(0.01) + assert len(client.completed_elicitations) == 1 + assert client.completed_elicitations[0].elicitation_id == "elicitation-1" + assert client.completed_elicitations[0].field_meta == {"source": "browser"} + + @pytest.mark.asyncio async def test_concurrent_reads(connect, client): for i in range(5): @@ -481,12 +549,17 @@ async def initialize( return InitializeResponse(protocol_version=protocol_version) async def new_session( - self, cwd: str, mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio], **kwargs: Any + self, + cwd: str, + additional_directories: list[str] | None = None, + mcp_servers: list[HttpMcpServer | SseMcpServer | McpServerStdio] | None = None, + **kwargs: Any, ) -> NewSessionResponse: return NewSessionResponse(session_id="sess_demo") async def prompt( self, + session_id: str, prompt: list[ TextContentBlock | ImageContentBlock @@ -494,7 +567,6 @@ async def prompt( | ResourceContentBlock | EmbeddedResourceContentBlock ], - session_id: str, **kwargs: Any, ) -> PromptResponse: assert self._conn is not None @@ -561,15 +633,15 @@ def __init__(self) -> None: async def request_permission( self, - options: list[PermissionOption] | RequestPermissionRequest, - session_id: str | None = None, + session_id: str | RequestPermissionRequest, tool_call: ToolCallUpdate | None = None, + options: list[PermissionOption] | None = None, **kwargs: Any, ) -> RequestPermissionResponse: - if isinstance(options, RequestPermissionRequest): - params = options + if isinstance(session_id, RequestPermissionRequest): + params = session_id else: - assert session_id is not None and tool_call is not None + assert tool_call is not None and options is not None params = RequestPermissionRequest( options=options, session_id=session_id, From b2db2566b6147535cbf9abfe0f072a33767b1959 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Mon, 6 Jul 2026 00:19:50 +0800 Subject: [PATCH 37/52] docs: fix quickstart prompt signature --- docs/quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index 796c3dc..ff31088 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -133,7 +133,7 @@ from acp import Agent, PromptResponse class MyAgent(Agent): - async def prompt(self, prompt, session_id, **kwargs) -> PromptResponse: + async def prompt(self, session_id, prompt, **kwargs) -> PromptResponse: # inspect prompt, stream updates, then finish the turn return PromptResponse(stop_reason="end_turn") ``` From 0f2859a95f36c69d6e405c7af50cabde05b19ba6 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Mon, 6 Jul 2026 00:38:57 +0800 Subject: [PATCH 38/52] docs: add 0.11 migration guide --- docs/index.md | 2 + docs/migration-guide-0.11.md | 144 +++++++++++++++++++++++++++++++++++ docs/quickstart.md | 2 +- mkdocs.yml | 1 + 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 docs/migration-guide-0.11.md diff --git a/docs/index.md b/docs/index.md index 4f70105..88dc076 100644 --- a/docs/index.md +++ b/docs/index.md @@ -38,6 +38,7 @@ Next steps live in the [Quickstart](quickstart.md): launch the echo agent, wire | Real-world adopters | [use-cases.md](use-cases.md) | | Contrib helpers | [contrib.md](contrib.md) | | Releasing workflow | [releasing.md](releasing.md) | +| Upgrade to 0.11 | [migration-guide-0.11.md](migration-guide-0.11.md) | | Example scripts | [github.com/agentclientprotocol/python-sdk/tree/main/examples](https://github.com/agentclientprotocol/python-sdk/tree/main/examples) | ## Choose a path @@ -52,6 +53,7 @@ Next steps live in the [Quickstart](quickstart.md): launch the echo agent, wire - [Use Cases](use-cases.md) — real adopters with succinct descriptions of what they build. - [Experimental Contrib](contrib.md) — deep dives on the `acp.contrib` utilities. - [Releasing](releasing.md) — schema upgrade process, versioning policy, and publishing checklist. +- [0.11 Migration Guide](migration-guide-0.11.md) — interface signature updates, elicitation, and schema notes for 0.10 users. Need API-level details? Browse the source in `src/acp/` or generate docs with `mkdocstrings`. diff --git a/docs/migration-guide-0.11.md b/docs/migration-guide-0.11.md new file mode 100644 index 0000000..a34ab5b --- /dev/null +++ b/docs/migration-guide-0.11.md @@ -0,0 +1,144 @@ +# Migrating to ACP Python SDK 0.11 + +ACP Python SDK 0.11 updates the generated bindings to `schema-v1.16.0` and aligns the high-level interfaces with the new schema. Most applications only need to update method signatures and review the new unstable capabilities. Agents and clients that already pass keyword arguments are the easiest to migrate. + +## 1. Regenerate schema-derived code + +If your project vendors ACP schema files, generated models, or protocol metadata, regenerate them against the same upstream schema tag: + +```bash +ACP_SCHEMA_VERSION=schema-v1.16.0 make gen-all +``` + +The SDK package version is `0.11.0`, while the protocol schema tag is `schema-v1.16.0`. + +## 2. Update interface method signatures + +Several generated request models changed field order or fields. The SDK now exposes those shapes through `Agent` and `Client` protocol methods. Prefer keyword calls when invoking connection helpers; keyword calls are stable across field-order changes. + +### Client methods + +Update client implementations from the 0.10 positional order: + +```python +async def request_permission(self, options, session_id, tool_call, **kwargs): ... +async def write_text_file(self, content, path, session_id, **kwargs): ... +async def read_text_file(self, path, session_id, limit=None, line=None, **kwargs): ... +async def create_terminal(self, command, session_id, args=None, cwd=None, env=None, **kwargs): ... +``` + +to the 0.11 order: + +```python +async def request_permission(self, session_id, tool_call, options, **kwargs): ... +async def write_text_file(self, session_id, path, content, **kwargs): ... +async def read_text_file(self, session_id, path, line=None, limit=None, **kwargs): ... +async def create_terminal(self, session_id, command, args=None, env=None, cwd=None, **kwargs): ... +``` + +### Agent methods + +Update agent implementations from the 0.10 prompt and mode signatures: + +```python +async def set_session_mode(self, mode_id, session_id, **kwargs): ... +async def prompt(self, prompt, session_id, message_id=None, **kwargs): ... +``` + +to the 0.11 signatures: + +```python +async def set_session_mode(self, session_id, mode_id, **kwargs): ... +async def prompt(self, session_id, prompt, **kwargs): ... +``` + +The `message_id` field was removed from `PromptRequest`. If your client generated a user message ID before calling `conn.prompt(...)`, stop passing it there. Message IDs now belong to streamed content chunks such as `UserMessageChunk` and `AgentMessageChunk`. + +## 3. Remove `session/model` handling + +The generated `SetSessionModelRequest` and `SetSessionModelResponse` types are no longer exported, and the `Agent.set_session_model(...)` protocol method is gone. If your agent used this endpoint to switch models, move that behavior into session modes or configuration options exposed through `set_session_mode(...)` and `set_config_option(...)`. + +## 4. Handle elicitation if your agent or client advertises it + +0.11 adds schema and connection support for the unstable `elicitation/create` request and `elicitation/complete` notification. + +Clients that advertise elicitation support should implement: + +```python +from typing import Any + +from acp import AcceptElicitationResponse, Client, CreateElicitationResponse, ElicitationMode + + +class MyClient(Client): + async def create_elicitation( + self, + message: str, + mode: ElicitationMode, + **kwargs: Any, + ) -> CreateElicitationResponse: + return AcceptElicitationResponse(action="accept", content={}) + + async def complete_elicitation(self, elicitation_id: str, **kwargs: Any) -> None: + ... +``` + +Agents can request structured input through the connected client: + +```python +from acp import ( + ElicitationFormSessionMode, + ElicitationSchema, + ElicitationStringPropertySchema, +) + +response = await client_conn.create_elicitation( + message="Choose a deployment target", + mode=ElicitationFormSessionMode( + session_id=session_id, + requested_schema=ElicitationSchema( + properties={"target": ElicitationStringPropertySchema(type="string")}, + required=["target"], + ), + ), +) +``` + +For URL-based flows, use `ElicitationUrlSessionMode` or `ElicitationUrlRequestMode` and call `complete_elicitation(...)` once the external flow finishes. + +## 5. Review new session update variants + +Clients that exhaustively match `session_update` variants should add the new plan update variants: + +```python +from acp.schema import AgentPlanContentUpdate, AgentPlanRemovedUpdate + +async def session_update(self, session_id, update, **kwargs): + if isinstance(update, AgentPlanContentUpdate): + ... + elif isinstance(update, AgentPlanRemovedUpdate): + ... +``` + +The existing full-plan `AgentPlanUpdate` variant remains available. + +## 6. Review MCP server configuration types + +Session creation, loading, forking, and resuming now accept `AcpMcpServer` in addition to HTTP, SSE, and stdio MCP server definitions: + +```python +from acp.schema import AcpMcpServer, HttpMcpServer, McpServerStdio, SseMcpServer +``` + +If you validate `mcp_servers` with your own union, add `AcpMcpServer` to keep accepting all SDK-supported server types. + +## 7. Re-run examples and checks + +After changing signatures, run the standard gates: + +```bash +make check +make test +``` + +Also run any example or integration that subclasses `Agent` or `Client`. Positional argument bugs usually surface there first; using keyword arguments for connection calls avoids most of them. diff --git a/docs/quickstart.md b/docs/quickstart.md index ff31088..04ef33d 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -99,7 +99,7 @@ from acp.interfaces import Client class SimpleClient(Client): async def request_permission( - self, options, session_id, tool_call, **kwargs: Any + self, session_id, tool_call, options, **kwargs: Any ): return {"outcome": {"outcome": "cancelled"}} diff --git a/mkdocs.yml b/mkdocs.yml index 6a7a76e..09e3ea4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,6 +13,7 @@ nav: - Use Cases: use-cases.md - Experimental Contrib: contrib.md - Releasing: releasing.md + - 0.11 Migration Guide: migration-guide-0.11.md - 0.7 Migration Guide: migration-guide-0.7.md - 0.8 Migration Guide: migration-guide-0.8.md plugins: From 3b3a5e35a2750110d65216fdb7c899ba4127e495 Mon Sep 17 00:00:00 2001 From: Michel Thomazo Date: Fri, 10 Jul 2026 09:21:52 +0200 Subject: [PATCH 39/52] fix(connection): log unhandled RPC handler exceptions --- src/acp/connection.py | 17 ++++- tests/test_request_error_logging.py | 108 ++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 tests/test_request_error_logging.py diff --git a/src/acp/connection.py b/src/acp/connection.py index 09e5a0e..41cdebc 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -1,7 +1,6 @@ from __future__ import annotations import asyncio -import contextlib import copy import inspect import json @@ -255,6 +254,11 @@ async def _run_request(self, message: dict[str, Any]) -> Any: self._notify_observers(StreamDirection.OUTGOING, payload) raise err from None except Exception as exc: + logging.exception( + "Unhandled error while handling request method=%s", + method, + exc_info=exc, + ) try: data = json.loads(str(exc)) except Exception: @@ -267,8 +271,15 @@ async def _run_request(self, message: dict[str, Any]) -> Any: async def _run_notification(self, message: dict[str, Any]) -> None: method = message["method"] - with span_context("acp.notification", attributes={"method": method}), contextlib.suppress(Exception): - await self._handler(method, message.get("params"), True) + with span_context("acp.notification", attributes={"method": method}): + try: + await self._handler(method, message.get("params"), True) + except Exception as exc: + logging.exception( + "Unhandled error while handling notification method=%s", + method, + exc_info=exc, + ) async def _handle_response(self, message: dict[str, Any]) -> None: request_id = message["id"] diff --git a/tests/test_request_error_logging.py b/tests/test_request_error_logging.py new file mode 100644 index 0000000..3581804 --- /dev/null +++ b/tests/test_request_error_logging.py @@ -0,0 +1,108 @@ +"""Unhandled RPC handler exceptions must be logged instead of silently swallowed. + +Requests already returned a JSON-RPC -32603 error but discarded the original +traceback; notifications suppressed the exception entirely. Both now log the +underlying exception so integrators (e.g. Sentry via its logging integration) +can see server-side handler crashes. +""" + +from __future__ import annotations + +import asyncio +import logging +from typing import Any +from unittest.mock import MagicMock + +import pytest + +from acp.connection import Connection, MethodHandler +from acp.exceptions import RequestError + + +class _RecordingSender: + """Duck-typed MessageSender that records outgoing frames instead of writing them.""" + + def __init__(self, writer: asyncio.StreamWriter, supervisor: Any) -> None: + self.sent: list[dict[str, Any]] = [] + + async def send(self, payload: dict[str, Any]) -> None: + self.sent.append(payload) + + async def close(self) -> None: + pass + + +def _make_connection(handler: MethodHandler) -> tuple[Connection, _RecordingSender]: + captured: dict[str, _RecordingSender] = {} + + def sender_factory(writer: asyncio.StreamWriter, supervisor: Any) -> _RecordingSender: + captured["sender"] = _RecordingSender(writer, supervisor) + return captured["sender"] + + conn = Connection(handler, MagicMock(), MagicMock(), sender_factory=sender_factory, listening=False) + return conn, captured["sender"] + + +async def _raising_handler(method: str, params: Any, is_notification: bool) -> Any: + raise RuntimeError("kaboom") + + +def _assert_logged_runtime_error(caplog: pytest.LogCaptureFixture, method: str) -> None: + records = [ + record + for record in caplog.records + if record.levelno == logging.ERROR and record.exc_info and f"method={method}" in record.getMessage() + ] + assert len(records) == 1, f"expected exactly one logged error for method={method}" + exc_info = records[0].exc_info + assert exc_info is not None + logged = exc_info[1] + assert isinstance(logged, RuntimeError) + assert str(logged) == "kaboom" + + +@pytest.mark.asyncio +async def test_run_request_unhandled_exception_is_logged_and_returned_as_internal_error(caplog): + conn, sender = _make_connection(_raising_handler) + request = {"jsonrpc": "2.0", "id": 7, "method": "explode", "params": None} + + try: + with caplog.at_level(logging.ERROR), pytest.raises(RequestError) as exc_info: + await conn._run_request(request) + finally: + await conn.close() + + # The handler exception is re-raised as a JSON-RPC internal error... + raised = exc_info.value + assert isinstance(raised, RequestError) + assert raised.code == -32603 + assert raised.data == {"details": "kaboom"} + + # ...and exactly one error frame carrying the handler's message is written to the peer. + assert len(sender.sent) == 1 + response = sender.sent[0] + assert response["id"] == 7 + assert "result" not in response + assert response["error"] == {"code": -32603, "message": "Internal error", "data": {"details": "kaboom"}} + + # The original exception is logged, not discarded by `raise err from None`. + _assert_logged_runtime_error(caplog, "explode") + + +@pytest.mark.asyncio +async def test_run_notification_unhandled_exception_is_logged_and_not_answered(caplog): + conn, sender = _make_connection(_raising_handler) + notification = {"jsonrpc": "2.0", "method": "session/cancel", "params": {"sessionId": "s1"}} + + try: + with caplog.at_level(logging.ERROR): + result = await conn._run_notification(notification) + finally: + await conn.close() + + # A notification has no response: the error is neither raised nor written to the wire. + assert result is None + assert sender.sent == [] + + # It must still be logged — previously contextlib.suppress dropped it silently. + _assert_logged_runtime_error(caplog, "session/cancel") From e7cac429f4004dea59439b3e49ec364eceff1665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Sat, 25 Jul 2026 23:09:22 +0200 Subject: [PATCH 40/52] chore: package scritps/ directory as well (#120) Fixes: https://github.com/agentclientprotocol/python-sdk/issues/119 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6432be2..700090f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ requires = ["pdm-backend"] build-backend = "pdm.backend" [tool.pdm.build] -source-includes = ["examples/", "tests/"] +source-includes = ["examples/", "tests/", "scripts/"] [tool.ty.environment] python = "./.venv" From 14b2956a1324b128a8e8a1e72411690b2bdd9219 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 02:38:27 +0800 Subject: [PATCH 41/52] chore(deps): bump pymdown-extensions in the uv group across 1 directory (#121) Bumps the uv group with 1 update in the / directory: [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions). Updates `pymdown-extensions` from 10.21.3 to 11.0 - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.21.3...11.0) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-version: '11.0' dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/uv.lock b/uv.lock index 4e813f0..933c3db 100644 --- a/uv.lock +++ b/uv.lock @@ -683,7 +683,7 @@ wheels = [ [[package]] name = "mkdocs-material" -version = "9.6.23" +version = "9.7.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "babel" }, @@ -698,9 +698,9 @@ dependencies = [ { name = "pymdown-extensions" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/57/de/cc1d5139c2782b1a49e1ed1845b3298ed6076b9ba1c740ad7c952d8ffcf9/mkdocs_material-9.6.23.tar.gz", hash = "sha256:62ebc9cdbe90e1ae4f4e9b16a6aa5c69b93474c7b9e79ebc0b11b87f9f055e00", size = 4048130, upload-time = "2025-11-01T16:33:11.782Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/cd/c05d3a530ba7934f144fb45f7203cd236adc25c7bdcc34673d202f4b0278/mkdocs_material-9.7.7.tar.gz", hash = "sha256:c0649c065b1b0512d60aad8c10f947f8e455284475239b364b610f2deb4d0855", size = 4097923, upload-time = "2026-07-17T16:21:33.156Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/df/bc583e857174b0dc6df67d555123533f09e7e1ac0f3fae7693fb6840c0a3/mkdocs_material-9.6.23-py3-none-any.whl", hash = "sha256:3bf3f1d82d269f3a14ed6897bfc3a844cc05e1dc38045386691b91d7e6945332", size = 9210689, upload-time = "2025-11-01T16:33:08.196Z" }, + { url = "https://files.pythonhosted.org/packages/ad/21/17c1bc9e6f47c972ad66fb2ac2568f99f90f1207eeb6fc3b34d094dba7b5/mkdocs_material-9.7.7-py3-none-any.whl", hash = "sha256:8ea9bb1737a5b524a5f9dcf2e1b4ebda8274ae3008aa7845720a97083bef708f", size = 9305438, upload-time = "2026-07-17T16:21:30.017Z" }, ] [[package]] @@ -1090,15 +1090,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.21.3" +version = "11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140, upload-time = "2026-05-13T12:57:32.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/67/f1e79672a5f91985577c7984c9709ca110e4fd37fe7fd167b60422e6ccc2/pymdown_extensions-11.0.tar.gz", hash = "sha256:8269cef0247f9e2d0a62fcea10860aba05c1cbab5470fd4b63230b96434dc589", size = 857049, upload-time = "2026-06-23T02:27:45.146Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002, upload-time = "2026-05-13T12:57:30.296Z" }, + { url = "https://files.pythonhosted.org/packages/af/b6/1ae53367e28b9cffa3be7574e13fbe4589694272fd47710fbdbafd3d63c6/pymdown_extensions-11.0-py3-none-any.whl", hash = "sha256:fbc4acb641814fa9d17521bbd21a5240ef739a662f11c06330c4b78c93e954d6", size = 269415, upload-time = "2026-06-23T02:27:43.826Z" }, ] [[package]] From 02b6f874525927a501daf8004cae8a30f91723a2 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Tue, 28 Jul 2026 02:42:39 +0800 Subject: [PATCH 42/52] chore: bump version to 0.11.1 (#122) --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 700090f..04117f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.11.0" +version = "0.11.1" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 933c3db..d8abdd3 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10, <3.15" [[package]] name = "agent-client-protocol" -version = "0.11.0" +version = "0.11.1" source = { editable = "." } dependencies = [ { name = "pydantic" }, From e0560baf451146b0bd6bdaca09d628a4d95fa5db Mon Sep 17 00:00:00 2001 From: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Date: Thu, 30 Jul 2026 18:42:44 +0200 Subject: [PATCH 43/52] feat(schema): bump ACP schema to v1.19.0 (extensible unions + lenient deserialization) (#117) * feat(schema): support custom/future variants and bump ACP schema to v1.19.0 Bump schema-v1.16.0 -> schema-v1.19.0. v1.18.0 introduced an "extensible union" idiom (known const-tagged variants plus a "custom or future" catch-all member) that datamodel-codegen cannot express in a discriminated union, so it emitted broken placeholder literals. Codegen support (scripts/gen_schema.py): - _normalize_catchall_unions: strip the discriminator and collapse each catch-all member to a permissive object, so codegen emits a plain, payload-preserving union. - Inject a field_validator per catch-all that rejects the known discriminator values (recovered from the schema's `not` clause), so a malformed known variant fails instead of silently parsing as custom (mirrors the TS SDK's excludeKnownTags). - EXTENSIBLE_UNIONS map + drift assertion so changes to the union set fail loudly. - RENAME_MAP names for the 5 new variants; alias template updated so the parse adapters include the catch-all. Export the 3 new Elicitation*/Create* variants from the acp package. Add unit and behavioral regression tests. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe * feat(schema): honor x-deserialize-default-on-error and skip-invalid-items The schema declares lenient-deserialization hints that generated Pydantic models cannot express directly: x-deserialize-default-on-error (salvage a malformed field to its default) on 379 fields, and x-deserialize-skip-invalid-items (drop bad array items) on 35. Mirrors the TypeScript SDK's src/schema-deserialize.ts. - src/acp/_deserialize.py: leaf module (imports only pydantic, so schema.py can depend on it without a layering cycle) with salvage_on_error and skip_invalid_items. - gen_schema.py injects field_validator(mode="wrap") methods: `_meta` once on the shared BaseModel via check_fields=False (inherited everywhere); non-meta fields per $def grouped by fallback (None / [] / schema default); union-def common props target the member variant classes. - Generated schema.py uses an absolute import (from acp._deserialize) because gen_signature.py loads the module standalone, where relative imports cannot resolve. Add unit tests (fallback rules, spec extraction) and behavioral round-trips. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe * fix(client): reject unknown elicitation modes with a clean error Adding CreateOtherElicitationRequest to the CreateElicitationRequest union (so custom/future modes parse) made a previously-unreachable `raise TypeError` in the client router reachable: an incoming custom mode now parses, then _mode_from_create_elicitation_request hit the fallthrough and surfaced as an opaque -32603 internal error (plus a logged traceback). Raise RequestError.invalid_params instead, so a client that can't render an unknown mode declines with a clean -32602. Adds a regression test. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe * fix(schema): terminate generated JSON with a trailing newline pretty-format-json (pre-commit) rewrites schema/schema.json and schema/meta.json because gen_all wrote them via json.dumps(indent=2) with no trailing newline. Content is otherwise identical to the hook's output, so add the newline in download_schema (keeping regeneration idempotent) and to the committed files. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --------- Co-authored-by: Mistral Vibe --- schema/VERSION | 2 +- schema/schema.json | 1034 +++++++++++++++++----- scripts/gen_all.py | 4 +- scripts/gen_schema.py | 243 +++++- src/acp/__init__.py | 6 + src/acp/_deserialize.py | 43 + src/acp/client/router.py | 8 +- src/acp/meta.py | 2 +- src/acp/schema.py | 1294 +++++++++++++++++++++++----- tests/test_deserialize.py | 62 ++ tests/test_elicitation_catchall.py | 83 ++ tests/test_gen_all.py | 87 +- 12 files changed, 2391 insertions(+), 477 deletions(-) create mode 100644 src/acp/_deserialize.py create mode 100644 tests/test_deserialize.py create mode 100644 tests/test_elicitation_catchall.py diff --git a/schema/VERSION b/schema/VERSION index 994766d..5c3b96a 100644 --- a/schema/VERSION +++ b/schema/VERSION @@ -1 +1 @@ -refs/tags/schema-v1.16.0 +refs/tags/schema-v1.19.0 diff --git a/schema/schema.json b/schema/schema.json index a117ee8..0f44cbf 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -109,7 +109,7 @@ "anyOf": [ { "title": "CancelRequestNotification", - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or\nchanged at any point.\n\nCancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MUST cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "description": "Cancels an ongoing request.\n\nThis is a notification sent by the side that sent a request to cancel that request.\n\nUpon receiving this notification, the receiver:\n\n1. MAY cancel the corresponding request activity and all nested activities\n2. MAY send any pending notifications.\n3. MUST send one of these responses for the original request:\n - Valid response with appropriate data (partial results or cancellation marker)\n - Error response with code `-32800` (Cancelled)\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", "allOf": [ { "$ref": "#/$defs/CancelRequestNotification" @@ -332,6 +332,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -370,7 +371,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "limit": { "description": "Maximum number of lines to read.", @@ -379,7 +381,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -387,6 +390,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -430,6 +434,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -482,7 +487,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "content": { "description": "Replace the content collection.", @@ -509,10 +515,12 @@ "x-deserialize-skip-invalid-items": true }, "rawInput": { - "description": "Update the raw input." + "description": "Update the raw input.", + "x-deserialize-default-on-error": true }, "rawOutput": { - "description": "Update the raw output." + "description": "Update the raw output.", + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -520,6 +528,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -792,7 +801,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "priority": { "description": "Relative importance of this content when clients choose what to surface.", @@ -800,7 +810,8 @@ "number", "null" ], - "format": "double" + "format": "double", + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -808,6 +819,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -853,6 +865,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -889,7 +902,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -897,6 +911,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -935,6 +950,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -964,14 +980,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "mimeType": { "description": "MIME type describing the encoded media payload.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "name": { "description": "Human-readable name shown for this protocol object.", @@ -983,14 +1001,16 @@ "integer", "null" ], - "format": "int64" + "format": "int64", + "x-deserialize-default-on-error": true }, "title": { "description": "Optional display title for end-user UI.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "uri": { "description": "URI associated with this resource or media payload.", @@ -1002,6 +1022,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1042,7 +1063,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "text": { "description": "Text payload carried by this content block.", @@ -1058,6 +1080,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1079,7 +1102,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "uri": { "description": "URI associated with this resource or media payload.", @@ -1091,6 +1115,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1129,6 +1154,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1154,6 +1180,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1166,7 +1193,7 @@ "type": "object", "properties": { "path": { - "description": "The file path being modified.", + "description": "The absolute file path being modified.", "type": "string" }, "oldText": { @@ -1174,7 +1201,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "newText": { "description": "The new content after modification.", @@ -1186,6 +1214,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1216,6 +1245,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1228,7 +1258,7 @@ "type": "object", "properties": { "path": { - "description": "The file path being accessed or modified.", + "description": "The absolute file path being accessed or modified.", "type": "string" }, "line": { @@ -1238,7 +1268,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -1246,6 +1277,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1283,6 +1315,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1342,21 +1375,26 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "env": { "description": "Environment variables for the command.", "type": "array", "items": { "$ref": "#/$defs/EnvVariable" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "cwd": { - "description": "Working directory for the command (absolute path).", + "description": "Working directory for the command. Must be an absolute path.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "outputByteLimit": { "description": "Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", @@ -1365,7 +1403,8 @@ "null" ], "format": "uint64", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -1373,6 +1412,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1401,6 +1441,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1435,6 +1476,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1471,6 +1513,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1507,6 +1550,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1543,6 +1587,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1567,10 +1612,11 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, - "oneOf": [ + "anyOf": [ { "description": "Form-based elicitation where the client renders a form from the provided schema.", "type": "object", @@ -1606,6 +1652,69 @@ "$ref": "#/$defs/ElicitationUrlMode" } ] + }, + { + "title": "other", + "description": "Custom or future elicitation mode.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.\n\nClients that do not understand this mode should preserve the raw payload\nwhen storing, replaying, proxying, or forwarding elicitation requests.\nThey MUST NOT render it as a known elicitation mode.", + "type": "object", + "properties": { + "mode": { + "description": "Custom or future elicitation mode.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.", + "type": "string" + } + }, + "required": [ + "mode" + ], + "anyOf": [ + { + "title": "Session", + "description": "Tied to a session, optionally to a specific tool call within that session.", + "allOf": [ + { + "$ref": "#/$defs/ElicitationSessionScope" + } + ] + }, + { + "title": "Request", + "description": "Tied to a specific JSON-RPC request outside of a session\n(e.g., during auth/configuration phases before any session is started).", + "allOf": [ + { + "$ref": "#/$defs/ElicitationRequestScope" + } + ] + } + ], + "unevaluatedProperties": true, + "not": { + "anyOf": [ + { + "type": "object", + "properties": { + "mode": { + "type": "string", + "const": "form" + } + }, + "required": [ + "mode" + ] + }, + { + "type": "object", + "properties": { + "mode": { + "type": "string", + "const": "url" + } + }, + "required": [ + "mode" + ] + } + ] + } } ], "discriminator": { @@ -1638,7 +1747,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true } }, "required": [ @@ -1668,6 +1778,7 @@ "properties": { "type": { "description": "Type discriminator. Always `\"object\"`.", + "x-deserialize-default-on-error": true, "default": "object", "allOf": [ { @@ -1680,7 +1791,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "properties": { "description": "Property definitions (must be primitive types).", @@ -1705,7 +1817,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -1713,6 +1826,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -1729,7 +1843,7 @@ }, "ElicitationPropertySchema": { "description": "Property schema for elicitation form fields.\n\nEach variant corresponds to a JSON Schema `\"type\"` value.\nSingle-select enums use the `String` variant with `enum` or `oneOf` set.\nMulti-select enums use the `Array` variant.", - "oneOf": [ + "anyOf": [ { "description": "String property (or single-select enum when `enum`/`oneOf` is set).", "type": "object", @@ -1819,6 +1933,85 @@ "$ref": "#/$defs/MultiSelectPropertySchema" } ] + }, + { + "title": "other", + "description": "Custom or future elicitation property schema.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.\n\nClients that do not understand this property schema type should preserve\nthe raw schema when storing, replaying, proxying, or forwarding\nelicitation requests. They MUST NOT render it as a known input control.", + "type": "object", + "properties": { + "type": { + "description": "Custom or future elicitation property schema type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.", + "type": "string" + } + }, + "required": [ + "type" + ], + "not": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string" + } + }, + "required": [ + "type" + ] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "number" + } + }, + "required": [ + "type" + ] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "integer" + } + }, + "required": [ + "type" + ] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "boolean" + } + }, + "required": [ + "type" + ] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "array" + } + }, + "required": [ + "type" + ] + } + ] + }, + "additionalProperties": true } ], "discriminator": { @@ -1851,7 +2044,7 @@ ] }, "EnumOption": { - "description": "A titled enum option with a const value and human-readable title.", + "description": "A titled enum option with a const value, human-readable title, and optional description.", "type": "object", "properties": { "const": { @@ -1862,12 +2055,21 @@ "description": "Human-readable title for this option.", "type": "string" }, + "description": { + "description": "Human-readable description.", + "type": [ + "string", + "null" + ], + "x-deserialize-default-on-error": true + }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", "type": [ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -1885,14 +2087,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "description": { "description": "Human-readable description.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "minLength": { "description": "Minimum string length.", @@ -1935,7 +2139,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "enum": { "description": "Enum values for untitled single-select enums.", @@ -1963,6 +2168,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -1976,14 +2182,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "description": { "description": "Human-readable description.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "minimum": { "description": "Minimum value (inclusive).", @@ -2007,7 +2215,8 @@ "number", "null" ], - "format": "double" + "format": "double", + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2015,6 +2224,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2028,14 +2238,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "description": { "description": "Human-readable description.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "minimum": { "description": "Minimum value (inclusive).", @@ -2059,7 +2271,8 @@ "integer", "null" ], - "format": "int64" + "format": "int64", + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2067,6 +2280,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2080,21 +2294,24 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "description": { "description": "Human-readable description.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "default": { "description": "Default value.", "type": [ "boolean", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2102,6 +2319,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2110,16 +2328,56 @@ "description": "Items for a multi-select (array) property schema.", "anyOf": [ { - "title": "Untitled", - "description": "Untitled multi-select items with plain string values.", + "description": "Multi-select string items with plain string values.", + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string" + } + }, + "required": [ + "type" + ], "allOf": [ { - "$ref": "#/$defs/UntitledMultiSelectItems" + "$ref": "#/$defs/StringMultiSelectItems" } ] }, { - "title": "Titled", + "title": "other", + "description": "Custom or future typed multi-select items.", + "type": "object", + "properties": { + "type": { + "description": "Custom or future multi-select item type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.", + "type": "string" + } + }, + "required": [ + "type" + ], + "not": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string" + } + }, + "required": [ + "type" + ] + } + ] + }, + "additionalProperties": true + }, + { + "title": "titled", "description": "Titled multi-select items with human-readable labels.", "allOf": [ { @@ -2127,20 +2385,15 @@ } ] } - ] + ], + "discriminator": { + "propertyName": "type" + } }, - "UntitledMultiSelectItems": { - "description": "Items definition for untitled multi-select enum properties.", + "StringMultiSelectItems": { + "description": "String item schema for multi-select enum properties.", "type": "object", "properties": { - "type": { - "description": "Item type discriminator. Must be `\"string\"`.", - "allOf": [ - { - "$ref": "#/$defs/ElicitationStringType" - } - ] - }, "enum": { "description": "Allowed enum values.", "type": "array", @@ -2154,24 +2407,14 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "type", "enum" ] }, - "ElicitationStringType": { - "description": "Items definition for untitled multi-select enum properties.", - "oneOf": [ - { - "description": "String schema type.", - "type": "string", - "const": "string" - } - ] - }, "TitledMultiSelectItems": { "description": "Items definition for titled multi-select enum properties.", "type": "object", @@ -2189,6 +2432,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -2205,14 +2449,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "description": { "description": "Human-readable description.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "minItems": { "description": "Minimum number of items to select.", @@ -2248,7 +2494,9 @@ ], "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2256,6 +2504,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -2351,7 +2600,7 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `mcp/connect`.", "type": "object", "properties": { - "acpId": { + "serverId": { "description": "The ACP MCP server ID that was provided by the component declaring the MCP server.", "allOf": [ { @@ -2365,11 +2614,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "acpId" + "serverId" ], "x-side": "client", "x-method": "mcp/connect" @@ -2408,6 +2658,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -2440,6 +2691,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -2712,6 +2964,7 @@ }, "agentCapabilities": { "description": "Capabilities supported by the agent.", + "x-deserialize-default-on-error": true, "default": { "loadSession": false, "promptCapabilities": { @@ -2761,6 +3014,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -2784,10 +3038,12 @@ "loadSession": { "description": "Whether the agent supports `session/load`.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "promptCapabilities": { "description": "Prompt capabilities supported by the agent.", + "x-deserialize-default-on-error": true, "default": { "image": false, "audio": false, @@ -2801,6 +3057,7 @@ }, "mcpCapabilities": { "description": "MCP capabilities supported by the agent.", + "x-deserialize-default-on-error": true, "default": { "http": false, "sse": false, @@ -2814,6 +3071,7 @@ }, "sessionCapabilities": { "description": "Session lifecycle and prompt capabilities advertised by the agent.", + "x-deserialize-default-on-error": true, "default": {}, "allOf": [ { @@ -2823,6 +3081,7 @@ }, "auth": { "description": "Authentication-related capabilities supported by the agent.", + "x-deserialize-default-on-error": true, "default": {}, "allOf": [ { @@ -2831,7 +3090,7 @@ ] }, "providers": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports provider configuration methods.", "anyOf": [ { "$ref": "#/$defs/ProvidersCapabilities" @@ -2843,7 +3102,7 @@ "x-deserialize-default-on-error": true }, "nes": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support\nfor NES methods.", "anyOf": [ { "$ref": "#/$defs/NesCapabilities" @@ -2872,6 +3131,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2883,17 +3143,20 @@ "image": { "description": "Agent supports [`ContentBlock::Image`].", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "audio": { "description": "Agent supports [`ContentBlock::Audio`].", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "embeddedContext": { "description": "Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2901,6 +3164,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2912,17 +3176,20 @@ "http": { "description": "Agent supports [`McpServer::Http`].", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "sse": { "description": "Agent supports [`McpServer::Sse`].", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "acp": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`].", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -2930,6 +3197,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -2939,7 +3207,7 @@ "type": "object", "properties": { "list": { - "description": "Whether the agent supports `session/list`.", + "description": "Whether the agent supports `session/list`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports listing sessions.", "anyOf": [ { "$ref": "#/$defs/SessionListCapabilities" @@ -2963,7 +3231,7 @@ "x-deserialize-default-on-error": true }, "additionalDirectories": { - "description": "Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + "description": "Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports `additionalDirectories` on\nsupported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", "anyOf": [ { "$ref": "#/$defs/SessionAdditionalDirectoriesCapabilities" @@ -2975,7 +3243,7 @@ "x-deserialize-default-on-error": true }, "fork": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports forking sessions.", "anyOf": [ { "$ref": "#/$defs/SessionForkCapabilities" @@ -2987,7 +3255,7 @@ "x-deserialize-default-on-error": true }, "resume": { - "description": "Whether the agent supports `session/resume`.", + "description": "Whether the agent supports `session/resume`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports resuming sessions.", "anyOf": [ { "$ref": "#/$defs/SessionResumeCapabilities" @@ -2999,7 +3267,7 @@ "x-deserialize-default-on-error": true }, "close": { - "description": "Whether the agent supports `session/close`.", + "description": "Whether the agent supports `session/close`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports closing sessions.", "anyOf": [ { "$ref": "#/$defs/SessionCloseCapabilities" @@ -3016,12 +3284,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionListCapabilities": { - "description": "Capabilities for the `session/list` method.\n\nBy supplying `{}` it means that the agent supports listing of sessions.", + "description": "Capabilities for the `session/list` method.\n\nSupplying `{}` means the agent supports listing sessions.", "type": "object", "properties": { "_meta": { @@ -3030,6 +3299,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3044,12 +3314,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionAdditionalDirectoriesCapabilities": { - "description": "Capabilities for additional session directories support.\n\nBy supplying `{}` it means that the agent supports the `additionalDirectories`\nfield on supported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", + "description": "Capabilities for additional session directories support.\n\nSupplying `{}` means the agent supports the `additionalDirectories` field on\nsupported session lifecycle requests. Agents that also support\n`session/list` may return `SessionInfo.additionalDirectories` to report the\ncomplete ordered additional-root list associated with a listed session.", "type": "object", "properties": { "_meta": { @@ -3058,12 +3329,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionForkCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nBy supplying `{}` it means that the agent supports forking of sessions.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for the `session/fork` method.\n\nSupplying `{}` means the agent supports forking sessions.", "type": "object", "properties": { "_meta": { @@ -3072,12 +3344,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionResumeCapabilities": { - "description": "Capabilities for the `session/resume` method.\n\nBy supplying `{}` it means that the agent supports resuming of sessions.", + "description": "Capabilities for the `session/resume` method.\n\nSupplying `{}` means the agent supports resuming sessions.", "type": "object", "properties": { "_meta": { @@ -3086,12 +3359,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionCloseCapabilities": { - "description": "Capabilities for the `session/close` method.\n\nBy supplying `{}` it means that the agent supports closing of sessions.", + "description": "Capabilities for the `session/close` method.\n\nSupplying `{}` means the agent supports closing sessions.", "type": "object", "properties": { "_meta": { @@ -3100,6 +3374,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3109,7 +3384,7 @@ "type": "object", "properties": { "logout": { - "description": "Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "description": "Whether the agent supports the logout method.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports the logout method.", "anyOf": [ { "$ref": "#/$defs/LogoutCapabilities" @@ -3126,12 +3401,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "LogoutCapabilities": { - "description": "Logout capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports the logout method.", + "description": "Logout capabilities supported by the agent.\n\nSupplying `{}` means the agent supports the logout method.", "type": "object", "properties": { "_meta": { @@ -3140,12 +3416,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "ProvidersCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nSupplying `{}` means the agent supports provider configuration methods.", "type": "object", "properties": { "_meta": { @@ -3154,6 +3431,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3192,6 +3470,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3218,6 +3497,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3292,6 +3572,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3306,6 +3587,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3328,6 +3610,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3360,6 +3643,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3374,6 +3658,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3388,6 +3673,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3474,6 +3760,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3489,7 +3776,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3497,6 +3785,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3511,6 +3800,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3526,7 +3816,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3534,6 +3825,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3549,7 +3841,8 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3557,6 +3850,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3571,6 +3865,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3585,6 +3880,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -3676,16 +3972,19 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "secret": { "description": "Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`.", "type": "boolean", + "x-deserialize-default-on-error": true, "default": true }, "optional": { "description": "Whether this variable is optional.\n\nDefaults to `false`.", "type": "boolean", + "x-deserialize-default-on-error": true, "default": false }, "_meta": { @@ -3694,6 +3993,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3722,21 +4022,25 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "vars": { "description": "The environment variables the client should set.", "type": "array", "items": { "$ref": "#/$defs/AuthEnvVar" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "link": { "description": "Optional link to a page where the user can obtain their credentials.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3744,6 +4048,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3774,18 +4079,22 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "args": { "description": "Additional arguments to pass when running the agent binary for terminal auth.", "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "env": { "description": "Additional environment variables to set when running the agent binary for terminal auth.", "type": "object", + "x-deserialize-default-on-error": true, "additionalProperties": { "type": "string" } @@ -3796,6 +4105,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3825,7 +4135,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3833,6 +4144,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3842,7 +4154,7 @@ ] }, "Implementation": { - "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an MCP implementation, with an optional\ntitle for UI representation.", + "description": "Metadata about the implementation of the client or agent.\nDescribes the name and version of an ACP implementation, with an optional\ntitle for UI representation.", "type": "object", "properties": { "name": { @@ -3854,7 +4166,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "version": { "description": "Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. \"1.0.0\").", @@ -3866,6 +4179,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3884,6 +4198,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3899,9 +4214,7 @@ "type": "array", "items": { "$ref": "#/$defs/ProviderInfo" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -3909,6 +4222,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -3922,9 +4236,13 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nInformation about a configurable LLM provider.", "type": "object", "properties": { - "id": { + "providerId": { "description": "Provider identifier, for example \"main\" or \"openai\".", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/ProviderId" + } + ] }, "supported": { "description": "Supported protocol types for this provider.", @@ -3936,7 +4254,7 @@ "x-deserialize-skip-invalid-items": true }, "required": { - "description": "Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id.", + "description": "Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this provider ID.", "type": "boolean" }, "current": { @@ -3956,15 +4274,20 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id", + "providerId", "supported", "required" ] }, + "ProviderId": { + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for a configurable LLM provider.", + "type": "string" + }, "LlmProtocol": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWell-known API protocol identifiers for LLM providers.\n\nAgents and clients MUST handle unknown protocol identifiers gracefully.\n\nProtocol names beginning with `_` are free for custom use, like other ACP extension methods.\nProtocol names that do not begin with `_` are reserved for the ACP spec.", "anyOf": [ @@ -4022,6 +4345,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4040,6 +4364,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4056,6 +4381,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4072,6 +4398,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4120,6 +4447,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4156,6 +4484,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4189,7 +4518,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4197,6 +4527,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4226,7 +4557,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "category": { "description": "Optional semantic category for this option (UX only).", @@ -4246,6 +4578,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4273,7 +4606,7 @@ ] }, { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nBoolean on/off toggle.", + "description": "Boolean on/off toggle.", "type": "object", "properties": { "type": { @@ -4375,7 +4708,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4383,6 +4717,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4412,7 +4747,9 @@ "type": "array", "items": { "$ref": "#/$defs/SessionConfigSelectOption" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4420,6 +4757,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4460,7 +4798,7 @@ ] }, "SessionConfigBoolean": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA boolean on/off toggle session configuration option payload.", + "description": "A boolean on/off toggle session configuration option payload.", "type": "object", "properties": { "currentValue": { @@ -4506,6 +4844,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4530,7 +4869,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4538,6 +4878,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4568,7 +4909,9 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "title": { "description": "Human-readable title for the session", @@ -4592,6 +4935,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4610,6 +4954,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4658,6 +5003,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4701,6 +5047,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4717,6 +5064,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4733,6 +5081,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4758,6 +5107,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4797,6 +5147,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4865,7 +5216,8 @@ "null" ], "format": "uint64", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "cachedReadTokens": { "description": "Total cache read tokens.", @@ -4874,7 +5226,8 @@ "null" ], "format": "uint64", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "cachedWriteTokens": { "description": "Total cache write tokens.", @@ -4883,7 +5236,8 @@ "null" ], "format": "uint64", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4891,6 +5245,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4918,6 +5273,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -4936,9 +5292,7 @@ "type": "array", "items": { "$ref": "#/$defs/NesSuggestion" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -4946,6 +5300,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5035,6 +5390,10 @@ "propertyName": "kind" } }, + "NesSuggestionId": { + "description": "Unique identifier for a next edit suggestion.", + "type": "string" + }, "NesTextEdit": { "description": "A text edit within a suggestion.", "type": "object", @@ -5057,6 +5416,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5091,6 +5451,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5121,6 +5482,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5135,7 +5497,11 @@ "properties": { "id": { "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "uri": { "description": "The URI of the file to edit.", @@ -5166,6 +5532,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5181,7 +5548,11 @@ "properties": { "id": { "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "uri": { "description": "The file to navigate to.", @@ -5201,6 +5572,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5216,7 +5588,11 @@ "properties": { "id": { "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "uri": { "description": "The file URI containing the symbol.", @@ -5240,6 +5616,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5256,7 +5633,11 @@ "properties": { "id": { "description": "Unique identifier for accept/reject tracking.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "uri": { "description": "The file URI to search within.", @@ -5283,6 +5664,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5303,6 +5685,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5334,7 +5717,8 @@ "type": "string" }, "data": { - "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." + "description": "Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details.", + "x-deserialize-default-on-error": true } }, "required": [ @@ -5382,7 +5766,7 @@ }, { "title": "Request cancelled", - "description": "**Request cancelled**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nExecution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", + "description": "**Request cancelled**: Execution of the method was aborted either due to a cancellation request from the caller or\nbecause of resource constraints or shutdown.", "type": "integer", "format": "int32", "const": -32800 @@ -5401,13 +5785,6 @@ "format": "int32", "const": -32002 }, - { - "title": "URL elicitation required", - "description": "**URL elicitation required**: **UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe agent requires user input via a URL-based elicitation before it can proceed.", - "type": "integer", - "format": "int32", - "const": -32042 - }, { "title": "Other", "description": "Other undefined error code.", @@ -5505,6 +5882,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5782,7 +6160,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -5790,6 +6169,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5815,6 +6195,7 @@ }, "kind": { "description": "The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment.", + "x-deserialize-default-on-error": true, "allOf": [ { "$ref": "#/$defs/ToolKind" @@ -5823,6 +6204,7 @@ }, "status": { "description": "Current execution status of the tool call.", + "x-deserialize-default-on-error": true, "allOf": [ { "$ref": "#/$defs/ToolCallStatus" @@ -5848,10 +6230,12 @@ "x-deserialize-skip-invalid-items": true }, "rawInput": { - "description": "Raw input parameters sent to the tool." + "description": "Raw input parameters sent to the tool.", + "x-deserialize-default-on-error": true }, "rawOutput": { - "description": "Raw output returned by the tool." + "description": "Raw output returned by the tool.", + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -5859,6 +6243,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5897,6 +6282,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -5965,6 +6351,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6042,7 +6429,7 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as structured entries.", "type": "object", "properties": { - "id": { + "planId": { "description": "The plan ID to update.", "allOf": [ { @@ -6065,11 +6452,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id", + "planId", "entries" ] }, @@ -6077,7 +6465,7 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented by a file URI.", "type": "object", "properties": { - "id": { + "planId": { "description": "The plan ID to update.", "allOf": [ { @@ -6095,11 +6483,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id", + "planId", "uri" ] }, @@ -6107,7 +6496,7 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA plan represented as raw markdown content.", "type": "object", "properties": { - "id": { + "planId": { "description": "The plan ID to update.", "allOf": [ { @@ -6125,11 +6514,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id", + "planId", "content" ] }, @@ -6151,6 +6541,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6162,7 +6553,7 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRemoval notice for a plan identified by ID.", "type": "object", "properties": { - "id": { + "planId": { "description": "The plan ID to remove.", "allOf": [ { @@ -6176,11 +6567,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id" + "planId" ] }, "AvailableCommand": { @@ -6213,6 +6605,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6249,6 +6642,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6275,6 +6669,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6300,6 +6695,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6326,6 +6722,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6342,14 +6739,16 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "updatedAt": { "description": "ISO 8601 timestamp of last activity. Set to null to clear.", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -6357,6 +6756,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -6380,6 +6780,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6422,6 +6823,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6448,6 +6850,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6479,6 +6882,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true }, "_meta": { @@ -6487,6 +6891,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6739,6 +7144,7 @@ }, "clientCapabilities": { "description": "Capabilities supported by the client.", + "x-deserialize-default-on-error": true, "default": { "fs": { "readTextFile": false, @@ -6773,6 +7179,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -6788,6 +7195,7 @@ "properties": { "fs": { "description": "File system capabilities supported by the client.\nDetermines which file operations the agent can request.", + "x-deserialize-default-on-error": true, "default": { "readTextFile": false, "writeTextFile": false @@ -6801,10 +7209,11 @@ "terminal": { "description": "Whether the Client support all `terminal/*` methods.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "session": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client.", + "description": "Session-related capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nsession-related extensions.", "anyOf": [ { "$ref": "#/$defs/ClientSessionCapabilities" @@ -6816,7 +7225,7 @@ "x-deserialize-default-on-error": true }, "plan": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client can receive both update types.", "anyOf": [ { "$ref": "#/$defs/PlanCapabilities" @@ -6829,6 +7238,7 @@ }, "auth": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`.", + "x-deserialize-default-on-error": true, "default": { "terminal": false }, @@ -6839,7 +7249,7 @@ ] }, "elicitation": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.\n\nOptional. Omitted or `null` both mean the client does not advertise\nelicitation support.", "anyOf": [ { "$ref": "#/$defs/ElicitationCapabilities" @@ -6851,7 +7261,7 @@ "x-deserialize-default-on-error": true }, "nes": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nNES suggestion-kind extensions.", "anyOf": [ { "$ref": "#/$defs/ClientNesCapabilities" @@ -6877,6 +7287,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -6888,12 +7299,14 @@ "readTextFile": { "description": "Whether the Client supports `fs/read_text_file` requests.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "writeTextFile": { "description": "Whether the Client supports `fs/write_text_file` requests.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -6901,16 +7314,17 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "ClientSessionCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client.", + "description": "Session-related capabilities supported by the client.", "type": "object", "properties": { "configOptions": { - "description": "Config option capabilities supported by the client.\n\nOmitted or `null` means the client does not advertise support for any\nconfig option extensions.", + "description": "Config option capabilities supported by the client.\n\nOmitted or `null` both mean the client does not advertise support for any\nconfig option extensions.", "anyOf": [ { "$ref": "#/$defs/SessionConfigOptionsCapabilities" @@ -6927,16 +7341,17 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "SessionConfigOptionsCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession configuration option capabilities supported by the client.", + "description": "Session configuration option capabilities supported by the client.", "type": "object", "properties": { "boolean": { - "description": "Whether the client supports boolean session configuration options.\n\nOmitted or `null` means the client does not advertise support.\nSupplying `{}` means agents may include `type: \"boolean\"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: \"boolean\"` and a boolean `value`.", + "description": "Whether the client supports boolean session configuration options.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means agents may include `type: \"boolean\"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: \"boolean\"` and a boolean `value`.", "anyOf": [ { "$ref": "#/$defs/BooleanConfigOptionCapabilities" @@ -6953,12 +7368,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "BooleanConfigOptionCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nCapabilities for boolean session configuration options.\n\nSupplying `{}` means the client supports boolean session configuration options.", + "description": "Capabilities for boolean session configuration options.\n\nSupplying `{}` means the client supports boolean session configuration options.", "type": "object", "properties": { "_meta": { @@ -6967,6 +7383,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -6981,6 +7398,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -6992,7 +7410,8 @@ "terminal": { "description": "Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods.", "type": "boolean", - "default": false + "default": false, + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -7000,6 +7419,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7009,7 +7429,7 @@ "type": "object", "properties": { "form": { - "description": "Whether the client supports form-based elicitation.", + "description": "Whether the client supports form-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports form-based elicitation.", "anyOf": [ { "$ref": "#/$defs/ElicitationFormCapabilities" @@ -7021,7 +7441,7 @@ "x-deserialize-default-on-error": true }, "url": { - "description": "Whether the client supports URL-based elicitation.", + "description": "Whether the client supports URL-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports URL-based elicitation.", "anyOf": [ { "$ref": "#/$defs/ElicitationUrlCapabilities" @@ -7038,12 +7458,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "ElicitationFormCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation capabilities.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation capabilities.\n\nSupplying `{}` means the client supports form-based elicitation.", "type": "object", "properties": { "_meta": { @@ -7052,12 +7473,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } }, "ElicitationUrlCapabilities": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation capabilities.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation capabilities.\n\nSupplying `{}` means the client supports URL-based elicitation.", "type": "object", "properties": { "_meta": { @@ -7066,6 +7488,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7116,6 +7539,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7130,6 +7554,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7144,6 +7569,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7158,6 +7584,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -7180,6 +7607,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7199,6 +7627,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7206,12 +7635,16 @@ "x-method": "providers/list" }, "SetProviderRequest": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider id.", + "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/set`.\n\nReplaces the full configuration for one provider ID.", "type": "object", "properties": { - "id": { - "description": "Provider id to configure.", - "type": "string" + "providerId": { + "description": "Provider ID to configure.", + "allOf": [ + { + "$ref": "#/$defs/ProviderId" + } + ] }, "apiType": { "description": "Protocol type for this provider.", @@ -7238,11 +7671,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id", + "providerId", "apiType", "baseUrl" ], @@ -7253,9 +7687,13 @@ "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nRequest parameters for `providers/disable`.", "type": "object", "properties": { - "id": { - "description": "Provider id to disable.", - "type": "string" + "providerId": { + "description": "Provider ID to disable.", + "allOf": [ + { + "$ref": "#/$defs/ProviderId" + } + ] }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -7263,11 +7701,12 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ - "id" + "providerId" ], "x-side": "agent", "x-method": "providers/disable" @@ -7282,6 +7721,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7301,14 +7741,18 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "mcpServers": { "description": "List of MCP (Model Context Protocol) servers the agent should connect to.", "type": "array", "items": { "$ref": "#/$defs/McpServer" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -7316,6 +7760,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7412,6 +7857,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7445,6 +7891,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7479,6 +7926,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7496,7 +7944,7 @@ "description": "Human-readable name identifying this MCP server.", "type": "string" }, - "id": { + "serverId": { "description": "Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection.", "allOf": [ { @@ -7510,12 +7958,13 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, "required": [ "name", - "id" + "serverId" ] }, "McpServerStdio": { @@ -7527,7 +7976,7 @@ "type": "string" }, "command": { - "description": "Path to the MCP server executable.", + "description": "Absolute path to the MCP server executable.", "type": "string" }, "args": { @@ -7550,6 +7999,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7569,10 +8019,12 @@ "type": "array", "items": { "$ref": "#/$defs/McpServer" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "cwd": { - "description": "The working directory for this session.", + "description": "The working directory for this session. Must be an absolute path.", "type": "string" }, "additionalDirectories": { @@ -7580,7 +8032,9 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "sessionId": { "description": "The ID of the session to load.", @@ -7596,6 +8050,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7631,6 +8086,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7655,6 +8111,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7677,7 +8134,7 @@ ] }, "cwd": { - "description": "The working directory for this session.", + "description": "The working directory for this session. Must be an absolute path.", "type": "string" }, "additionalDirectories": { @@ -7685,14 +8142,18 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "mcpServers": { "description": "List of MCP servers to connect to for this session.", "type": "array", "items": { "$ref": "#/$defs/McpServer" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -7700,6 +8161,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7723,7 +8185,7 @@ ] }, "cwd": { - "description": "The working directory for this session.", + "description": "The working directory for this session. Must be an absolute path.", "type": "string" }, "additionalDirectories": { @@ -7731,14 +8193,18 @@ "type": "array", "items": { "type": "string" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "mcpServers": { "description": "List of MCP servers to connect to for this session.", "type": "array", "items": { "$ref": "#/$defs/McpServer" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -7746,6 +8212,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7774,6 +8241,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7809,6 +8277,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7845,6 +8314,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7918,6 +8388,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7937,7 +8408,8 @@ "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "workspaceFolders": { "description": "The workspace folders.", @@ -7947,9 +8419,7 @@ ], "items": { "$ref": "#/$defs/WorkspaceFolder" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "repository": { "description": "Repository metadata, if the workspace is a git repository.", @@ -7969,6 +8439,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -7993,6 +8464,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8023,6 +8495,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8070,8 +8543,7 @@ { "type": "null" } - ], - "x-deserialize-default-on-error": true + ] }, "triggerKind": { "description": "What triggered this suggestion request.", @@ -8090,8 +8562,7 @@ { "type": "null" } - ], - "x-deserialize-default-on-error": true + ] }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -8099,6 +8570,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8144,9 +8616,7 @@ ], "items": { "$ref": "#/$defs/NesRecentFile" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "relatedSnippets": { "description": "Related code snippets.", @@ -8156,9 +8626,7 @@ ], "items": { "$ref": "#/$defs/NesRelatedSnippet" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "editHistory": { "description": "Recent edit history.", @@ -8168,9 +8636,7 @@ ], "items": { "$ref": "#/$defs/NesEditHistoryEntry" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "userActions": { "description": "Recent user actions (typing, navigation, etc.).", @@ -8180,9 +8646,7 @@ ], "items": { "$ref": "#/$defs/NesUserAction" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "openFiles": { "description": "Currently open files in the editor.", @@ -8192,9 +8656,7 @@ ], "items": { "$ref": "#/$defs/NesOpenFile" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "diagnostics": { "description": "Current diagnostics (errors, warnings).", @@ -8204,9 +8666,7 @@ ], "items": { "$ref": "#/$defs/NesDiagnostic" - }, - "x-deserialize-default-on-error": true, - "x-deserialize-skip-invalid-items": true + } }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -8214,6 +8674,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -8240,6 +8701,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8270,6 +8732,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8304,6 +8767,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8331,6 +8795,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8371,6 +8836,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8421,6 +8887,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8463,6 +8930,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8516,6 +8984,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8644,20 +9113,20 @@ ] }, { - "title": "ExtMethodResponse", - "description": "Successful result returned by an extension method outside the core ACP method set.", + "title": "MessageMcpResponse", + "description": "Successful result returned by an MCP-over-ACP `mcp/message` request.", "allOf": [ { - "$ref": "#/$defs/ExtResponse" + "$ref": "#/$defs/MessageMcpResponse" } ] }, { - "title": "MessageMcpResponse", - "description": "Successful result returned by an MCP-over-ACP `mcp/message` request.", + "title": "ExtMethodResponse", + "description": "Successful result returned by an extension method outside the core ACP method set.", "allOf": [ { - "$ref": "#/$defs/MessageMcpResponse" + "$ref": "#/$defs/ExtResponse" } ] } @@ -8709,6 +9178,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8729,6 +9199,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8756,6 +9227,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8822,6 +9294,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8847,6 +9320,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8877,7 +9351,8 @@ { "type": "null" } - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -8885,6 +9360,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8906,14 +9382,16 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "signal": { "description": "The signal that terminated the process (may be null if exited normally).", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -8921,6 +9399,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } } @@ -8935,6 +9414,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8952,14 +9432,16 @@ "null" ], "format": "uint32", - "minimum": 0 + "minimum": 0, + "x-deserialize-default-on-error": true }, "signal": { "description": "The signal that terminated the process (may be null if exited normally).", "type": [ "string", "null" - ] + ], + "x-deserialize-default-on-error": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -8967,6 +9449,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8983,6 +9466,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -8999,10 +9483,11 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, - "oneOf": [ + "anyOf": [ { "description": "The user accepted and provided content.", "type": "object", @@ -9046,6 +9531,61 @@ "required": [ "action" ] + }, + { + "title": "other", + "description": "Custom or future elicitation action.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.\n\nAgents that do not understand this action should preserve the raw\npayload when storing, replaying, proxying, or forwarding elicitation\nresponses. They MUST NOT treat it as a known elicitation action.", + "type": "object", + "properties": { + "action": { + "description": "Custom or future elicitation action.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants.", + "type": "string" + } + }, + "required": [ + "action" + ], + "not": { + "anyOf": [ + { + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "accept" + } + }, + "required": [ + "action" + ] + }, + { + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "decline" + } + }, + "required": [ + "action" + ] + }, + { + "type": "object", + "properties": { + "action": { + "type": "string", + "const": "cancel" + } + }, + "required": [ + "action" + ] + } + ] + }, + "additionalProperties": true } ], "discriminator": { @@ -9123,6 +9663,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9142,6 +9683,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9283,6 +9825,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9327,6 +9870,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9366,7 +9910,9 @@ "type": "array", "items": { "$ref": "#/$defs/TextDocumentContentChangeEvent" - } + }, + "x-deserialize-default-on-error": true, + "x-deserialize-skip-invalid-items": true }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -9374,6 +9920,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9411,6 +9958,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9440,6 +9988,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9472,6 +10021,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9525,6 +10075,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9552,7 +10103,11 @@ }, "id": { "description": "The ID of the accepted suggestion.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "_meta": { "description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", @@ -9560,6 +10115,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9584,7 +10140,11 @@ }, "id": { "description": "The ID of the rejected suggestion.", - "type": "string" + "allOf": [ + { + "$ref": "#/$defs/NesSuggestionId" + } + ] }, "reason": { "description": "The reason for rejection.", @@ -9604,6 +10164,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, @@ -9640,7 +10201,7 @@ ] }, "CancelRequestNotification": { - "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNotification to cancel an ongoing request.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", + "description": "Notification to cancel an ongoing request.\n\nSee protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/cancellation)", "type": "object", "properties": { "requestId": { @@ -9657,6 +10218,7 @@ "object", "null" ], + "x-deserialize-default-on-error": true, "additionalProperties": true } }, diff --git a/scripts/gen_all.py b/scripts/gen_all.py index de1cb52..53d4fe9 100644 --- a/scripts/gen_all.py +++ b/scripts/gen_all.py @@ -140,8 +140,8 @@ def download_schema(repo: str, ref: str) -> None: print(exc, file=sys.stderr) sys.exit(1) - SCHEMA_JSON.write_text(json.dumps(schema_data, indent=2), encoding="utf-8") - META_JSON.write_text(json.dumps(meta_data, indent=2), encoding="utf-8") + SCHEMA_JSON.write_text(json.dumps(schema_data, indent=2) + "\n", encoding="utf-8") + META_JSON.write_text(json.dumps(meta_data, indent=2) + "\n", encoding="utf-8") VERSION_FILE.write_text(ref + "\n", encoding="utf-8") print(f"Fetched schema and meta from {repo}@{ref}") diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 571ad34..936f6a4 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -85,9 +85,11 @@ "CreateElicitationRequest2": "CreateFormRequestElicitationRequest", "CreateElicitationRequest3": "CreateUrlSessionElicitationRequest", "CreateElicitationRequest4": "CreateUrlRequestElicitationRequest", + "CreateElicitationRequest5": "CreateOtherElicitationRequest", "CreateElicitationResponse1": "AcceptElicitationResponse", "CreateElicitationResponse2": "DeclineElicitationResponse", "CreateElicitationResponse3": "CancelElicitationResponse", + "CreateElicitationResponse4": "OtherElicitationResponse", "ElicitationFormMode1": "ElicitationFormSessionMode", "ElicitationFormMode2": "ElicitationFormRequestMode", "ElicitationPropertySchema1": "ElicitationStringPropertySchema", @@ -95,6 +97,9 @@ "ElicitationPropertySchema3": "ElicitationIntegerPropertySchema", "ElicitationPropertySchema4": "ElicitationBooleanPropertySchema", "ElicitationPropertySchema5": "ElicitationMultiSelectPropertySchema", + "ElicitationPropertySchema6": "ElicitationOtherPropertySchema", + "MultiSelectItems1": "StringMultiSelectItems", + "MultiSelectItems2": "OtherMultiSelectItems", "ElicitationUrlMode1": "ElicitationUrlSessionMode", "ElicitationUrlMode2": "ElicitationUrlRequestMode", "NesSuggestion1": "NesEditSuggestionVariant", @@ -103,6 +108,21 @@ "NesSuggestion4": "NesSearchAndReplaceSuggestionVariant", } +# Extensible ("custom or future") unions: known const-tagged variants plus a +# catch-all member tagged `"title": "other"`. _normalize_catchall_unions strips the +# discriminator and the catch-all's `not` clause so datamodel-codegen produces a plain +# union; the exclusion is restored at runtime by a field_validator injected into the +# catch-all class, so a malformed known variant fails instead of silently parsing as +# custom (mirrors the TypeScript SDK's excludeKnownTags). Maps union def name -> +# catch-all class name; the set is asserted against the schema in +# _validate_schema_alignment. +EXTENSIBLE_UNIONS: dict[str, str] = { + "CreateElicitationRequest": "CreateOtherElicitationRequest", + "CreateElicitationResponse": "OtherElicitationResponse", + "ElicitationPropertySchema": "ElicitationOtherPropertySchema", + "MultiSelectItems": "OtherMultiSelectItems", +} + ENUM_LITERAL_MAP: dict[str, tuple[str, ...]] = { "PermissionOptionKind": ( "allow_once", @@ -257,10 +277,45 @@ def _load_schema() -> dict[str, Any]: def _preprocess_schema_for_codegen(schema: dict[str, Any]) -> dict[str, Any]: + schema = _normalize_catchall_unions(schema) defs = schema.get("$defs", {}) return _distribute_composed_object_schemas(schema, defs) +def _normalize_catchall_unions(node: Any) -> Any: + # ACP "custom or future" unions include a member tagged `"title": "other"` whose + # discriminator (type/mode/action) is a free-form string. datamodel-codegen cannot + # put that in a discriminated union, so it emits `#-special-#` placeholder literals. + # Drop the discriminator (the union is then validated structurally) and collapse the + # catch-all to a permissive object so unknown variants round-trip their raw payload. + if isinstance(node, list): + return [_normalize_catchall_unions(item) for item in node] + if not isinstance(node, dict): + return node + + transformed = {key: _normalize_catchall_unions(value) for key, value in node.items()} + for combinator in COMBINATOR_KEYS: + members = transformed.get(combinator) + if not isinstance(members, list): + continue + if not any(isinstance(member, dict) and member.get("title") == "other" for member in members): + continue + transformed.pop("discriminator", None) + transformed[combinator] = [ + _collapse_catchall_member(member) if isinstance(member, dict) and member.get("title") == "other" else member + for member in members + ] + return transformed + + +def _collapse_catchall_member(member: dict[str, Any]) -> dict[str, Any]: + collapsed: dict[str, Any] = {"type": "object", "additionalProperties": True} + for key in ("title", "description", "properties", "required"): + if key in member: + collapsed[key] = member[key] + return collapsed + + def _distribute_composed_object_schemas(node: Any, defs: dict[str, Any]) -> Any: if isinstance(node, list): return [_distribute_composed_object_schemas(item, defs) for item in node] @@ -429,6 +484,7 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: _ProcessingStep("attach description comments", _add_description_comments), _ProcessingStep("ensure custom BaseModel", _ensure_custom_base_model), _ProcessingStep("inject field validators", _inject_field_validators), + _ProcessingStep("inject deserialize defaults", _inject_deserialize_defaults), _ProcessingStep("inject schema aliases", _inject_schema_aliases), ) @@ -522,9 +578,29 @@ def _validate_schema_alignment() -> list[str]: warnings.append( f"Enum mismatch for '{enum_name}': schema.json -> {schema_values}, generated aliases -> {expected_values}" ) + + detected_unions = _detect_extensible_unions() + if detected_unions != set(EXTENSIBLE_UNIONS): + warnings.append( + f"Extensible union drift: schema defines {sorted(detected_unions)}, " + f"EXTENSIBLE_UNIONS lists {sorted(EXTENSIBLE_UNIONS)}. Update EXTENSIBLE_UNIONS, the " + "RENAME_MAP catch-all names, and the alias template together." + ) return warnings +def _detect_extensible_unions() -> set[str]: + defs = _load_schema().get("$defs", {}) + detected: set[str] = set() + for name, definition in defs.items(): + if not isinstance(definition, dict) or "discriminator" not in definition: + continue + members = definition.get("anyOf") or definition.get("oneOf") or [] + if any(isinstance(member, dict) and member.get("title") == "other" for member in members): + detected.add(name) + return detected + + def _load_schema_enum_literals() -> dict[str, tuple[str, ...]]: schema_data = json.loads(SCHEMA_JSON.read_text(encoding="utf-8")) defs = schema_data.get("$defs", {}) @@ -600,9 +676,58 @@ def _ensure_pydantic_import(content: str, name: str) -> str: return content +def _extensible_union_excluded_tags(union_def: dict[str, Any], discriminator: str) -> tuple[str, ...]: + members = union_def.get("anyOf") or union_def.get("oneOf") or [] + other = next((member for member in members if isinstance(member, dict) and member.get("title") == "other"), None) + if other is None: + return () + tags: list[str] = [] + for excluded in other.get("not", {}).get("anyOf", []): + const = excluded.get("properties", {}).get(discriminator, {}).get("const") + if isinstance(const, str) and const not in tags: + tags.append(const) + return tuple(tags) + + +def _catchall_exclusion_injections() -> list[FieldValidatorInjection]: + defs = _load_schema().get("$defs", {}) + injections: list[FieldValidatorInjection] = [] + for union_name, catchall_class in EXTENSIBLE_UNIONS.items(): + union_def = defs.get(union_name) + if not isinstance(union_def, dict): + continue + discriminator = union_def.get("discriminator", {}).get("propertyName") + if not discriminator: + continue + tags = _extensible_union_excluded_tags(union_def, discriminator) + if not tags: + continue + field = _schema_field_name(discriminator) + injections.append( + FieldValidatorInjection( + class_name=catchall_class, + field_name=field, + method_name=f"_reject_known_{field}", + argument_name="value", + return_type="Any", + comment_lines=( + "Restore the schema's `not` clause dropped for codegen: reject the known", + "variants' discriminator values so a malformed known variant fails instead", + "of silently parsing as this catch-all.", + ), + body_lines=( + f"if value in {tags!r}:", + f' raise ValueError("{field} value is reserved by a known variant")', + "return value", + ), + ) + ) + return injections + + def _inject_field_validators(content: str) -> str: - """Inject field_validator methods into classes listed in CLASS_VALIDATOR_INJECTIONS.""" - for injection in CLASS_VALIDATOR_INJECTIONS: + """Inject field_validator methods for CLASS_VALIDATOR_INJECTIONS and catch-all exclusions.""" + for injection in (*CLASS_VALIDATOR_INJECTIONS, *_catchall_exclusion_injections()): content = _ensure_pydantic_import(content, "field_validator") class_pattern = re.compile( @@ -627,6 +752,118 @@ def _append_validator( return content +def _inject_deserialize_defaults(content: str) -> str: + defs = _load_schema().get("$defs", {}) + + # `_meta` carries x-deserialize-default-on-error on almost every model; handle it once + # on the shared BaseModel with check_fields=False so every subclass inherits the salvage. + meta_validator = ( + '@field_validator("field_meta", mode="wrap", check_fields=False)\n' + "@classmethod\n" + "def _salvage_meta_on_error(cls, value: Any, handler: Any) -> Any:\n" + " return salvage_on_error(value, handler, lambda: None)\n" + ) + content, count = _append_class_method(content, r"class BaseModel\(_BaseModel\):", meta_validator) + if count == 0: + print("Warning: custom BaseModel not found for _meta salvage injection", file=sys.stderr) + + for class_name, definition in defs.items(): + if not isinstance(definition, dict): + continue + salvage_groups, skip_fields = _deserialize_field_specs(definition) + methods: list[str] = [] + for index, (fallback, fields) in enumerate(sorted(salvage_groups.items())): + arguments = ", ".join(f'"{field}"' for field in sorted(fields)) + methods.append( + f'@field_validator({arguments}, mode="wrap")\n' + "@classmethod\n" + f"def _salvage_on_error_{index}(cls, value: Any, handler: Any) -> Any:\n" + f" return salvage_on_error(value, handler, {fallback})\n" + ) + for index, field in enumerate(sorted(skip_fields)): + methods.append( + f'@field_validator("{field}", mode="wrap")\n' + "@classmethod\n" + f"def _skip_invalid_items_{index}(cls, value: Any, handler: Any) -> Any:\n" + " return skip_invalid_items(value, handler)\n" + ) + # A plain object $def renders as `class Name(BaseModel)` (or `_Name` after a + # collision rename). A union $def has no class of its own; its common properties + # distribute to the member variant classes, so target those instead. + targets = [rf"class _?{re.escape(class_name)}\(BaseModel\):"] + members = _union_member_classes(class_name) + if members: + targets = [rf"class {re.escape(member)}\(\w+\):" for member in members] + for method in methods: + for target in targets: + content, count = _append_class_method(content, target, method) + if count == 0: + print(f"Warning: no class matched {target!r} for deserialize injection", file=sys.stderr) + + content = _ensure_pydantic_import(content, "field_validator") + return _ensure_deserialize_import(content) + + +def _union_member_classes(union_name: str) -> list[str]: + return [new for old, new in RENAME_MAP.items() if re.fullmatch(rf"{re.escape(union_name)}\d+", old)] + + +def _deserialize_field_specs(definition: dict[str, Any]) -> tuple[dict[str, list[str]], list[str]]: + """Return ({fallback_expr: [field, ...]}, [skip_field, ...]) for a $def. `_meta` is handled + on the shared BaseModel and excluded here.""" + required = set(definition.get("required", [])) + salvage: dict[str, list[str]] = {} + skip: list[str] = [] + for prop_name, prop in definition.get("properties", {}).items(): + if not isinstance(prop, dict) or prop_name == "_meta": + continue + field = _schema_field_name(prop_name) + if prop.get("x-deserialize-skip-invalid-items"): + skip.append(field) + elif prop.get("x-deserialize-default-on-error"): + salvage.setdefault(_fallback_expression(prop, prop_name in required), []).append(field) + return salvage, skip + + +def _fallback_expression(prop: dict[str, Any], is_required: bool) -> str: + if "default" in prop: + return f"lambda: {prop['default']!r}" + if _is_array_schema(prop) and (is_required or not _schema_allows_null(prop, {})): + return "lambda: []" + return "lambda: None" + + +def _is_array_schema(prop: dict[str, Any]) -> bool: + prop_type = prop.get("type") + if prop_type == "array" or (isinstance(prop_type, list) and "array" in prop_type): + return True + return "items" in prop + + +def _append_class_method(content: str, header_pattern: str, method_text: str) -> tuple[str, int]: + pattern = re.compile(rf"({header_pattern})(.*?)(?=\nclass |\Z)", re.DOTALL) + + def _append(match: re.Match[str]) -> str: + indented = "\n" + textwrap.indent(method_text, " ") + return match.group(1) + match.group(2) + indented + "\n" + + return pattern.subn(_append, content, count=1) + + +def _ensure_deserialize_import(content: str) -> str: + # Absolute import (not relative): gen_signature.py loads schema.py as a standalone + # module with no package context, where `from ._deserialize` cannot resolve. + statement = "from acp._deserialize import salvage_on_error, skip_invalid_items" + if statement in content: + return content + lines = content.splitlines() + for idx, line in enumerate(lines): + if line.startswith("from pydantic import "): + lines.insert(idx + 1, statement) + return "\n".join(lines) + "\n" + return content + + def _inject_schema_aliases(content: str) -> str: if "CreateElicitationRequest = Union[" in content: return content @@ -649,11 +886,13 @@ def _inject_schema_aliases(content: str) -> str: CreateElicitationRequest = Union[ CreateFormElicitationRequest, CreateUrlElicitationRequest, + CreateOtherElicitationRequest, ] CreateElicitationResponse = Union[ AcceptElicitationResponse, DeclineElicitationResponse, CancelElicitationResponse, + OtherElicitationResponse, ] """) pattern = re.compile( diff --git a/src/acp/__init__.py b/src/acp/__init__.py index d343529..e6cd484 100644 --- a/src/acp/__init__.py +++ b/src/acp/__init__.py @@ -49,6 +49,7 @@ CreateFormElicitationRequest, CreateFormRequestElicitationRequest, CreateFormSessionElicitationRequest, + CreateOtherElicitationRequest, CreateTerminalRequest, CreateTerminalResponse, CreateUrlElicitationRequest, @@ -64,6 +65,7 @@ ElicitationMode, ElicitationMultiSelectPropertySchema, ElicitationNumberPropertySchema, + ElicitationOtherPropertySchema, ElicitationSchema, ElicitationStringPropertySchema, ElicitationUrlCapabilities, @@ -77,6 +79,7 @@ LoadSessionResponse, NewSessionRequest, NewSessionResponse, + OtherElicitationResponse, PromptRequest, PromptResponse, ReadTextFileRequest, @@ -156,6 +159,7 @@ "ElicitationIntegerPropertySchema", "ElicitationBooleanPropertySchema", "ElicitationMultiSelectPropertySchema", + "ElicitationOtherPropertySchema", "CreateElicitationRequest", "CreateElicitationResponse", "CreateFormElicitationRequest", @@ -164,9 +168,11 @@ "CreateUrlElicitationRequest", "CreateUrlSessionElicitationRequest", "CreateUrlRequestElicitationRequest", + "CreateOtherElicitationRequest", "AcceptElicitationResponse", "DeclineElicitationResponse", "CancelElicitationResponse", + "OtherElicitationResponse", "CompleteElicitationNotification", # terminal types "CreateTerminalRequest", diff --git a/src/acp/_deserialize.py b/src/acp/_deserialize.py new file mode 100644 index 0000000..1cc2ea9 --- /dev/null +++ b/src/acp/_deserialize.py @@ -0,0 +1,43 @@ +"""Runtime helpers that restore the lenient-deserialization semantics the ACP schema +declares via ``x-deserialize-default-on-error`` and ``x-deserialize-skip-invalid-items`` +but that generated Pydantic models cannot express directly. + +Referenced by ``field_validator`` methods that ``scripts/gen_schema.py`` injects into +``schema.py``. Mirrors the TypeScript SDK's ``src/schema-deserialize.ts``. +""" + +from __future__ import annotations + +from collections.abc import Callable +from typing import Any + +from pydantic import ValidationError + + +def salvage_on_error(value: Any, handler: Callable[[Any], Any], fallback: Callable[[], Any]) -> Any: + """Return ``fallback()`` when ``value`` fails validation, otherwise the validated value. + + Restores ``x-deserialize-default-on-error``: a malformed non-critical field is replaced + with its default rather than failing the whole payload. + """ + try: + return handler(value) + except ValidationError: + return fallback() + + +def skip_invalid_items(value: Any, handler: Callable[[Any], Any]) -> Any: + """Drop array items that fail validation instead of failing the whole array. + + Restores ``x-deserialize-skip-invalid-items``. Each item is validated through the field's + own list handler, so item coercion and salvaging still apply to the survivors. + """ + if not isinstance(value, list): + return handler(value) + salvaged: list[Any] = [] + for item in value: + try: + salvaged.append(handler([item])[0]) + except ValidationError: + continue + return salvaged diff --git a/src/acp/client/router.py b/src/acp/client/router.py index c8b26bb..204a67b 100644 --- a/src/acp/client/router.py +++ b/src/acp/client/router.py @@ -11,11 +11,9 @@ from ..schema import ( CompleteElicitationNotification, CreateElicitationRequest, - CreateFormElicitationRequest, CreateFormRequestElicitationRequest, CreateFormSessionElicitationRequest, CreateTerminalRequest, - CreateUrlElicitationRequest, CreateUrlRequestElicitationRequest, CreateUrlSessionElicitationRequest, ElicitationFormRequestMode, @@ -37,12 +35,12 @@ _CREATE_ELICITATION_REQUEST_ADAPTER = TypeAdapter(CreateElicitationRequest) -def _validate_create_elicitation_request(params: Any) -> CreateFormElicitationRequest | CreateUrlElicitationRequest: +def _validate_create_elicitation_request(params: Any) -> CreateElicitationRequest: return _CREATE_ELICITATION_REQUEST_ADAPTER.validate_python(params) def _mode_from_create_elicitation_request( - request: CreateFormElicitationRequest | CreateUrlElicitationRequest, + request: CreateElicitationRequest, ) -> ElicitationFormSessionMode | ElicitationFormRequestMode | ElicitationUrlSessionMode | ElicitationUrlRequestMode: if isinstance(request, CreateFormSessionElicitationRequest): return ElicitationFormSessionMode( @@ -69,7 +67,7 @@ def _mode_from_create_elicitation_request( elicitation_id=request.elicitation_id, url=request.url, ) - raise TypeError(f"Unsupported elicitation request: {type(request).__name__}") + raise RequestError.invalid_params({"details": f"Unsupported elicitation mode: {request.mode!r}"}) def _make_create_elicitation_handler(client: Client) -> Any: diff --git a/src/acp/meta.py b/src/acp/meta.py index a7bd914..9c883c5 100644 --- a/src/acp/meta.py +++ b/src/acp/meta.py @@ -1,5 +1,5 @@ # Generated from schema/meta.json. Do not edit by hand. -# Schema ref: refs/tags/schema-v1.16.0 +# Schema ref: refs/tags/schema-v1.19.0 AGENT_METHODS = { "initialize": "initialize", "authenticate": "authenticate", diff --git a/src/acp/schema.py b/src/acp/schema.py index 6b74f46..e2dd1f1 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -1,12 +1,13 @@ # Generated from schema/schema.json. Do not edit by hand. -# Schema ref: refs/tags/schema-v1.16.0 +# Schema ref: refs/tags/schema-v1.19.0 from __future__ import annotations from enum import Enum from typing import Annotated, Any, Dict, List, Literal, Optional, Union -from pydantic import AnyUrl, BaseModel as _BaseModel, Field, RootModel, ConfigDict, field_validator +from pydantic import AnyUrl, BaseModel as _BaseModel, ConfigDict, Field, RootModel, field_validator +from acp._deserialize import salvage_on_error, skip_invalid_items PermissionOptionKind = Literal["allow_once", "allow_always", "reject_once", "reject_always"] PlanEntryPriority = Literal["high", "medium", "low"] @@ -25,6 +26,11 @@ def __getattr__(self, item: str) -> Any: return getattr(self, snake_cased) raise AttributeError(f"'{type(self).__name__}' object has no attribute '{item}'") + @field_validator("field_meta", mode="wrap", check_fields=False) + @classmethod + def _salvage_meta_on_error(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class Jsonrpc(Enum): field_2_0 = "2.0" @@ -55,6 +61,11 @@ class ReadTextFileRequest(BaseModel): ), ] = None + @field_validator("limit", "line", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class TextResourceContents(BaseModel): # MIME type describing the encoded media payload. @@ -82,6 +93,11 @@ class TextResourceContents(BaseModel): ), ] = None + @field_validator("mime_type", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class BlobResourceContents(BaseModel): # Base64-encoded bytes for a binary resource payload. @@ -109,10 +125,15 @@ class BlobResourceContents(BaseModel): ), ] = None + @field_validator("mime_type", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class Diff(BaseModel): - # The file path being modified. - path: Annotated[str, Field(description="The file path being modified.")] + # The absolute file path being modified. + path: Annotated[str, Field(description="The absolute file path being modified.")] # The original content (None for new files). old_text: Annotated[ Optional[str], @@ -133,6 +154,11 @@ class Diff(BaseModel): ), ] = None + @field_validator("old_text", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class Terminal(BaseModel): # Identifier of the terminal instance to embed in the content stream. @@ -158,8 +184,8 @@ class Terminal(BaseModel): class ToolCallLocation(BaseModel): - # The file path being accessed or modified. - path: Annotated[str, Field(description="The file path being accessed or modified.")] + # The absolute file path being accessed or modified. + path: Annotated[str, Field(description="The absolute file path being accessed or modified.")] # Optional line number within the file. line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -175,6 +201,11 @@ class ToolCallLocation(BaseModel): ), ] = None + @field_validator("line", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class EnvVariable(BaseModel): # The name of the environment variable. @@ -277,6 +308,50 @@ class KillTerminalRequest(BaseModel): ] = None +class CreateOtherElicitationRequest(BaseModel): + model_config = ConfigDict( + extra="allow", + ) + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Custom or future elicitation mode. + # + # Values beginning with `_` are reserved for implementation-specific + # extensions. Unknown values that do not begin with `_` are reserved for + # future ACP variants. + mode: Annotated[ + str, + Field( + description="Custom or future elicitation mode.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." + ), + ] + + @field_validator("mode", mode="before") + @classmethod + def _reject_known_mode(cls, value: Any) -> Any: + # Restore the schema's `not` clause dropped for codegen: reject the known + # variants' discriminator values so a malformed known variant fails instead + # of silently parsing as this catch-all. + if value in ("form", "url"): + raise ValueError("mode value is reserved by a known variant") + return value + + class ElicitationSessionScope(BaseModel): # The session this elicitation is tied to. session_id: Annotated[ @@ -289,6 +364,11 @@ class ElicitationSessionScope(BaseModel): Field(alias="toolCallId", description="Optional tool call within the session."), ] = None + @field_validator("tool_call_id", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ElicitationRequestScope(BaseModel): # The request this elicitation is tied to. @@ -298,11 +378,40 @@ class ElicitationRequestScope(BaseModel): ] +class ElicitationOtherPropertySchema(BaseModel): + model_config = ConfigDict( + extra="allow", + ) + # Custom or future elicitation property schema type. + # + # Values beginning with `_` are reserved for implementation-specific + # extensions. Unknown values that do not begin with `_` are reserved for + # future ACP variants. + type: Annotated[ + str, + Field( + description="Custom or future elicitation property schema type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." + ), + ] + + @field_validator("type", mode="before") + @classmethod + def _reject_known_type(cls, value: Any) -> Any: + # Restore the schema's `not` clause dropped for codegen: reject the known + # variants' discriminator values so a malformed known variant fails instead + # of silently parsing as this catch-all. + if value in ("string", "number", "integer", "boolean", "array"): + raise ValueError("type value is reserved by a known variant") + return value + + class EnumOption(BaseModel): # The constant value for this option. const: Annotated[str, Field(description="The constant value for this option.")] # Human-readable title for this option. title: Annotated[str, Field(description="Human-readable title for this option.")] + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -316,6 +425,11 @@ class EnumOption(BaseModel): ), ] = None + @field_validator("description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class StringPropertySchema(BaseModel): # Optional title for the property. @@ -364,6 +478,11 @@ class StringPropertySchema(BaseModel): ), ] = None + @field_validator("default", "description", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NumberPropertySchema(BaseModel): # Optional title for the property. @@ -389,6 +508,11 @@ class NumberPropertySchema(BaseModel): ), ] = None + @field_validator("default", "description", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class IntegerPropertySchema(BaseModel): # Optional title for the property. @@ -414,6 +538,11 @@ class IntegerPropertySchema(BaseModel): ), ] = None + @field_validator("default", "description", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class BooleanPropertySchema(BaseModel): # Optional title for the property. @@ -435,6 +564,55 @@ class BooleanPropertySchema(BaseModel): ), ] = None + @field_validator("default", "description", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + +class OtherMultiSelectItems(BaseModel): + model_config = ConfigDict( + extra="allow", + ) + # Custom or future multi-select item type. + # + # Values beginning with `_` are reserved for implementation-specific + # extensions. Unknown values that do not begin with `_` are reserved for + # future ACP variants. + type: Annotated[ + str, + Field( + description="Custom or future multi-select item type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." + ), + ] + + @field_validator("type", mode="before") + @classmethod + def _reject_known_type(cls, value: Any) -> Any: + # Restore the schema's `not` clause dropped for codegen: reject the known + # variants' discriminator values so a malformed known variant fails instead + # of silently parsing as this catch-all. + if value in ("string",): + raise ValueError("type value is reserved by a known variant") + return value + + +class _StringMultiSelectItems(BaseModel): + # Allowed enum values. + enum: Annotated[List[str], Field(description="Allowed enum values.")] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + class TitledMultiSelectItems(BaseModel): # Titled enum options. @@ -542,6 +720,11 @@ class PromptCapabilities(BaseModel): ), ] = None + @field_validator("audio", "embedded_context", "image", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + class McpCapabilities(BaseModel): # Agent supports [`McpServer::Http`]. @@ -572,6 +755,11 @@ class McpCapabilities(BaseModel): ), ] = None + @field_validator("acp", "http", "sse", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + class SessionListCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -776,6 +964,11 @@ class NesRecentFilesCapabilities(BaseModel): ), ] = None + @field_validator("max_count", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesRelatedSnippetsCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -815,6 +1008,11 @@ class NesEditHistoryCapabilities(BaseModel): ), ] = None + @field_validator("max_count", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesUserActionsCapabilities(BaseModel): # Maximum number of user actions the agent can use. @@ -839,6 +1037,11 @@ class NesUserActionsCapabilities(BaseModel): ), ] = None + @field_validator("max_count", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesOpenFilesCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -911,6 +1114,21 @@ class AuthEnvVar(BaseModel): ), ] = None + @field_validator("optional", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + + @field_validator("label", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("secret", mode="wrap") + @classmethod + def _salvage_on_error_2(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: True) + class AuthMethodEnvVar(BaseModel): # Unique identifier for this authentication method. @@ -945,6 +1163,16 @@ class AuthMethodEnvVar(BaseModel): ), ] = None + @field_validator("description", "link", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("vars", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class AuthMethodTerminal(BaseModel): # Unique identifier for this authentication method. @@ -979,6 +1207,16 @@ class AuthMethodTerminal(BaseModel): ), ] = None + @field_validator("description", "env", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("args", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class AuthMethodAgent(BaseModel): # Unique identifier for this authentication method. @@ -1003,6 +1241,11 @@ class AuthMethodAgent(BaseModel): ), ] = None + @field_validator("description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class Implementation(BaseModel): # Intended for programmatic or logical use, but can be used as a display @@ -1044,6 +1287,11 @@ class Implementation(BaseModel): ), ] = None + @field_validator("title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AuthenticateResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1063,7 +1311,7 @@ class AuthenticateResponse(BaseModel): class ProviderCurrentConfig(BaseModel): # Protocol currently used by this provider. api_type: Annotated[ - str, + Union[str, Dict[str, Any]], Field(alias="apiType", description="Protocol currently used by this provider."), ] # Base URL currently used by this provider. @@ -1156,6 +1404,11 @@ class SessionMode(BaseModel): ), ] = None + @field_validator("description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class SessionConfigSelectOption(BaseModel): # Unique identifier for this option value. @@ -1177,6 +1430,11 @@ class SessionConfigSelectOption(BaseModel): ), ] = None + @field_validator("description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class SessionConfigBoolean(BaseModel): # The current value of the boolean option. @@ -1226,6 +1484,16 @@ class SessionInfo(BaseModel): ), ] = None + @field_validator("title", "updated_at", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("additional_directories", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class DeleteSessionResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1328,6 +1596,11 @@ class Usage(BaseModel): ), ] = None + @field_validator("cached_read_tokens", "cached_write_tokens", "thought_tokens", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class StartNesResponse(BaseModel): # The session ID for the newly started NES session. @@ -1466,7 +1739,7 @@ class CloseNesResponse(BaseModel): class PlanFile(BaseModel): # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] + plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] # The URI of the file containing the plan. uri: Annotated[str, Field(description="The URI of the file containing the plan.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1485,7 +1758,7 @@ class PlanFile(BaseModel): class PlanMarkdown(BaseModel): # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] + plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] # Markdown content for the plan. content: Annotated[str, Field(description="Markdown content for the plan.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1504,7 +1777,7 @@ class PlanMarkdown(BaseModel): class PlanRemoved(BaseModel): # The plan ID to remove. - id: Annotated[str, Field(description="The plan ID to remove.")] + plan_id: Annotated[str, Field(alias="planId", description="The plan ID to remove.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -1583,6 +1856,11 @@ class _SessionInfoUpdate(BaseModel): ), ] = None + @field_validator("title", "updated_at", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class Cost(BaseModel): # Total cumulative cost for session. @@ -1623,6 +1901,11 @@ class _UsageUpdate(BaseModel): ), ] = None + @field_validator("cost", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class CompleteElicitationNotification(BaseModel): # The ID of the elicitation that completed. @@ -1680,6 +1963,11 @@ class MessageMcpNotification(BaseModel): ), ] = None + @field_validator("params", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class FileSystemCapabilities(BaseModel): # Whether the Client supports `fs/read_text_file` requests. @@ -1711,6 +1999,11 @@ class FileSystemCapabilities(BaseModel): ), ] = None + @field_validator("read_text_file", "write_text_file", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + class BooleanConfigOptionCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1765,6 +2058,11 @@ class AuthCapabilities(BaseModel): ), ] = None + @field_validator("terminal", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + class ElicitationFormCapabilities(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -1881,10 +2179,13 @@ class ListProvidersRequest(BaseModel): class SetProviderRequest(BaseModel): - # Provider id to configure. - id: Annotated[str, Field(description="Provider id to configure.")] + # Provider ID to configure. + provider_id: Annotated[str, Field(alias="providerId", description="Provider ID to configure.")] # Protocol type for this provider. - api_type: Annotated[str, Field(alias="apiType", description="Protocol type for this provider.")] + api_type: Annotated[ + Union[str, Dict[str, Any]], + Field(alias="apiType", description="Protocol type for this provider."), + ] # Base URL for requests sent through this provider. base_url: Annotated[ str, @@ -1916,8 +2217,8 @@ class SetProviderRequest(BaseModel): class DisableProviderRequest(BaseModel): - # Provider id to disable. - id: Annotated[str, Field(description="Provider id to disable.")] + # Provider ID to disable. + provider_id: Annotated[str, Field(alias="providerId", description="Provider ID to disable.")] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -2021,10 +2322,11 @@ class McpServerAcp(BaseModel): # # Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible # on the same ACP connection. - id: Annotated[ + server_id: Annotated[ str, Field( - description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection." + alias="serverId", + description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection.", ), ] # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -2044,8 +2346,8 @@ class McpServerAcp(BaseModel): class McpServerStdio(BaseModel): # Human-readable name identifying this MCP server. name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # Path to the MCP server executable. - command: Annotated[str, Field(description="Path to the MCP server executable.")] + # Absolute path to the MCP server executable. + command: Annotated[str, Field(description="Absolute path to the MCP server executable.")] # Command-line arguments to pass to the MCP server. args: Annotated[ List[str], @@ -2486,6 +2788,11 @@ class TerminalExitStatus(BaseModel): ), ] = None + @field_validator("exit_code", "signal", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ReleaseTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -2530,6 +2837,11 @@ class WaitForTerminalExitResponse(BaseModel): ), ] = None + @field_validator("exit_code", "signal", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class KillTerminalResponse(BaseModel): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -2578,6 +2890,45 @@ class CancelElicitationResponse(BaseModel): action: Literal["cancel"] +class OtherElicitationResponse(BaseModel): + model_config = ConfigDict( + extra="allow", + ) + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + # Custom or future elicitation action. + # + # Values beginning with `_` are reserved for implementation-specific + # extensions. Unknown values that do not begin with `_` are reserved for + # future ACP variants. + action: Annotated[ + str, + Field( + description="Custom or future elicitation action.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." + ), + ] + + @field_validator("action", mode="before") + @classmethod + def _reject_known_action(cls, value: Any) -> Any: + # Restore the schema's `not` clause dropped for codegen: reject the known + # variants' discriminator values so a malformed known variant fails instead + # of silently parsing as this catch-all. + if value in ("accept", "decline", "cancel"): + raise ValueError("action value is reserved by a known variant") + return value + + class ElicitationContentValue(RootModel[Union[str, int, float, bool, List[str]]]): # Allowed wire representations for [`ElicitationContentValue`]. root: Annotated[ @@ -2836,6 +3187,16 @@ class Annotations(BaseModel): ), ] = None + @field_validator("last_modified", "priority", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("audience", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class TextContent(BaseModel): # Optional annotations that help clients decide how to display or route this content. @@ -2858,6 +3219,11 @@ class TextContent(BaseModel): ), ] = None + @field_validator("annotations", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ImageContent(BaseModel): # Optional annotations that help clients decide how to display or route this content. @@ -2893,6 +3259,11 @@ class ImageContent(BaseModel): ), ] = None + @field_validator("annotations", "uri", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AudioContent(BaseModel): # Optional annotations that help clients decide how to display or route this content. @@ -2923,6 +3294,11 @@ class AudioContent(BaseModel): ), ] = None + @field_validator("annotations", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ResourceLink(BaseModel): # Optional annotations that help clients decide how to display or route this content. @@ -2967,6 +3343,11 @@ class ResourceLink(BaseModel): ), ] = None + @field_validator("annotations", "description", "mime_type", "size", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class EmbeddedResource(BaseModel): # Optional annotations that help clients decide how to display or route this content. @@ -2992,6 +3373,11 @@ class EmbeddedResource(BaseModel): ), ] = None + @field_validator("annotations", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class PermissionOption(BaseModel): # Unique identifier for this permission option. @@ -3032,10 +3418,10 @@ class CreateTerminalRequest(BaseModel): Optional[List[EnvVariable]], Field(description="Environment variables for the command."), ] = None - # Working directory for the command (absolute path). + # Working directory for the command. Must be an absolute path. cwd: Annotated[ Optional[str], - Field(description="Working directory for the command (absolute path)."), + Field(description="Working directory for the command. Must be an absolute path."), ] = None # Maximum number of output bytes to retain. # @@ -3066,6 +3452,21 @@ class CreateTerminalRequest(BaseModel): ), ] = None + @field_validator("cwd", "output_byte_limit", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("args", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("env", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class CreateUrlSessionElicitationRequest(ElicitationSessionScope): # A human-readable message describing what input is needed. @@ -3145,11 +3546,32 @@ class ElicitationBooleanPropertySchema(BooleanPropertySchema): type: Literal["boolean"] -class UntitledMultiSelectItems(BaseModel): - # Item type discriminator. Must be `"string"`. - type: Annotated[str, Field(description='Item type discriminator. Must be `"string"`.')] - # Allowed enum values. - enum: Annotated[List[str], Field(description="Allowed enum values.")] +class StringMultiSelectItems(_StringMultiSelectItems): + type: Literal["string"] + + +class MultiSelectPropertySchema(BaseModel): + # Optional title for the property. + title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None + # Human-readable description. + description: Annotated[Optional[str], Field(description="Human-readable description.")] = None + # Minimum number of items to select. + min_items: Annotated[ + Optional[int], + Field(alias="minItems", description="Minimum number of items to select.", ge=0), + ] = None + # Maximum number of items to select. + max_items: Annotated[ + Optional[int], + Field(alias="maxItems", description="Maximum number of items to select.", ge=0), + ] = None + # The items definition describing allowed values. + items: Annotated[ + Union[StringMultiSelectItems, OtherMultiSelectItems, TitledMultiSelectItems], + Field(description="The items definition describing allowed values."), + ] + # Default selected values. + default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -3163,13 +3585,23 @@ class UntitledMultiSelectItems(BaseModel): ), ] = None + @field_validator("description", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("default", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ConnectMcpRequest(BaseModel): # The ACP MCP server ID that was provided by the component declaring the MCP server. - acp_id: Annotated[ + server_id: Annotated[ str, Field( - alias="acpId", + alias="serverId", description="The ACP MCP server ID that was provided by the component declaring the MCP server.", ), ] @@ -3223,9 +3655,14 @@ class MessageMcpRequest(BaseModel): class SessionCapabilities(BaseModel): # Whether the agent supports `session/list`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports listing sessions. list: Annotated[ Optional[SessionListCapabilities], - Field(description="Whether the agent supports `session/list`."), + Field( + description="Whether the agent supports `session/list`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports listing sessions." + ), ] = None # Whether the agent supports `session/delete`. # @@ -3239,6 +3676,10 @@ class SessionCapabilities(BaseModel): ] = None # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports `additionalDirectories` on + # supported session lifecycle requests. + # # Agents that also support `session/list` may return # `SessionInfo.additionalDirectories` to report the complete ordered # additional-root list associated with a listed session. @@ -3246,7 +3687,7 @@ class SessionCapabilities(BaseModel): Optional[SessionAdditionalDirectoriesCapabilities], Field( alias="additionalDirectories", - description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", + description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports `additionalDirectories` on\nsupported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", ), ] = None # **UNSTABLE** @@ -3254,21 +3695,34 @@ class SessionCapabilities(BaseModel): # This capability is not part of the spec yet, and may be removed or changed at any point. # # Whether the agent supports `session/fork`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports forking sessions. fork: Annotated[ Optional[SessionForkCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports forking sessions." ), ] = None # Whether the agent supports `session/resume`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports resuming sessions. resume: Annotated[ Optional[SessionResumeCapabilities], - Field(description="Whether the agent supports `session/resume`."), + Field( + description="Whether the agent supports `session/resume`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports resuming sessions." + ), ] = None # Whether the agent supports `session/close`. + # + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports closing sessions. close: Annotated[ Optional[SessionCloseCapabilities], - Field(description="Whether the agent supports `session/close`."), + Field( + description="Whether the agent supports `session/close`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports closing sessions." + ), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3283,15 +3737,21 @@ class SessionCapabilities(BaseModel): ), ] = None + @field_validator("additional_directories", "close", "delete", "fork", "list", "resume", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AgentAuthCapabilities(BaseModel): # Whether the agent supports the logout method. # - # By supplying `{}` it means that the agent supports the logout method. + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports the logout method. logout: Annotated[ Optional[LogoutCapabilities], Field( - description="Whether the agent supports the logout method.\n\nBy supplying `{}` it means that the agent supports the logout method." + description="Whether the agent supports the logout method.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports the logout method." ), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -3307,6 +3767,11 @@ class AgentAuthCapabilities(BaseModel): ), ] = None + @field_validator("logout", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesDocumentDidChangeCapabilities(BaseModel): # The sync kind the agent wants: `"full"` or `"incremental"`. @@ -3387,6 +3852,13 @@ class NesContextCapabilities(BaseModel): ), ] = None + @field_validator( + "diagnostics", "edit_history", "open_files", "recent_files", "related_snippets", "user_actions", mode="wrap" + ) + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class EnvVarAuthMethod(AuthMethodEnvVar): type: Literal["env_var"] @@ -3398,15 +3870,24 @@ class TerminalAuthMethod(AuthMethodTerminal): class ProviderInfo(BaseModel): # Provider identifier, for example "main" or "openai". - id: Annotated[str, Field(description='Provider identifier, for example "main" or "openai".')] + provider_id: Annotated[ + str, + Field( + alias="providerId", + description='Provider identifier, for example "main" or "openai".', + ), + ] # Supported protocol types for this provider. - supported: Annotated[List[str], Field(description="Supported protocol types for this provider.")] + supported: Annotated[ + List[Union[str, Dict[str, Any]]], + Field(description="Supported protocol types for this provider."), + ] # Whether this provider is mandatory and cannot be disabled via `providers/disable`. - # If true, clients must not call `providers/disable` for this id. + # If true, clients must not call `providers/disable` for this provider ID. required: Annotated[ bool, Field( - description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this id." + description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this provider ID." ), ] # Current effective non-secret routing config. @@ -3428,6 +3909,11 @@ class ProviderInfo(BaseModel): ), ] = None + @field_validator("supported", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class SessionModeState(BaseModel): # The current mode the Agent is in. @@ -3456,6 +3942,11 @@ class SessionModeState(BaseModel): ), ] = None + @field_validator("available_modes", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class SessionConfigOptionBoolean(SessionConfigBoolean): # Unique identifier for the configuration option. @@ -3469,7 +3960,7 @@ class SessionConfigOptionBoolean(SessionConfigBoolean): ] = None # Optional semantic category for this option (UX only). category: Annotated[ - Optional[str], + Optional[Union[str, Dict[str, Any]]], Field(description="Optional semantic category for this option (UX only)."), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -3486,6 +3977,11 @@ class SessionConfigOptionBoolean(SessionConfigBoolean): ] = None type: Literal["boolean"] + @field_validator("category", "description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class SessionConfigSelectGroup(BaseModel): # Unique identifier for this group. @@ -3510,6 +4006,11 @@ class SessionConfigSelectGroup(BaseModel): ), ] = None + @field_validator("options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ListSessionsResponse(BaseModel): # Array of session information objects @@ -3536,6 +4037,16 @@ class ListSessionsResponse(BaseModel): ), ] = None + @field_validator("next_cursor", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("sessions", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class PromptResponse(BaseModel): # Indicates why the agent stopped processing the turn. @@ -3570,6 +4081,11 @@ class PromptResponse(BaseModel): ), ] = None + @field_validator("usage", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesJumpSuggestionVariant(NesJumpSuggestion): kind: Literal["jump"] @@ -3628,6 +4144,11 @@ class Error(BaseModel): ), ] = None + @field_validator("data", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AgentPlanRemovedUpdate(PlanRemoved): session_update: Annotated[Literal["plan_removed"], Field(alias="sessionUpdate")] @@ -3699,6 +4220,11 @@ class Plan(BaseModel): ), ] = None + @field_validator("entries", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class PlanUpdateFile(PlanFile): type: Literal["file"] @@ -3710,7 +4236,7 @@ class PlanUpdateMarkdown(PlanMarkdown): class PlanItems(BaseModel): # The plan ID to update. - id: Annotated[str, Field(description="The plan ID to update.")] + plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] # The list of tasks to be accomplished. # # When updating an item-based plan, the agent must send a complete list of all entries @@ -3734,6 +4260,11 @@ class PlanItems(BaseModel): ), ] = None + @field_validator("entries", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class AvailableCommandInput(RootModel[UnstructuredCommandInput]): # The input specification for a command. @@ -3746,14 +4277,14 @@ class AvailableCommandInput(RootModel[UnstructuredCommandInput]): class SessionConfigOptionsCapabilities(BaseModel): # Whether the client supports boolean session configuration options. # - # Omitted or `null` means the client does not advertise support. + # Optional. Omitted or `null` both mean the client does not advertise support. # Supplying `{}` means agents may include `type: "boolean"` entries in # `configOptions`, and the client may send `session/set_config_option` # requests with `type: "boolean"` and a boolean `value`. boolean: Annotated[ Optional[BooleanConfigOptionCapabilities], Field( - description='Whether the client supports boolean session configuration options.\n\nOmitted or `null` means the client does not advertise support.\nSupplying `{}` means agents may include `type: "boolean"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: "boolean"` and a boolean `value`.' + description='Whether the client supports boolean session configuration options.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means agents may include `type: "boolean"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: "boolean"` and a boolean `value`.' ), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -3769,17 +4300,32 @@ class SessionConfigOptionsCapabilities(BaseModel): ), ] = None + @field_validator("boolean", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ElicitationCapabilities(BaseModel): # Whether the client supports form-based elicitation. + # + # Optional. Omitted or `null` both mean the client does not advertise support. + # Supplying `{}` means the client supports form-based elicitation. form: Annotated[ Optional[ElicitationFormCapabilities], - Field(description="Whether the client supports form-based elicitation."), + Field( + description="Whether the client supports form-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports form-based elicitation." + ), ] = None # Whether the client supports URL-based elicitation. + # + # Optional. Omitted or `null` both mean the client does not advertise support. + # Supplying `{}` means the client supports URL-based elicitation. url: Annotated[ Optional[ElicitationUrlCapabilities], - Field(description="Whether the client supports URL-based elicitation."), + Field( + description="Whether the client supports URL-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports URL-based elicitation." + ), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at @@ -3794,6 +4340,11 @@ class ElicitationCapabilities(BaseModel): ), ] = None + @field_validator("form", "url", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ClientNesCapabilities(BaseModel): # Whether the client supports the `jump` suggestion kind. @@ -3827,6 +4378,11 @@ class ClientNesCapabilities(BaseModel): ), ] = None + @field_validator("jump", "rename", "search_and_replace", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class HttpMcpServer(McpServerHttp): type: Literal["http"] @@ -3849,8 +4405,11 @@ class LoadSessionRequest(BaseModel): description="List of MCP servers to connect to for this session.", ), ] - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -3879,12 +4438,25 @@ class LoadSessionRequest(BaseModel): ), ] = None + @field_validator("additional_directories", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("mcp_servers", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ForkSessionRequest(BaseModel): # The ID of the session to fork. session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -3918,12 +4490,25 @@ class ForkSessionRequest(BaseModel): ), ] = None + @field_validator("additional_directories", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("mcp_servers", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ResumeSessionRequest(BaseModel): # The ID of the session to resume. session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] - # The working directory for this session. - cwd: Annotated[str, Field(description="The working directory for this session.")] + # The working directory for this session. Must be an absolute path. + cwd: Annotated[ + str, + Field(description="The working directory for this session. Must be an absolute path."), + ] # Additional workspace roots to activate for this session. Each path must be absolute. # # When omitted or empty, no additional roots are activated. When non-empty, @@ -3958,6 +4543,16 @@ class ResumeSessionRequest(BaseModel): ), ] = None + @field_validator("additional_directories", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("mcp_servers", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class StartNesRequest(BaseModel): # The root URI of the workspace. @@ -3988,6 +4583,11 @@ class StartNesRequest(BaseModel): ), ] = None + @field_validator("repository", "workspace_uri", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesRelatedSnippet(BaseModel): # The URI of the file containing the snippets. @@ -4040,6 +4640,11 @@ class NesOpenFile(BaseModel): ), ] = None + @field_validator("last_focused_ms", "visible_range", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NesDiagnostic(BaseModel): # The URI of the file containing the diagnostic. @@ -4101,6 +4706,11 @@ class TerminalOutputResponse(BaseModel): ), ] = None + @field_validator("exit_status", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AcceptElicitationResponse(ElicitationAcceptAction): # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -4200,6 +4810,11 @@ class RejectNesNotification(BaseModel): ), ] = None + @field_validator("reason", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class TextContentBlock(TextContent): type: Literal["text"] @@ -4243,40 +4858,8 @@ class Content(BaseModel): ] = None -class MultiSelectPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Minimum number of items to select. - min_items: Annotated[ - Optional[int], - Field(alias="minItems", description="Minimum number of items to select.", ge=0), - ] = None - # Maximum number of items to select. - max_items: Annotated[ - Optional[int], - Field(alias="maxItems", description="Maximum number of items to select.", ge=0), - ] = None - # The items definition describing allowed values. - items: Annotated[ - Union[UntitledMultiSelectItems, TitledMultiSelectItems], - Field(description="The items definition describing allowed values."), - ] - # Default selected values. - default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None +class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): + type: Literal["array"] class AgentErrorMessage(BaseModel): @@ -4343,6 +4926,11 @@ class NesDocumentEventCapabilities(BaseModel): ), ] = None + @field_validator("did_change", "did_close", "did_focus", "did_open", "did_save", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class ListProvidersResponse(BaseModel): # Configurable providers with current routing info suitable for UI display. @@ -4421,6 +5009,11 @@ class NesEditSuggestion(BaseModel): ), ] = None + @field_validator("cursor_position", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class AgentPlanUpdate(Plan): session_update: Annotated[Literal["plan"], Field(alias="sessionUpdate")] @@ -4458,6 +5051,11 @@ class ContentChunk(BaseModel): ), ] = None + @field_validator("message_id", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class PlanUpdateItems(PlanItems): type: Literal["items"] @@ -4509,6 +5107,11 @@ class AvailableCommand(BaseModel): ), ] = None + @field_validator("input", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class _AvailableCommandsUpdate(BaseModel): # Commands the agent can execute @@ -4529,17 +5132,22 @@ class _AvailableCommandsUpdate(BaseModel): ), ] = None + @field_validator("available_commands", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ClientSessionCapabilities(BaseModel): # Config option capabilities supported by the client. # - # Omitted or `null` means the client does not advertise support for any + # Omitted or `null` both mean the client does not advertise support for any # config option extensions. config_options: Annotated[ Optional[SessionConfigOptionsCapabilities], Field( alias="configOptions", - description="Config option capabilities supported by the client.\n\nOmitted or `null` means the client does not advertise support for any\nconfig option extensions.", + description="Config option capabilities supported by the client.\n\nOmitted or `null` both mean the client does not advertise support for any\nconfig option extensions.", ), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -4555,6 +5163,11 @@ class ClientSessionCapabilities(BaseModel): ), ] = None + @field_validator("config_options", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NewSessionRequest(BaseModel): # The working directory for this session. Must be an absolute path. @@ -4595,6 +5208,16 @@ class NewSessionRequest(BaseModel): ), ] = None + @field_validator("additional_directories", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("mcp_servers", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class PromptRequest(BaseModel): # The ID of the session to send this user message to @@ -4745,13 +5368,103 @@ class DidChangeDocumentNotification(BaseModel): ), ] = None + @field_validator("content_changes", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ContentToolCallContent(Content): type: Literal["content"] -class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): - type: Literal["array"] +class ElicitationSchema(BaseModel): + # Type discriminator. Always `"object"`. + type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" + # Optional title for the schema. + title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None + # Property definitions (must be primitive types). + properties: Annotated[ + Optional[ + Dict[ + str, + Union[ + ElicitationStringPropertySchema, + ElicitationNumberPropertySchema, + ElicitationIntegerPropertySchema, + ElicitationBooleanPropertySchema, + ElicitationMultiSelectPropertySchema, + ElicitationOtherPropertySchema, + ], + ] + ], + Field(description="Property definitions (must be primitive types)."), + ] = {} + # List of required property names. + required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None + # Optional description of what this schema represents. + description: Annotated[ + Optional[str], + Field(description="Optional description of what this schema represents."), + ] = None + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + + @field_validator("type", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: "object") + + @field_validator("description", "title", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + +class ElicitationFormSessionMode(ElicitationSessionScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, + Field( + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", + ), + ] + + +class ElicitationFormRequestMode(ElicitationRequestScope): + # A JSON Schema describing the form fields to present to the user. + requested_schema: Annotated[ + ElicitationSchema, + Field( + alias="requestedSchema", + description="A JSON Schema describing the form fields to present to the user.", + ), + ] + + +class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): + # **UNSTABLE** + # + # This capability is not part of the spec yet, and may be removed or changed at any point. + # + # Form-based elicitation mode where the client renders a form from the provided schema. + root: Annotated[ + Union[ElicitationFormSessionMode, ElicitationFormRequestMode], + Field( + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." + ), + ] class NesEventCapabilities(BaseModel): @@ -4773,6 +5486,11 @@ class NesEventCapabilities(BaseModel): ), ] = None + @field_validator("document", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class SessionConfigOptionSelect(SessionConfigSelect): # Unique identifier for the configuration option. @@ -4786,7 +5504,7 @@ class SessionConfigOptionSelect(SessionConfigSelect): ] = None # Optional semantic category for this option (UX only). category: Annotated[ - Optional[str], + Optional[Union[str, Dict[str, Any]]], Field(description="Optional semantic category for this option (UX only)."), ] = None # The _meta property is reserved by ACP to allow clients and agents to attach additional @@ -4803,6 +5521,11 @@ class SessionConfigOptionSelect(SessionConfigSelect): ] = None type: Literal["select"] + @field_validator("category", "description", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class LoadSessionResponse(BaseModel): # Initial mode state if supported by the Agent @@ -4835,6 +5558,16 @@ class LoadSessionResponse(BaseModel): ), ] = None + @field_validator("modes", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ForkSessionResponse(BaseModel): # Unique identifier for the newly created forked session. @@ -4875,6 +5608,16 @@ class ForkSessionResponse(BaseModel): ), ] = None + @field_validator("modes", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ResumeSessionResponse(BaseModel): # Initial mode state if supported by the Agent @@ -4907,6 +5650,16 @@ class ResumeSessionResponse(BaseModel): ), ] = None + @field_validator("modes", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class SetSessionConfigOptionResponse(BaseModel): # The full set of configuration options and their current values. @@ -4930,6 +5683,11 @@ class SetSessionConfigOptionResponse(BaseModel): ), ] = None + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class NesEditSuggestionVariant(NesEditSuggestion): kind: Literal["edit"] @@ -5013,6 +5771,21 @@ class ToolCall(BaseModel): ), ] = None + @field_validator("kind", "raw_input", "raw_output", "status", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("content", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("locations", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class _ConfigOptionUpdate(BaseModel): # The full set of configuration options and their current values. @@ -5036,6 +5809,11 @@ class _ConfigOptionUpdate(BaseModel): ), ] = None + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class ClientCapabilities(BaseModel): # File system capabilities supported by the client. @@ -5051,15 +5829,14 @@ class ClientCapabilities(BaseModel): Optional[bool], Field(description="Whether the Client support all `terminal/*` methods."), ] = False - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # # Session-related capabilities supported by the client. + # + # Optional. Omitted or `null` both mean the client does not advertise any + # session-related extensions. session: Annotated[ Optional[ClientSessionCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSession-related capabilities supported by the client." + description="Session-related capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nsession-related extensions." ), ] = None # **UNSTABLE** @@ -5068,12 +5845,12 @@ class ClientCapabilities(BaseModel): # # Whether the client supports `plan_update` and `plan_removed` session updates. # - # Optional. Omitted means the client does not advertise support. + # Optional. Omitted or `null` both mean the client does not advertise support. # Supplying `{}` means the client can receive both update types. plan: Annotated[ Optional[PlanCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted means the client does not advertise support.\nSupplying `{}` means the client can receive both update types." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client can receive both update types." ), ] = None # **UNSTABLE** @@ -5095,10 +5872,13 @@ class ClientCapabilities(BaseModel): # # Elicitation capabilities supported by the client. # Determines which elicitation modes the agent may use. + # + # Optional. Omitted or `null` both mean the client does not advertise + # elicitation support. elicitation: Annotated[ Optional[ElicitationCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.\n\nOptional. Omitted or `null` both mean the client does not advertise\nelicitation support." ), ] = None # **UNSTABLE** @@ -5106,10 +5886,13 @@ class ClientCapabilities(BaseModel): # This capability is not part of the spec yet, and may be removed or changed at any point. # # NES (Next Edit Suggestions) capabilities supported by the client. + # + # Optional. Omitted or `null` both mean the client does not advertise any + # NES suggestion-kind extensions. nes: Annotated[ Optional[ClientNesCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nNES suggestion-kind extensions." ), ] = None # **UNSTABLE** @@ -5137,6 +5920,31 @@ class ClientCapabilities(BaseModel): ), ] = None + @field_validator("terminal", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + + @field_validator("elicitation", "nes", "plan", "session", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("fs", mode="wrap") + @classmethod + def _salvage_on_error_2(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: {"readTextFile": False, "writeTextFile": False}) + + @field_validator("auth", mode="wrap") + @classmethod + def _salvage_on_error_3(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: {"terminal": False}) + + @field_validator("position_encodings", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class SuggestNesRequest(BaseModel): # The session ID for this request. @@ -5196,6 +6004,7 @@ class ClientResponseMessage(BaseModel): AcceptElicitationResponse, DeclineElicitationResponse, CancelElicitationResponse, + OtherElicitationResponse, ], Any, ], @@ -5273,35 +6082,28 @@ class ToolCallUpdate(BaseModel): ), ] = None + @field_validator("kind", "raw_input", "raw_output", "status", "title", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) -class ElicitationSchema(BaseModel): - # Type discriminator. Always `"object"`. - type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" - # Optional title for the schema. - title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None - # Property definitions (must be primitive types). - properties: Annotated[ - Optional[ - Dict[ - str, - Union[ - ElicitationStringPropertySchema, - ElicitationNumberPropertySchema, - ElicitationIntegerPropertySchema, - ElicitationBooleanPropertySchema, - ElicitationMultiSelectPropertySchema, - ], - ] - ], - Field(description="Property definitions (must be primitive types)."), - ] = {} - # List of required property names. - required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None - # Optional description of what this schema represents. - description: Annotated[ - Optional[str], - Field(description="Optional description of what this schema represents."), - ] = None + @field_validator("content", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + @field_validator("locations", mode="wrap") + @classmethod + def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + +class CreateFormSessionElicitationRequest(ElicitationSessionScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] # The _meta property is reserved by ACP to allow clients and agents to attach additional # metadata to their interactions. Implementations MUST NOT make assumptions about values at # these keys. @@ -5314,9 +6116,7 @@ class ElicitationSchema(BaseModel): description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", ), ] = None - - -class ElicitationFormSessionMode(ElicitationSessionScope): + mode: Literal["form"] # A JSON Schema describing the form fields to present to the user. requested_schema: Annotated[ ElicitationSchema, @@ -5327,7 +6127,25 @@ class ElicitationFormSessionMode(ElicitationSessionScope): ] -class ElicitationFormRequestMode(ElicitationRequestScope): +class CreateFormRequestElicitationRequest(ElicitationRequestScope): + # A human-readable message describing what input is needed. + message: Annotated[ + str, + Field(description="A human-readable message describing what input is needed."), + ] + # The _meta property is reserved by ACP to allow clients and agents to attach additional + # metadata to their interactions. Implementations MUST NOT make assumptions about values at + # these keys. + # + # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + field_meta: Annotated[ + Optional[Dict[str, Any]], + Field( + alias="_meta", + description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", + ), + ] = None + mode: Literal["form"] # A JSON Schema describing the form fields to present to the user. requested_schema: Annotated[ ElicitationSchema, @@ -5338,18 +6156,31 @@ class ElicitationFormRequestMode(ElicitationRequestScope): ] -class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Form-based elicitation mode where the client renders a form from the provided schema. - root: Annotated[ - Union[ElicitationFormSessionMode, ElicitationFormRequestMode], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." - ), - ] +ElicitationMode = Union[ + ElicitationFormSessionMode, + ElicitationFormRequestMode, + ElicitationUrlSessionMode, + ElicitationUrlRequestMode, +] +CreateFormElicitationRequest = Union[ + CreateFormSessionElicitationRequest, + CreateFormRequestElicitationRequest, +] +CreateUrlElicitationRequest = Union[ + CreateUrlSessionElicitationRequest, + CreateUrlRequestElicitationRequest, +] +CreateElicitationRequest = Union[ + CreateFormElicitationRequest, + CreateUrlElicitationRequest, + CreateOtherElicitationRequest, +] +CreateElicitationResponse = Union[ + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, + OtherElicitationResponse, +] class NesCapabilities(BaseModel): @@ -5376,6 +6207,11 @@ class NesCapabilities(BaseModel): ), ] = None + @field_validator("context", "events", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + class NewSessionResponse(BaseModel): # Unique identifier for the created session. @@ -5418,6 +6254,16 @@ class NewSessionResponse(BaseModel): ), ] = None + @field_validator("modes", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("config_options", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class SuggestNesResponse(BaseModel): # The list of suggestions. @@ -5514,6 +6360,24 @@ def _coerce_protocol_version(cls, value: Any) -> int: except (TypeError, ValueError): return 1 + @field_validator("client_info", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("client_capabilities", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error( + value, + handler, + lambda: { + "fs": {"readTextFile": False, "writeTextFile": False}, + "terminal": False, + "auth": {"terminal": False}, + }, + ) + class RequestPermissionRequest(BaseModel): # The session ID for this request. @@ -5545,89 +6409,6 @@ class RequestPermissionRequest(BaseModel): ] = None -class CreateFormSessionElicitationRequest(ElicitationSessionScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - mode: Literal["form"] - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] - - -class CreateFormRequestElicitationRequest(ElicitationRequestScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - mode: Literal["form"] - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] - - -ElicitationMode = Union[ - ElicitationFormSessionMode, - ElicitationFormRequestMode, - ElicitationUrlSessionMode, - ElicitationUrlRequestMode, -] -CreateFormElicitationRequest = Union[ - CreateFormSessionElicitationRequest, - CreateFormRequestElicitationRequest, -] -CreateUrlElicitationRequest = Union[ - CreateUrlSessionElicitationRequest, - CreateUrlRequestElicitationRequest, -] -CreateElicitationRequest = Union[ - CreateFormElicitationRequest, - CreateUrlElicitationRequest, -] -CreateElicitationResponse = Union[ - AcceptElicitationResponse, - DeclineElicitationResponse, - CancelElicitationResponse, -] - - class AgentCapabilities(BaseModel): # Whether the agent supports `session/load`. load_session: Annotated[ @@ -5672,11 +6453,12 @@ class AgentCapabilities(BaseModel): # # Provider configuration capabilities supported by the agent. # - # By supplying `{}` it means that the agent supports provider configuration methods. + # Optional. Omitted or `null` both mean the agent does not advertise support. + # Supplying `{}` means the agent supports provider configuration methods. providers: Annotated[ Optional[ProvidersCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nBy supplying `{}` it means that the agent supports provider configuration methods." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports provider configuration methods." ), ] = None # **UNSTABLE** @@ -5684,10 +6466,13 @@ class AgentCapabilities(BaseModel): # This capability is not part of the spec yet, and may be removed or changed at any point. # # NES (Next Edit Suggestions) capabilities supported by the agent. + # + # Optional. Omitted or `null` both mean the agent does not advertise support + # for NES methods. nes: Annotated[ Optional[NesCapabilities], Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent." + description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support\nfor NES methods." ), ] = None # **UNSTABLE** @@ -5715,6 +6500,31 @@ class AgentCapabilities(BaseModel): ), ] = None + @field_validator("load_session", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: False) + + @field_validator("nes", "position_encoding", "providers", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("mcp_capabilities", mode="wrap") + @classmethod + def _salvage_on_error_2(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: {"http": False, "sse": False, "acp": False}) + + @field_validator("prompt_capabilities", mode="wrap") + @classmethod + def _salvage_on_error_3(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: {"image": False, "audio": False, "embeddedContext": False}) + + @field_validator("auth", "session_capabilities", mode="wrap") + @classmethod + def _salvage_on_error_4(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: {}) + class SessionNotification(BaseModel): # The ID of the session this update pertains to. @@ -5825,6 +6635,7 @@ class AgentRequest(BaseModel): CreateFormRequestElicitationRequest, CreateUrlSessionElicitationRequest, CreateUrlRequestElicitationRequest, + CreateOtherElicitationRequest, ], Any, ] @@ -5886,6 +6697,31 @@ class InitializeResponse(BaseModel): ), ] = None + @field_validator("agent_info", mode="wrap") + @classmethod + def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + @field_validator("agent_capabilities", mode="wrap") + @classmethod + def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: + return salvage_on_error( + value, + handler, + lambda: { + "loadSession": False, + "promptCapabilities": {"image": False, "audio": False, "embeddedContext": False}, + "mcpCapabilities": {"http": False, "sse": False, "acp": False}, + "sessionCapabilities": {}, + "auth": {}, + }, + ) + + @field_validator("auth_methods", mode="wrap") + @classmethod + def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + class AgentNotification(BaseModel): # The notification method name. diff --git a/tests/test_deserialize.py b/tests/test_deserialize.py new file mode 100644 index 0000000..42188ff --- /dev/null +++ b/tests/test_deserialize.py @@ -0,0 +1,62 @@ +"""Regression tests for lenient deserialization restored by ``acp._deserialize`` and the +validators ``scripts/gen_schema.py`` injects: ``x-deserialize-default-on-error`` (salvage a +malformed field to its default) and ``x-deserialize-skip-invalid-items`` (drop bad array +items). Mirrors the TypeScript SDK's ``src/schema-deserialize.test.ts``. +""" + +from typing import Any + +from pydantic import BaseModel, field_validator + +from acp._deserialize import salvage_on_error, skip_invalid_items +from acp.schema import ReadTextFileRequest, ToolCallUpdate, WriteTextFileRequest + + +class _Salvage(BaseModel): + n: int | None = None + + @field_validator("n", mode="wrap") + @classmethod + def _v(cls, value: Any, handler: Any) -> Any: + return salvage_on_error(value, handler, lambda: None) + + +def test_salvage_on_error_replaces_invalid_value() -> None: + assert _Salvage.model_validate({"n": "not-an-int"}).n is None + assert _Salvage.model_validate({"n": 7}).n == 7 + + +class _Skip(BaseModel): + xs: list[int] = [] + + @field_validator("xs", mode="wrap") + @classmethod + def _v(cls, value: Any, handler: Any) -> Any: + return skip_invalid_items(value, handler) + + +def test_skip_invalid_items_drops_bad_entries() -> None: + assert _Skip.model_validate({"xs": [1, "bad", 3]}).xs == [1, 3] + + +def test_meta_is_salvaged_to_none() -> None: + request = WriteTextFileRequest.model_validate({ + "sessionId": "s", + "path": "/p", + "content": "x", + "_meta": "not-a-dict", + }) + assert request.field_meta is None + + +def test_default_on_error_field_is_salvaged() -> None: + salvaged = ReadTextFileRequest.model_validate({"sessionId": "s", "path": "/p", "line": "nan"}) + assert salvaged.line is None + kept = ReadTextFileRequest.model_validate({"sessionId": "s", "path": "/p", "line": 5}) + assert kept.line == 5 + + +def test_skip_invalid_items_on_generated_model() -> None: + good = {"type": "content", "content": {"type": "text", "text": "ok"}} + update = ToolCallUpdate.model_validate({"toolCallId": "t", "content": [good, {"bogus": 1}]}) + assert len(update.content or []) == 1 diff --git a/tests/test_elicitation_catchall.py b/tests/test_elicitation_catchall.py new file mode 100644 index 0000000..331185f --- /dev/null +++ b/tests/test_elicitation_catchall.py @@ -0,0 +1,83 @@ +"""Regression tests for the schema-v1.18 "custom or future" catch-all union idiom. + +These guard the codegen support in ``scripts/gen_schema.py``: unknown discriminator +values must resolve to the catch-all variant while preserving the raw payload, and +known values must still resolve to their specific typed variant. +""" + +import pytest +from pydantic import TypeAdapter, ValidationError + +from acp.client.router import _mode_from_create_elicitation_request +from acp.exceptions import RequestError +from acp.schema import ( + AcceptElicitationResponse, + CreateElicitationRequest, + CreateElicitationResponse, + CreateOtherElicitationRequest, + ElicitationOtherPropertySchema, + ElicitationStringPropertySchema, + OtherElicitationResponse, + OtherMultiSelectItems, + StringMultiSelectItems, + TitledMultiSelectItems, +) + +_RESPONSE = TypeAdapter(CreateElicitationResponse) +_REQUEST = TypeAdapter(CreateElicitationRequest) + + +def test_known_elicitation_response_resolves_to_specific_variant() -> None: + assert isinstance(_RESPONSE.validate_python({"action": "accept"}), AcceptElicitationResponse) + + +def test_custom_elicitation_response_falls_back_to_catchall() -> None: + parsed = _RESPONSE.validate_python({"action": "x-snooze", "until": "later"}) + assert isinstance(parsed, OtherElicitationResponse) + assert parsed.action == "x-snooze" + assert parsed.model_dump(by_alias=True)["until"] == "later" + + +def test_malformed_known_variant_is_rejected_not_catchall() -> None: + # A "form" request missing the required requestedSchema must fail validation rather + # than silently degrade to the catch-all (restores the schema's dropped `not` clause). + with pytest.raises(ValidationError): + _REQUEST.validate_python({"mode": "form", "message": "hi", "sessionId": "s1"}) + + +def test_custom_elicitation_request_preserves_mode_and_payload() -> None: + parsed = _REQUEST.validate_python({ + "mode": "x-voice", + "message": "speak now", + "sessionId": "sess-1", + "codec": "opus", + }) + assert isinstance(parsed, CreateOtherElicitationRequest) + assert parsed.mode == "x-voice" + assert parsed.model_dump(by_alias=True)["codec"] == "opus" + + +def test_unknown_elicitation_mode_dispatches_to_clean_request_error() -> None: + # A custom mode parses (above); the client router must then reject it with a clean + # RequestError (invalid params) rather than a bare TypeError that surfaces as an + # opaque -32603 internal error. + request = CreateOtherElicitationRequest(message="hi", mode="x-voice") + with pytest.raises(RequestError) as exc_info: + _mode_from_create_elicitation_request(request) + assert isinstance(exc_info.value, RequestError) + assert exc_info.value.code == -32602 + + +def test_elicitation_property_schema_catchall() -> None: + adapter = TypeAdapter(ElicitationStringPropertySchema | ElicitationOtherPropertySchema) + assert isinstance(adapter.validate_python({"type": "string"}), ElicitationStringPropertySchema) + custom = adapter.validate_python({"type": "x-slider", "min": 0, "max": 9}) + assert isinstance(custom, ElicitationOtherPropertySchema) + assert custom.model_dump(by_alias=True)["max"] == 9 + + +def test_multi_select_items_variants() -> None: + adapter = TypeAdapter(StringMultiSelectItems | OtherMultiSelectItems | TitledMultiSelectItems) + assert isinstance(adapter.validate_python({"type": "string", "enum": ["a", "b"]}), StringMultiSelectItems) + assert isinstance(adapter.validate_python({"anyOf": [{"const": "a", "title": "A"}]}), TitledMultiSelectItems) + assert isinstance(adapter.validate_python({"type": "x-chips", "note": "hi"}), OtherMultiSelectItems) diff --git a/tests/test_gen_all.py b/tests/test_gen_all.py index 2cc95b5..da9f73d 100644 --- a/tests/test_gen_all.py +++ b/tests/test_gen_all.py @@ -1,5 +1,12 @@ from scripts.gen_all import resolve_ref, schema_source_paths -from scripts.gen_schema import _preprocess_schema_for_codegen, _restore_required_nullable_fields +from scripts.gen_schema import ( + _deserialize_field_specs, + _extensible_union_excluded_tags, + _fallback_expression, + _normalize_catchall_unions, + _preprocess_schema_for_codegen, + _restore_required_nullable_fields, +) def test_resolve_ref_accepts_schema_release_tags() -> None: @@ -87,6 +94,84 @@ def test_codegen_preprocess_distributes_common_object_properties() -> None: assert request["oneOf"][1]["allOf"] == [{"$ref": "#/$defs/ScopeB"}] +def test_codegen_preprocess_normalizes_catchall_unions() -> None: + schema = { + "anyOf": [ + { + "type": "object", + "properties": {"type": {"type": "string", "const": "known"}}, + "required": ["type"], + }, + { + "title": "other", + "description": "Custom or future.", + "type": "object", + "properties": {"type": {"type": "string"}}, + "required": ["type"], + "not": {"anyOf": [{"const": "known"}]}, + "unevaluatedProperties": True, + }, + ], + "discriminator": {"propertyName": "type"}, + } + + normalized = _normalize_catchall_unions(schema) + + assert "discriminator" not in normalized + known, other = normalized["anyOf"] + assert known["properties"]["type"]["const"] == "known" + assert other["additionalProperties"] is True + assert other["properties"] == {"type": {"type": "string"}} + assert other["required"] == ["type"] + assert "not" not in other + assert "unevaluatedProperties" not in other + + +def test_extensible_union_excluded_tags_reads_not_clause() -> None: + union_def = { + "discriminator": {"propertyName": "action"}, + "anyOf": [ + {"properties": {"action": {"const": "accept"}}, "required": ["action"]}, + { + "title": "other", + "properties": {"action": {"type": "string"}}, + "not": { + "anyOf": [ + {"properties": {"action": {"const": "accept"}}}, + {"properties": {"action": {"const": "decline"}}}, + ] + }, + }, + ], + } + + assert _extensible_union_excluded_tags(union_def, "action") == ("accept", "decline") + + +def test_deserialize_field_specs_groups_by_fallback_and_excludes_meta() -> None: + definition = { + "required": ["items"], + "properties": { + "_meta": {"x-deserialize-default-on-error": True}, + "note": {"type": "string", "x-deserialize-default-on-error": True}, + "flag": {"type": "boolean", "default": False, "x-deserialize-default-on-error": True}, + "items": {"type": "array", "x-deserialize-skip-invalid-items": True}, + }, + } + + salvage, skip = _deserialize_field_specs(definition) + + assert salvage == {"lambda: None": ["note"], "lambda: False": ["flag"]} + assert skip == ["items"] + + +def test_fallback_expression_matches_schema_default_rules() -> None: + assert _fallback_expression({"default": False}, is_required=False) == "lambda: False" + assert _fallback_expression({"type": "array"}, is_required=True) == "lambda: []" + assert _fallback_expression({"type": ["array", "null"]}, is_required=False) == "lambda: None" + assert _fallback_expression({"type": "string"}, is_required=False) == "lambda: None" + + def test_codegen_postprocess_preserves_required_nullable_fields() -> None: schema = { "$defs": { From 3ddfa385fabd3123ab3ea46c5a203674a823143a Mon Sep 17 00:00:00 2001 From: Federico Ciner Date: Fri, 31 Jul 2026 02:43:09 +1000 Subject: [PATCH 44/52] Initial implementation of ACP web transport, with docs and examples (#118) --- AGENTS.md | 1 + docs/web-transport.md | 108 ++++++++ examples/http_client.py | 54 ++++ examples/http_server.py | 81 ++++++ examples/ws_client.py | 53 ++++ mkdocs.yml | 1 + pyproject.toml | 5 + src/acp/_cookies.py | 53 ++++ src/acp/_sse.py | 84 ++++++ src/acp/_transport.py | 151 +++++++++++ src/acp/agent/connection.py | 16 +- src/acp/client/connection.py | 16 +- src/acp/connection.py | 73 +++--- src/acp/core.py | 17 +- src/acp/http/__init__.py | 30 +++ src/acp/http/asgi.py | 175 +++++++++++++ src/acp/http/client.py | 238 +++++++++++++++++ src/acp/http/protocol.py | 106 ++++++++ src/acp/http/server.py | 461 +++++++++++++++++++++++++++++++++ src/acp/ws/__init__.py | 23 ++ src/acp/ws/client.py | 117 +++++++++ src/acp/ws/server.py | 79 ++++++ tests/http/conftest.py | 62 +++++ tests/http/test_cookies.py | 42 +++ tests/http/test_fixes.py | 186 +++++++++++++ tests/http/test_http_client.py | 213 +++++++++++++++ tests/http/test_http_server.py | 233 +++++++++++++++++ tests/http/test_loopback.py | 131 ++++++++++ tests/http/test_protocol.py | 55 ++++ tests/http/test_sse.py | 63 +++++ tests/http/test_websocket.py | 182 +++++++++++++ tests/http/test_ws_cookies.py | 55 ++++ tests/test_rpc.py | 4 +- uv.lock | 233 ++++++++++++++++- 34 files changed, 3343 insertions(+), 58 deletions(-) create mode 100644 docs/web-transport.md create mode 100644 examples/http_client.py create mode 100644 examples/http_server.py create mode 100644 examples/ws_client.py create mode 100644 src/acp/_cookies.py create mode 100644 src/acp/_sse.py create mode 100644 src/acp/_transport.py create mode 100644 src/acp/http/__init__.py create mode 100644 src/acp/http/asgi.py create mode 100644 src/acp/http/client.py create mode 100644 src/acp/http/protocol.py create mode 100644 src/acp/http/server.py create mode 100644 src/acp/ws/__init__.py create mode 100644 src/acp/ws/client.py create mode 100644 src/acp/ws/server.py create mode 100644 tests/http/conftest.py create mode 100644 tests/http/test_cookies.py create mode 100644 tests/http/test_fixes.py create mode 100644 tests/http/test_http_client.py create mode 100644 tests/http/test_http_server.py create mode 100644 tests/http/test_loopback.py create mode 100644 tests/http/test_protocol.py create mode 100644 tests/http/test_sse.py create mode 100644 tests/http/test_websocket.py create mode 100644 tests/http/test_ws_cookies.py diff --git a/AGENTS.md b/AGENTS.md index a2927e4..263c281 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,6 +7,7 @@ Use this page as the quick orientation for the Python SDK repo. It mirrors the t | Path | Why it exists | | --- | --- | | `src/acp/` | Runtime package: agent/client bases, transports, helpers, schema bindings, contrib utilities | +| `src/acp/http/`, `src/acp/ws/` | Experimental remote transports (Streamable HTTP + WebSocket), client + server; opt-in via the `[http]` extra | | `schema/` | Upstream JSON schema sources (regenerate with `make gen-all`) | | `examples/` | Runnable scripts such as `echo_agent.py`, `client.py`, `gemini.py`, `duet.py` | | `tests/` | Pytest suite, including optional Gemini smoke tests in `tests/test_gemini_example.py` | diff --git a/docs/web-transport.md b/docs/web-transport.md new file mode 100644 index 0000000..e601988 --- /dev/null +++ b/docs/web-transport.md @@ -0,0 +1,108 @@ +# Web Transport (Streamable HTTP & WebSocket) + +> **Experimental.** The remote web transports are experimental and may change. +> They ship as an optional extra and are import-guarded. + +The SDK can run ACP over two remote connectivity profiles in addition to stdio: + +- **Streamable HTTP** — `POST` for client→server messages, long-lived `GET` SSE + streams for server→client messages (one connection-scoped stream plus one per + session), and `DELETE` to terminate. `initialize` returns `200 OK` with a JSON + body; all other POSTs return `202 Accepted`. **Requires HTTP/2.** +- **WebSocket** — a `GET` upgrade on the same endpoint carrying full-duplex + JSON-RPC text frames. + +Both reuse the existing JSON-RPC message format and ACP lifecycle +(`initialize` → session methods → close). + +## Installation + +```bash +pip install "agent-client-protocol[http]" +``` + +This pulls in `httpx[http2]` (HTTP/2 + SSE consumption) and `websockets`. + +## Client + +Both transports produce a message-level `Transport` that plugs into the existing +`connect_to_agent`: + +```python +from acp import connect_to_agent +from acp.http import create_http_stream +from acp.ws import create_websocket_stream + +# Streamable HTTP +transport = create_http_stream("http://localhost:8000/acp") +conn = connect_to_agent(my_client, transport) + +# ...or WebSocket +transport = await create_websocket_stream("ws://localhost:8000/acp") +conn = connect_to_agent(my_client, transport) + +init = await conn.initialize(protocol_version=1) +session = await conn.new_session(cwd="/tmp", mcp_servers=[]) +await conn.prompt(session_id=session.session_id, prompt=[...]) +await conn.close() +await transport.close() +``` + +The client sends `initialize` first, reads the `Acp-Connection-Id` response +header, then opens the connection-scoped SSE stream. When a new `sessionId` +appears it opens that session-scoped stream too. A single SSE attempt is made per +stream; reconnect/retry is the caller's responsibility (v1 of the RFD). + +## Server + +The server core is framework-agnostic; a thin ASGI adapter bridges it to your +web framework: + +```python +from acp.http.asgi import create_asgi_app + +# One agent instance is created per connection. +app = create_asgi_app(lambda conn: MyAgent()) +``` + +`app` is a standard ASGI 3.0 application handling `POST`/`GET`/`DELETE` and +WebSocket upgrades on the ACP endpoint. + +### HTTP/2 server requirement + +> ⚠️ **Uvicorn does not serve HTTP/2.** For a spec-compliant Streamable HTTP +> server, run an HTTP/2-capable ASGI server (**Hypercorn**, Daphne, Granian) or +> terminate HTTP/2 at a proxy. The WebSocket profile works on Uvicorn. + +```python +import asyncio +import hypercorn.asyncio +from hypercorn.config import Config + +config = Config() +config.bind = ["localhost:8000"] +config.alpn_protocols = ["h2", "http/1.1"] +asyncio.run(hypercorn.asyncio.serve(app, config)) +``` + +## Examples + +- [`examples/http_server.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/http_server.py) — serve an agent over HTTP + WS (Hypercorn). +- [`examples/http_client.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/http_client.py) — connect over Streamable HTTP. +- [`examples/ws_client.py`](https://github.com/agentclientprotocol/python-sdk/blob/main/examples/ws_client.py) — connect over WebSocket. + +## Identity model + +- `Acp-Connection-Id` (HTTP header) — returned by `initialize`; required on all + post-initialize HTTP requests and every GET stream. +- `Acp-Session-Id` (HTTP header) — required on session-scoped POSTs and the + session-scoped GET stream. +- `sessionId` (JSON-RPC field) — carried in params/results and used to route + messages to the correct stream. + +## Not yet supported (deferred to a future revision) + +- `Last-Event-ID` / SSE resumability and message sequencing. +- Client-side automatic reconnect/backoff. +- Batch JSON-RPC (the server returns `501`). +- `Acp-Protocol-Version` header enforcement. diff --git a/examples/http_client.py b/examples/http_client.py new file mode 100644 index 0000000..1843c01 --- /dev/null +++ b/examples/http_client.py @@ -0,0 +1,54 @@ +# /// script +# requires-python = ">=3.10,<3.15" +# dependencies = [ +# "agent-client-protocol[http]", +# ] +# /// +"""Connect to a remote ACP agent over Streamable HTTP (experimental). + +Start the server first (``uv run examples/http_server.py``), then run this. +""" + +import asyncio +from typing import Any + +from acp import connect_to_agent, text_block +from acp.http import create_http_stream +from acp.interfaces import Client + + +class ExampleClient(Client): + async def request_permission(self, session_id: str, tool_call: Any, options: Any, **kwargs: Any) -> Any: + # Auto-allow the first option. + return {"outcome": {"outcome": "selected", "optionId": options[0]["optionId"]}} + + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + content = getattr(update, "content", None) + text = getattr(content, "text", None) if content is not None else None + if text: + print(f"<< {text}") + + async def write_text_file(self, *args: Any, **kwargs: Any) -> None: + return None + + async def read_text_file(self, *args: Any, **kwargs: Any) -> Any: + return {"content": ""} + + +async def main() -> None: + transport = create_http_stream("http://localhost:8000/acp") + conn = connect_to_agent(ExampleClient(), transport) + try: + init = await conn.initialize(protocol_version=1) + print(f"initialized (protocol v{init.protocol_version})") + session = await conn.new_session(cwd=".", mcp_servers=[]) + print(f"session: {session.session_id}") + result = await conn.prompt(session_id=session.session_id, prompt=[text_block("hello over http")]) + print(f"stop reason: {result.stop_reason}") + finally: + await conn.close() + await transport.close() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/http_server.py b/examples/http_server.py new file mode 100644 index 0000000..98b4fc7 --- /dev/null +++ b/examples/http_server.py @@ -0,0 +1,81 @@ +# /// script +# requires-python = ">=3.10,<3.15" +# dependencies = [ +# "agent-client-protocol[http]", +# "hypercorn>=0.17", +# ] +# /// +"""Serve an ACP agent over Streamable HTTP + WebSocket (experimental). + +Run with an HTTP/2-capable ASGI server for spec-compliant Streamable HTTP. This +example uses Hypercorn; Uvicorn works for WebSocket but does not serve HTTP/2. + + uv run examples/http_server.py + # then, in another terminal: + uv run examples/http_client.py + uv run examples/ws_client.py +""" + +import asyncio +from typing import Any +from uuid import uuid4 + +from acp import ( + Agent, + InitializeResponse, + NewSessionResponse, + PromptResponse, + text_block, + update_agent_message, +) +from acp.http.asgi import create_asgi_app +from acp.interfaces import Client +from acp.schema import ClientCapabilities, Implementation + + +class EchoAgent(Agent): + _conn: Client + + def on_connect(self, conn: Client) -> None: + self._conn = conn + + async def initialize( + self, + protocol_version: int, + client_capabilities: ClientCapabilities | None = None, + client_info: Implementation | None = None, + **kwargs: Any, + ) -> InitializeResponse: + return InitializeResponse(protocol_version=protocol_version) + + async def new_session(self, cwd: str = "", **kwargs: Any) -> NewSessionResponse: + return NewSessionResponse(session_id=uuid4().hex) + + async def prompt(self, session_id: str, prompt: list[Any], **kwargs: Any) -> PromptResponse: + for block in prompt: + text = block.get("text", "") if isinstance(block, dict) else getattr(block, "text", "") + await self._conn.session_update( + session_id=session_id, + update=update_agent_message(text_block(f"echo: {text}")), + ) + return PromptResponse(stop_reason="end_turn") + + +# One agent instance per connection. +app = create_asgi_app(lambda conn: EchoAgent()) + + +async def main() -> None: + import hypercorn.asyncio + from hypercorn.config import Config + + config = Config() + config.bind = ["localhost:8000"] + # Enable HTTP/2 (Streamable HTTP requires it). Hypercorn negotiates h2c/h2. + config.alpn_protocols = ["h2", "http/1.1"] + print("Serving ACP agent on http://localhost:8000/acp (HTTP + WS)") + await hypercorn.asyncio.serve(app, config) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/ws_client.py b/examples/ws_client.py new file mode 100644 index 0000000..ac9c05c --- /dev/null +++ b/examples/ws_client.py @@ -0,0 +1,53 @@ +# /// script +# requires-python = ">=3.10,<3.15" +# dependencies = [ +# "agent-client-protocol[http]", +# ] +# /// +"""Connect to a remote ACP agent over WebSocket (experimental). + +Start the server first (``uv run examples/http_server.py``), then run this. +""" + +import asyncio +from typing import Any + +from acp import connect_to_agent, text_block +from acp.interfaces import Client +from acp.ws import create_websocket_stream + + +class ExampleClient(Client): + async def request_permission(self, session_id: str, tool_call: Any, options: Any, **kwargs: Any) -> Any: + return {"outcome": {"outcome": "selected", "optionId": options[0]["optionId"]}} + + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + content = getattr(update, "content", None) + text = getattr(content, "text", None) if content is not None else None + if text: + print(f"<< {text}") + + async def write_text_file(self, *args: Any, **kwargs: Any) -> None: + return None + + async def read_text_file(self, *args: Any, **kwargs: Any) -> Any: + return {"content": ""} + + +async def main() -> None: + transport = await create_websocket_stream("ws://localhost:8000/acp") + conn = connect_to_agent(ExampleClient(), transport) + try: + init = await conn.initialize(protocol_version=1) + print(f"initialized (protocol v{init.protocol_version})") + session = await conn.new_session(cwd=".", mcp_servers=[]) + print(f"session: {session.session_id}") + result = await conn.prompt(session_id=session.session_id, prompt=[text_block("hello over websocket")]) + print(f"stop reason: {result.stop_reason}") + finally: + await conn.close() + await transport.close() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/mkdocs.yml b/mkdocs.yml index 09e3ea4..f7e1b6f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,6 +11,7 @@ nav: - Home: index.md - Quick Start: quickstart.md - Use Cases: use-cases.md + - Web Transport (HTTP/WS): web-transport.md - Experimental Contrib: contrib.md - Releasing: releasing.md - 0.11 Migration Guide: migration-guide-0.11.md diff --git a/pyproject.toml b/pyproject.toml index 04117f4..220b908 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,10 +44,15 @@ dev = [ "mkdocstrings[python]>=0.26.1", "python-dotenv>=1.1.1", "prek>=0.2.17", + "httpx[http2]>=0.27", + "websockets>=12.0", + "uvicorn>=0.30", ] [project.optional-dependencies] logfire = ["logfire>=0.14", "opentelemetry-sdk>=1.28.0"] +# Experimental remote transports (Streamable HTTP + WebSocket), client + server. +http = ["httpx[http2]>=0.27", "websockets>=12.0"] [build-system] requires = ["pdm-backend"] diff --git a/src/acp/_cookies.py b/src/acp/_cookies.py new file mode 100644 index 0000000..a4b05d6 --- /dev/null +++ b/src/acp/_cookies.py @@ -0,0 +1,53 @@ +"""In-memory cookie store for the WebSocket handshake. + +The HTTP client relies on ``httpx``'s built-in cookie jar for session affinity, +but the WebSocket handshake needs a small, explicit store to collect +``Set-Cookie`` headers from the upgrade response and echo them back as a +``Cookie`` request header for the socket lifetime. + +This is intentionally minimal: it stores name→value pairs without attribute +parsing (domain/path/expiry), matching the affinity-only use case in the RFD. +""" + +from __future__ import annotations + +__all__ = ["MemoryAcpCookieStore"] + + +class MemoryAcpCookieStore: + """A tiny name→value cookie store keyed by cookie name.""" + + def __init__(self) -> None: + self._cookies: dict[str, str] = {} + + def store_set_cookie(self, header_value: str) -> None: + """Ingest a single ``Set-Cookie`` header value. + + Only the leading ``name=value`` pair is retained; cookie attributes + (``; Path=/``, ``; HttpOnly`` etc.) are ignored. + """ + first = header_value.split(";", 1)[0].strip() + if not first or "=" not in first: + return + name, _, value = first.partition("=") + name = name.strip() + if name: + self._cookies[name] = value.strip() + + def store_set_cookies(self, header_values: list[str]) -> None: + """Ingest multiple ``Set-Cookie`` header values.""" + for value in header_values: + self.store_set_cookie(value) + + def cookie_header(self) -> str | None: + """Render the stored cookies as a ``Cookie`` request header value.""" + if not self._cookies: + return None + return "; ".join(f"{name}={value}" for name, value in self._cookies.items()) + + def clear(self) -> None: + """Drop all stored cookies.""" + self._cookies.clear() + + def __len__(self) -> int: + return len(self._cookies) diff --git a/src/acp/_sse.py b/src/acp/_sse.py new file mode 100644 index 0000000..455a2d2 --- /dev/null +++ b/src/acp/_sse.py @@ -0,0 +1,84 @@ +"""Server-Sent Events (SSE) serialization + parsing building blocks. + +Minimal helpers shared by the Streamable HTTP client and server. We only need +the ``data:`` field (JSON-RPC payloads) plus keepalive comments; ``event:``, +``id:``, and ``retry:`` are not used by this transport (resumability is v2). +""" + +from __future__ import annotations + +import json +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from collections.abc import AsyncIterator + +__all__ = [ + "parse_sse_stream", + "serialize_sse_event", + "serialize_sse_keepalive", +] + + +def serialize_sse_event(message: dict[str, Any]) -> bytes: + """Serialize a JSON-RPC message as an SSE ``data:`` event. + + The payload is JSON-encoded on a single line and terminated by a blank line, + per the SSE framing rules. + """ + data = json.dumps(message, separators=(",", ":")) + return f"data: {data}\n\n".encode() + + +def serialize_sse_keepalive() -> bytes: + """Serialize an SSE comment used to keep the connection alive.""" + return b": keepalive\n\n" + + +def _decode_event(data_lines: list[str]) -> dict[str, Any] | None: + """Decode buffered ``data:`` lines into a JSON object, or None to skip.""" + payload = "\n".join(data_lines) + if not payload: + return None + try: + return json.loads(payload) + except json.JSONDecodeError: + return None + + +def _append_field(line: str, data_lines: list[str]) -> None: + """Append a ``data:`` field's value to the buffer; ignore other fields.""" + field, _, value = line.partition(":") + if value.startswith(" "): + value = value[1:] + if field == "data": + data_lines.append(value) + + +async def parse_sse_stream(chunks: AsyncIterator[bytes]) -> AsyncIterator[dict[str, Any]]: + """Parse an SSE byte stream, yielding decoded JSON-RPC ``data:`` payloads. + + Comments (lines starting with ``:``) and non-``data`` fields are ignored. + Multi-line ``data:`` fields are concatenated with newlines per the spec. A + blank line dispatches the buffered event. + """ + buffer = "" + data_lines: list[str] = [] + + async for chunk in chunks: + buffer += chunk.decode("utf-8") + while "\n" in buffer: + line, buffer = buffer.split("\n", 1) + line = line.rstrip("\r") + if line == "": + event = _decode_event(data_lines) + data_lines = [] + if event is not None: + yield event + elif not line.startswith(":"): + _append_field(line, data_lines) + + # Flush a trailing event with no terminating blank line. + event = _decode_event(data_lines) + if event is not None: + yield event diff --git a/src/acp/_transport.py b/src/acp/_transport.py new file mode 100644 index 0000000..17c2815 --- /dev/null +++ b/src/acp/_transport.py @@ -0,0 +1,151 @@ +"""Message-level transport seam for :class:`acp.connection.Connection`. + +Historically the connection spoke directly to ``asyncio`` byte streams with +newline framing. To support message-oriented remote transports (Streamable +HTTP + WebSocket) we introduce a small :class:`Transport` protocol that moves +JSON-RPC *messages* (already-decoded ``dict`` payloads) instead of bytes. + +The existing stdio path is re-expressed on top of this seam via +:class:`NdjsonTransport`, which wraps the current byte-stream framing so there +is **zero behaviour change** for stdio users. :func:`memory_transport_pair` +gives two linked in-memory transports, used by the HTTP/WS server to bind an +``AgentSideConnection`` to its message pump. +""" + +from __future__ import annotations + +import asyncio +import contextlib +import json +import logging +from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable + +if TYPE_CHECKING: + from collections.abc import Awaitable + + from .task import MessageSender + +__all__ = [ + "NdjsonTransport", + "Transport", + "memory_transport_pair", +] + + +@runtime_checkable +class Transport(Protocol): + """A bidirectional stream of JSON-RPC messages. + + Implementations move already-decoded ``dict`` payloads. ``receive`` returns + ``None`` to signal end-of-stream (EOF). ``send`` may raise if the message + could not be delivered (e.g. an HTTP POST failing before any JSON-RPC + response exists); callers correlate such failures with pending requests. + """ + + async def send(self, message: dict[str, Any]) -> None: ... + + async def receive(self) -> dict[str, Any] | None: ... + + async def close(self) -> None: ... + + +class NdjsonTransport: + """Transport backed by newline-delimited JSON over asyncio byte streams. + + This preserves the exact framing, buffer-limit-overrun handling, and receive + timeout semantics that previously lived inside ``Connection`` so that stdio + behaviour is byte-for-byte unchanged. + """ + + def __init__( + self, + reader: asyncio.StreamReader, + sender: MessageSender, + *, + receive_timeout: float | None = None, + ) -> None: + self._reader = reader + self._sender = sender + self._receive_timeout = receive_timeout + + async def send(self, message: dict[str, Any]) -> None: + await self._sender.send(message) + + async def receive(self) -> dict[str, Any] | None: + while True: + line = await self._read_line() + if not line: + return None + line = line.strip() + if not line: + continue + try: + message: dict[str, Any] = json.loads(line) + except Exception: + logging.exception("Error parsing JSON-RPC message") + continue + return message + + async def close(self) -> None: + await self._sender.close() + + async def _read_line(self) -> bytes: + chunks: list[bytes] = [] + try: + while True: + try: + line = await self._wait_for_reader(self._reader.readuntil(b"\n")) + except asyncio.LimitOverrunError as exc: + chunks.append(await self._wait_for_reader(self._reader.readexactly(exc.consumed))) + else: + chunks.append(line) + return b"".join(chunks) + except asyncio.IncompleteReadError as exc: + chunks.append(exc.partial) + return b"".join(chunks) + + async def _wait_for_reader(self, awaitable: Awaitable[bytes]) -> bytes: + return await asyncio.wait_for(awaitable, timeout=self._receive_timeout) + + +class _MemoryTransport: + """One end of an in-process :func:`memory_transport_pair`.""" + + def __init__( + self, + outbox: asyncio.Queue[dict[str, Any] | None], + inbox: asyncio.Queue[dict[str, Any] | None], + ) -> None: + self._outbox = outbox + self._inbox = inbox + self._closed = False + + async def send(self, message: dict[str, Any]) -> None: + if self._closed: + raise ConnectionError("Transport closed") + await self._outbox.put(dict(message)) + + async def receive(self) -> dict[str, Any] | None: + return await self._inbox.get() + + async def close(self) -> None: + if self._closed: + return + self._closed = True + with contextlib.suppress(Exception): + self._outbox.put_nowait(None) + + +def memory_transport_pair() -> tuple[Transport, Transport]: + """Return two linked in-memory transports. + + A message ``send`` on one end becomes available via ``receive`` on the + other. Closing an end enqueues an EOF (``None``) for its peer. This mirrors + the ``TransformStream`` pair the TypeScript SDK uses to bind a server-side + connection to its HTTP/WS message pump. + """ + a_to_b: asyncio.Queue[dict[str, Any] | None] = asyncio.Queue() + b_to_a: asyncio.Queue[dict[str, Any] | None] = asyncio.Queue() + left = _MemoryTransport(outbox=a_to_b, inbox=b_to_a) + right = _MemoryTransport(outbox=b_to_a, inbox=a_to_b) + return left, right diff --git a/src/acp/agent/connection.py b/src/acp/agent/connection.py index bd8c176..a3921e3 100644 --- a/src/acp/agent/connection.py +++ b/src/acp/agent/connection.py @@ -6,6 +6,7 @@ from pydantic import TypeAdapter +from .._transport import Transport from ..connection import Connection from ..interfaces import Agent, Client from ..meta import CLIENT_METHODS @@ -79,17 +80,24 @@ def __init__( self, to_agent: Callable[[Client], Agent] | Agent, input_stream: Any, - output_stream: Any, + output_stream: Any = None, listening: bool = True, *, use_unstable_protocol: bool = False, **connection_kwargs: Any, ) -> None: agent = to_agent(self) if callable(to_agent) else to_agent - if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance(output_stream, asyncio.StreamReader): - raise TypeError(_AGENT_CONNECTION_ERROR) handler = build_agent_router(cast(Agent, agent), use_unstable_protocol=use_unstable_protocol) - self._conn = Connection(handler, input_stream, output_stream, listening=listening, **connection_kwargs) + if isinstance(input_stream, Transport): + if output_stream is not None: + raise TypeError(_AGENT_CONNECTION_ERROR) + self._conn = Connection(handler, input_stream, listening=listening, **connection_kwargs) + else: + if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance( + output_stream, asyncio.StreamReader + ): + raise TypeError(_AGENT_CONNECTION_ERROR) + self._conn = Connection(handler, input_stream, output_stream, listening=listening, **connection_kwargs) if on_connect := getattr(agent, "on_connect", None): on_connect(self) diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 0f3b1cf..81f6769 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -4,6 +4,7 @@ from collections.abc import Callable from typing import Any, cast, final +from .._transport import Transport from ..connection import Connection from ..interfaces import Agent, Client from ..meta import AGENT_METHODS @@ -62,16 +63,23 @@ def __init__( self, to_client: Callable[[Agent], Client] | Client, input_stream: Any, - output_stream: Any, + output_stream: Any = None, *, use_unstable_protocol: bool = False, **connection_kwargs: Any, ) -> None: - if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance(output_stream, asyncio.StreamReader): - raise TypeError(_CLIENT_CONNECTION_ERROR) client = to_client(self) if callable(to_client) else to_client handler = build_client_router(cast(Client, client), use_unstable_protocol=use_unstable_protocol) - self._conn = Connection(handler, input_stream, output_stream, **connection_kwargs) + if isinstance(input_stream, Transport): + if output_stream is not None: + raise TypeError(_CLIENT_CONNECTION_ERROR) + self._conn = Connection(handler, input_stream, **connection_kwargs) + else: + if not isinstance(input_stream, asyncio.StreamWriter) or not isinstance( + output_stream, asyncio.StreamReader + ): + raise TypeError(_CLIENT_CONNECTION_ERROR) + self._conn = Connection(handler, input_stream, output_stream, **connection_kwargs) if on_connect := getattr(client, "on_connect", None): on_connect(self) diff --git a/src/acp/connection.py b/src/acp/connection.py index 41cdebc..cfd7b5c 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -8,10 +8,11 @@ from collections.abc import Awaitable, Callable from dataclasses import dataclass from enum import Enum -from typing import Any +from typing import Any, cast from pydantic import BaseModel, ValidationError +from ._transport import NdjsonTransport, Transport from .exceptions import RequestError from .task import ( DefaultMessageDispatcher, @@ -63,8 +64,8 @@ class Connection: def __init__( self, handler: MethodHandler, - writer: asyncio.StreamWriter, - reader: asyncio.StreamReader, + writer: asyncio.StreamWriter | Transport, + reader: asyncio.StreamReader | None = None, *, queue: MessageQueue | None = None, state_store: MessageStateStore | None = None, @@ -75,8 +76,6 @@ def __init__( receive_timeout: float | None = None, ) -> None: self._handler = handler - self._writer = writer - self._reader = reader self._next_request_id = 0 self._state = state_store or InMemoryMessageStateStore() self._tasks = TaskSupervisor(source="acp.Connection") @@ -84,9 +83,18 @@ def __init__( self._queue = queue or InMemoryMessageQueue() self._closed = False self._disconnected = False - self._sender = (sender_factory or self._default_sender_factory)(self._writer, self._tasks) + # Two construction forms: + # * message-level: ``Connection(handler, transport)`` (reader omitted) + # * byte-level: ``Connection(handler, writer, reader)`` (stdio path) + # We discriminate on ``reader`` rather than ``isinstance(writer, Transport)`` + # because a runtime-checkable Protocol would spuriously match duck-typed + # test doubles (e.g. ``MagicMock``). + if reader is None: + self._transport: Transport = cast("Transport", writer) + else: + sender = (sender_factory or self._default_sender_factory)(cast("asyncio.StreamWriter", writer), self._tasks) + self._transport = NdjsonTransport(reader, sender, receive_timeout=receive_timeout) self._observers: list[StreamObserver] = list(observers or []) - self._receive_timeout = receive_timeout if listening: self._recv_task = self._tasks.create( self._receive_loop(), @@ -111,7 +119,7 @@ async def close(self) -> None: return self._closed = True await self._dispatcher.stop() - await self._sender.close() + await self._transport.close() await self._tasks.shutdown() self._state.reject_all_outgoing(ConnectionError("Connection closed")) @@ -139,30 +147,29 @@ async def send_request(self, method: str, params: JsonValue | None = None) -> An self._next_request_id += 1 future = self._state.register_outgoing(request_id, method) payload = {"jsonrpc": "2.0", "id": request_id, "method": method, "params": params} - await self._sender.send(payload) + try: + await self._transport.send(payload) + except Exception as exc: + # A synchronous send failure (e.g. HTTP POST rejected before any + # JSON-RPC response exists) must reject the correlated future so the + # caller gets a real, attributable error. + self._state.reject_outgoing(request_id, exc) + raise self._notify_observers(StreamDirection.OUTGOING, payload) return await future async def send_notification(self, method: str, params: JsonValue | None = None) -> None: self._raise_if_unavailable() payload = {"jsonrpc": "2.0", "method": method, "params": params} - await self._sender.send(payload) + await self._transport.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) async def _receive_loop(self) -> None: try: while True: - line = await self._read_line() - if not line: + message = await self._transport.receive() + if message is None: break - line = line.strip() - if not line: - continue - try: - message: dict[str, Any] = json.loads(line) - except Exception: - logging.exception("Error parsing JSON-RPC message") - continue self._notify_observers(StreamDirection.INCOMING, message) await self._process_message(message) except asyncio.CancelledError: @@ -171,24 +178,6 @@ async def _receive_loop(self) -> None: raise RequestError.internal_error({"details": "Agent timeout"}) from None self._disconnect() - async def _read_line(self) -> bytes: - chunks: list[bytes] = [] - try: - while True: - try: - line = await self._wait_for_reader(self._reader.readuntil(b"\n")) - except asyncio.LimitOverrunError as exc: - chunks.append(await self._wait_for_reader(self._reader.readexactly(exc.consumed))) - else: - chunks.append(line) - return b"".join(chunks) - except asyncio.IncompleteReadError as exc: - chunks.append(exc.partial) - return b"".join(chunks) - - async def _wait_for_reader(self, awaitable: Awaitable[bytes]) -> bytes: - return await asyncio.wait_for(awaitable, timeout=self._receive_timeout) - async def _process_message(self, message: dict[str, Any]) -> None: method = message.get("method") has_id = "id" in message @@ -239,18 +228,18 @@ async def _run_request(self, message: dict[str, Any]) -> Any: exclude_unset=True, ) payload["result"] = result if result is not None else None - await self._sender.send(payload) + await self._transport.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) return payload.get("result") except RequestError as exc: payload["error"] = exc.to_error_obj() - await self._sender.send(payload) + await self._transport.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) raise except ValidationError as exc: err = RequestError.invalid_params({"errors": exc.errors()}) payload["error"] = err.to_error_obj() - await self._sender.send(payload) + await self._transport.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) raise err from None except Exception as exc: @@ -265,7 +254,7 @@ async def _run_request(self, message: dict[str, Any]) -> Any: data = {"details": str(exc)} err = RequestError.internal_error(data) payload["error"] = err.to_error_obj() - await self._sender.send(payload) + await self._transport.send(payload) self._notify_observers(StreamDirection.OUTGOING, payload) raise err from None diff --git a/src/acp/core.py b/src/acp/core.py index 2d280c6..d42b164 100644 --- a/src/acp/core.py +++ b/src/acp/core.py @@ -79,17 +79,26 @@ async def run_agent( def connect_to_agent( client: Client, input_stream: Any, - output_stream: Any, + output_stream: Any = None, *, use_unstable_protocol: bool = False, **connection_kwargs: Any, ) -> ClientSideConnection: - """Create a ClientSideConnection to an ACP agent over the given input/output streams. + """Create a ClientSideConnection to an ACP agent. + + Two forms are supported: + + * **Byte streams (stdio):** pass ``input_stream`` (an ``asyncio.StreamWriter``) + and ``output_stream`` (an ``asyncio.StreamReader``). + * **Message transport (HTTP/WebSocket):** pass a single + :class:`~acp._transport.Transport` as ``input_stream`` and leave + ``output_stream`` as ``None``. Args: client: The client implementation to use. - input_stream: The (agent) input stream to write to (default: ``sys.stdin``). - output_stream: The (agent) output stream to read from (default: ``sys.stdout``). + input_stream: The agent input stream (``StreamWriter``) or a ``Transport``. + output_stream: The agent output stream (``StreamReader``), or ``None`` when + passing a ``Transport``. use_unstable_protocol: Whether to enable unstable protocol features. **connection_kwargs: Additional keyword arguments to pass to the :class:`ClientSideConnection` constructor. diff --git a/src/acp/http/__init__.py b/src/acp/http/__init__.py new file mode 100644 index 0000000..7529047 --- /dev/null +++ b/src/acp/http/__init__.py @@ -0,0 +1,30 @@ +"""Streamable HTTP transport for ACP (experimental). + +Public exports are import-guarded: the heavy client/server implementations pull +in optional dependencies (``httpx[http2]``). Importing a symbol without the +extra installed raises a friendly ``ImportError`` pointing at +``pip install agent-client-protocol[http]``. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +__all__ = ["AcpServer", "create_http_stream"] + +if TYPE_CHECKING: + from .client import create_http_stream + from .server import AcpServer + + +def __getattr__(name: str) -> Any: + if name == "create_http_stream": + from .client import create_http_stream + + return create_http_stream + if name == "AcpServer": + from .server import AcpServer + + return AcpServer + msg = f"module {__name__!r} has no attribute {name!r}" + raise AttributeError(msg) diff --git a/src/acp/http/asgi.py b/src/acp/http/asgi.py new file mode 100644 index 0000000..7dbd5f8 --- /dev/null +++ b/src/acp/http/asgi.py @@ -0,0 +1,175 @@ +"""Thin ASGI adapter bridging Starlette/FastAPI/Hypercorn to :class:`AcpServer`. + +``create_asgi_app(agent_factory)`` returns an ASGI 3.0 application callable that +handles POST/GET/DELETE (and WebSocket upgrades) on the ACP endpoint. Users can +mount it directly or wrap it in their framework of choice. + +Note: for a spec-compliant Streamable HTTP server, run this under an +HTTP/2-capable ASGI server (Hypercorn, Daphne, Granian) or terminate HTTP/2 at a +proxy. Uvicorn does not serve HTTP/2 (WebSocket still works). +""" + +from __future__ import annotations + +import json +from collections.abc import Callable +from typing import TYPE_CHECKING, Any + +from .protocol import CONNECTION_ID_HEADER, CONTENT_TYPE_SSE, SESSION_ID_HEADER +from .server import AcpServer + +if TYPE_CHECKING: + from .server import AgentFactory + +__all__ = ["AcpAsgiApp", "create_asgi_app"] + +_JSON_HEADERS = [(b"content-type", b"application/json")] + + +def _header_lookup(scope_headers: list[tuple[bytes, bytes]], name: str) -> str | None: + target = name.lower().encode() + for key, value in scope_headers: + if key.lower() == target: + return value.decode("latin-1") + return None + + +class AcpAsgiApp: + """ASGI application wrapping an :class:`AcpServer`.""" + + def __init__(self, server: AcpServer) -> None: + self._server = server + + async def __call__(self, scope: dict[str, Any], receive: Callable, send: Callable) -> None: + scope_type = scope["type"] + if scope_type == "lifespan": + await self._handle_lifespan(receive, send) + return + if scope_type == "websocket": + await self._handle_websocket(scope, receive, send) + return + if scope_type != "http": + return + + method = scope["method"] + if method == "POST": + await self._handle_post(scope, receive, send) + elif method == "GET": + await self._handle_get(scope, receive, send) + elif method == "DELETE": + await self._handle_delete(scope, send) + else: + await self._send_json(send, 405, {"error": "Method not allowed"}) + + async def _handle_lifespan(self, receive: Callable, send: Callable) -> None: + while True: + message = await receive() + if message["type"] == "lifespan.startup": + await send({"type": "lifespan.startup.complete"}) + elif message["type"] == "lifespan.shutdown": + await self._server.close() + await send({"type": "lifespan.shutdown.complete"}) + return + + async def _read_body(self, receive: Callable) -> bytes: + chunks: list[bytes] = [] + while True: + message = await receive() + if message["type"] == "http.request": + chunks.append(message.get("body", b"")) + if not message.get("more_body", False): + break + elif message["type"] == "http.disconnect": + break + return b"".join(chunks) + + async def _handle_post(self, scope: dict[str, Any], receive: Callable, send: Callable) -> None: + headers = scope["headers"] + content_type = _header_lookup(headers, "content-type") + connection_id = _header_lookup(headers, CONNECTION_ID_HEADER) + session_id = _header_lookup(headers, SESSION_ID_HEADER) + raw = await self._read_body(receive) + try: + message = json.loads(raw) if raw else None + except json.JSONDecodeError: + await self._send_json(send, 400, {"error": "Invalid JSON"}) + return + result = await self._server.handle_post( + message, + content_type=content_type, + connection_id=connection_id, + session_id=session_id, + ) + await self._send_json(send, result.status, result.body, extra_headers=result.headers) + + async def _handle_get(self, scope: dict[str, Any], receive: Callable, send: Callable) -> None: + headers = scope["headers"] + upgrade = _header_lookup(headers, "upgrade") + if upgrade is not None and upgrade.lower() == "websocket": + # WebSocket upgrades arrive as scope type "websocket" in ASGI; a GET + # http scope with Upgrade is non-standard, so reject clearly. + await self._send_json(send, 400, {"error": "WebSocket upgrade must use the ws scope"}) + return + accept = _header_lookup(headers, "accept") or "" + if CONTENT_TYPE_SSE not in accept and "*/*" not in accept: + await self._send_json(send, 406, {"error": "Accept must include text/event-stream"}) + return + connection_id = _header_lookup(headers, CONNECTION_ID_HEADER) + session_id = _header_lookup(headers, SESSION_ID_HEADER) + error = self._server.validate_stream(connection_id=connection_id, session_id=session_id) + if error is not None: + await self._send_json(send, error.status, error.body) + return + if connection_id is None: # validated above, narrow for type-checker + await self._send_json(send, 400, {"error": "Missing connection id"}) + return + await send({ + "type": "http.response.start", + "status": 200, + "headers": [ + (b"content-type", CONTENT_TYPE_SSE.encode()), + (b"cache-control", b"no-cache"), + (b"connection", b"keep-alive"), + ], + }) + async for frame in self._server.open_stream(connection_id=connection_id, session_id=session_id): + await send({"type": "http.response.body", "body": frame, "more_body": True}) + await send({"type": "http.response.body", "body": b"", "more_body": False}) + + async def _handle_delete(self, scope: dict[str, Any], send: Callable) -> None: + connection_id = _header_lookup(scope["headers"], CONNECTION_ID_HEADER) + result = await self._server.handle_delete(connection_id=connection_id) + await self._send_json(send, result.status, result.body, extra_headers=result.headers) + + async def _handle_websocket(self, scope: dict[str, Any], receive: Callable, send: Callable) -> None: + from ..ws.server import handle_asgi_websocket + + await handle_asgi_websocket(self._server, scope, receive, send) + + async def _send_json( + self, + send: Callable, + status: int, + body: dict[str, Any] | None, + *, + extra_headers: dict[str, str] | None = None, + ) -> None: + payload = json.dumps(body).encode() if body is not None else b"" + headers = list(_JSON_HEADERS) + if extra_headers: + headers.extend((k.encode("latin-1"), v.encode("latin-1")) for k, v in extra_headers.items()) + await send({"type": "http.response.start", "status": status, "headers": headers}) + await send({"type": "http.response.body", "body": payload}) + + +def create_asgi_app(agent_factory: AgentFactory) -> AcpAsgiApp: + """Create an ASGI app serving an ACP agent over Streamable HTTP + WebSocket. + + Args: + agent_factory: Called once per connection with the bound + ``AgentSideConnection`` to produce a per-connection ``Agent``. + + Returns: + An :class:`AcpAsgiApp` ASGI 3.0 application. + """ + return AcpAsgiApp(AcpServer(agent_factory)) diff --git a/src/acp/http/client.py b/src/acp/http/client.py new file mode 100644 index 0000000..b224167 --- /dev/null +++ b/src/acp/http/client.py @@ -0,0 +1,238 @@ +"""Streamable HTTP client transport (port of #155 ``http-stream.ts``, minus retry). + +``create_http_stream(url, ...)`` returns a :class:`~acp._transport.Transport` +that can be handed to :func:`acp.connect_to_agent`. The flow: + +* The first message MUST be ``initialize``: POSTed as ``application/json``, + expecting ``200 OK`` + an ``Acp-Connection-Id`` response header. The JSON body + is enqueued back into ``receive()`` so the core correlates it by ``id``. +* Subsequent messages are POSTed with the connection id (+ session id header for + session-scoped methods) and return ``202 Accepted``. +* After ``initialize`` the client opens the connection-scoped SSE stream (GET); + when it sees a new ``sessionId`` it opens that session-scoped SSE stream too. +* Server→client messages arrive on those SSE streams, merged into one + ``receive()`` feed. Order is preserved within a stream, interleaved across. +* A single SSE attempt is made per stream; on EOF/closure the reader surfaces + end-of-stream (no auto-retry — that is the caller's responsibility). +* ``close()`` aborts in-flight streams and DELETEs the connection. +""" + +from __future__ import annotations + +import asyncio +import contextlib +from typing import TYPE_CHECKING, Any + +from .._sse import parse_sse_stream +from .protocol import ( + CONNECTION_ID_HEADER, + CONTENT_TYPE_JSON, + CONTENT_TYPE_SSE, + SESSION_ID_HEADER, + is_initialize_request, + method_requires_session_header, + session_id_from_message, +) + +try: + import httpx +except ImportError as exc: # pragma: no cover - exercised via import guard message + msg = "The Streamable HTTP transport requires the 'http' extra: pip install agent-client-protocol[http]" + raise ImportError(msg) from exc + +if TYPE_CHECKING: + from collections.abc import AsyncIterator + + from .._transport import Transport + +__all__ = ["AcpHttpStatusError", "create_http_stream"] + +_EOF = object() + + +class AcpHttpStatusError(RuntimeError): + """Raised when an HTTP request returns an unexpected status code.""" + + def __init__(self, status_code: int, message: str) -> None: + super().__init__(f"HTTP {status_code}: {message}") + self.status_code = status_code + + +class _HttpStreamTransport: + """Streamable HTTP client transport implementing the :class:`Transport` protocol.""" + + def __init__( + self, + url: str, + *, + client: httpx.AsyncClient, + owns_client: bool, + headers: dict[str, str] | None = None, + ) -> None: + self._url = url + self._client = client + self._owns_client = owns_client + self._extra_headers = dict(headers or {}) + self._connection_id: str | None = None + self._closed = False + self._inbox: asyncio.Queue[Any] = asyncio.Queue() + self._stream_tasks: set[asyncio.Task[None]] = set() + self._session_streams: set[str] = set() + + # -- Transport protocol ------------------------------------------------- + + async def send(self, message: dict[str, Any]) -> None: + if self._closed: + raise ConnectionError("Transport closed") + if is_initialize_request(message): + await self._send_initialize(message) + return + await self._send_post(message) + + async def receive(self) -> dict[str, Any] | None: + item = await self._inbox.get() + if item is _EOF: + return None + return item + + async def close(self) -> None: + if self._closed: + return + self._closed = True + for task in list(self._stream_tasks): + task.cancel() + for task in list(self._stream_tasks): + with contextlib.suppress(asyncio.CancelledError, Exception): + await task + self._stream_tasks.clear() + if self._connection_id is not None: + with contextlib.suppress(Exception): + await self._client.request( + "DELETE", + self._url, + headers={CONNECTION_ID_HEADER: self._connection_id, **self._extra_headers}, + ) + if self._owns_client: + with contextlib.suppress(Exception): + await self._client.aclose() + self._inbox.put_nowait(_EOF) + + # -- Internals ---------------------------------------------------------- + + async def _send_initialize(self, message: dict[str, Any]) -> None: + headers = {"Content-Type": CONTENT_TYPE_JSON, **self._extra_headers} + response = await self._client.post(self._url, json=message, headers=headers) + if response.status_code != 200: + raise AcpHttpStatusError(response.status_code, "initialize failed") + connection_id = response.headers.get(CONNECTION_ID_HEADER) + if not connection_id: + raise AcpHttpStatusError(response.status_code, f"missing {CONNECTION_ID_HEADER} header") + self._connection_id = connection_id + body = response.json() + # Enqueue the initialize result so the core correlates it by id. + self._inbox.put_nowait(body) + # Open the connection-scoped SSE stream. + self._open_stream(session_id=None) + + async def _send_post(self, message: dict[str, Any]) -> None: + if self._connection_id is None: + raise ConnectionError("Cannot send before initialize established a connection id") + headers = {"Content-Type": CONTENT_TYPE_JSON, CONNECTION_ID_HEADER: self._connection_id, **self._extra_headers} + method = message.get("method") + session_id = session_id_from_message(message) + if method_requires_session_header(method) and session_id is not None: + headers[SESSION_ID_HEADER] = session_id + response = await self._client.post(self._url, json=message, headers=headers) + if response.status_code not in (200, 202): + raise AcpHttpStatusError(response.status_code, f"POST {method} failed") + # Some servers may answer initialize-like 200 bodies; for 200 with a body enqueue it. + if response.status_code == 200 and response.content: + with contextlib.suppress(Exception): + self._inbox.put_nowait(response.json()) + + def _open_stream(self, *, session_id: str | None) -> None: + if self._closed: + return + if session_id is not None: + if session_id in self._session_streams: + return + self._session_streams.add(session_id) + task = asyncio.ensure_future(self._consume_stream(session_id=session_id)) + self._stream_tasks.add(task) + task.add_done_callback(self._stream_tasks.discard) + + async def _consume_stream(self, *, session_id: str | None) -> None: + if self._connection_id is None: + return + headers = { + "Accept": CONTENT_TYPE_SSE, + CONNECTION_ID_HEADER: self._connection_id, + **self._extra_headers, + } + if session_id is not None: + headers[SESSION_ID_HEADER] = session_id + try: + async with self._client.stream("GET", self._url, headers=headers) as response: + if response.status_code != 200: + return + async for event in parse_sse_stream(_aiter_raw(response)): + self._handle_incoming(event) + except (httpx.HTTPError, asyncio.CancelledError): + return + finally: + self._on_stream_closed(session_id) + + def _on_stream_closed(self, session_id: str | None) -> None: + """Handle a stream reader terminating (EOF, non-200, or error). + + A dropped/ended **connection-scoped** stream is the client's only channel + for connection-level server→client messages, so its loss is surfaced as + end-of-stream: ``receive()`` returns ``None``, the core's receive loop + exits, and pending requests are rejected instead of hanging forever. v1 + does not auto-reconnect — that is the host's responsibility — but the + disconnect must be observable. Session-scoped streams may legitimately + close, so their EOF is not treated as a connection-level disconnect. + """ + if session_id is not None: + self._session_streams.discard(session_id) + return + if not self._closed: + self._inbox.put_nowait(_EOF) + + def _handle_incoming(self, message: dict[str, Any]) -> None: + # Open a session-scoped stream when any message carries a new sessionId + # (e.g. a session/new or session/load result on the connection stream). + session_id = session_id_from_message(message) + if session_id is not None and session_id not in self._session_streams: + self._open_stream(session_id=session_id) + self._inbox.put_nowait(message) + + +async def _aiter_raw(response: httpx.Response) -> AsyncIterator[bytes]: + async for chunk in response.aiter_bytes(): + yield chunk + + +def create_http_stream( + url: str, + *, + client: httpx.AsyncClient | None = None, + headers: dict[str, str] | None = None, +) -> Transport: + """Create a Streamable HTTP client :class:`Transport`. + + Args: + url: The ACP endpoint URL (e.g. ``https://host/acp``). + client: An optional pre-configured ``httpx.AsyncClient``. If omitted, an + HTTP/2-enabled client with a cookie jar is created and owned by the + transport (closed on ``close()``). + headers: Extra headers sent on every request. + + Returns: + A :class:`Transport` usable with :func:`acp.connect_to_agent`. + """ + owns_client = client is None + if client is None: + # SSE GET streams are long-lived, so disable read timeouts by default. + client = httpx.AsyncClient(http2=True, timeout=httpx.Timeout(None)) + return _HttpStreamTransport(url, client=client, owns_client=owns_client, headers=headers) diff --git a/src/acp/http/protocol.py b/src/acp/http/protocol.py new file mode 100644 index 0000000..c15fdb4 --- /dev/null +++ b/src/acp/http/protocol.py @@ -0,0 +1,106 @@ +"""Protocol constants and JSON-RPC routing helpers for the HTTP/WS transport. + +Ports the small helpers from #155's ``protocol.ts`` + ``jsonrpc.ts``: header +names, MIME types, endpoint path, and pure functions that classify JSON-RPC +messages and extract routing keys (``id`` normalization, ``sessionId``). +""" + +from __future__ import annotations + +from typing import Any + +from ..meta import AGENT_METHODS + +__all__ = [ + "ACP_ENDPOINT_PATH", + "CONNECTION_ID_HEADER", + "CONTENT_TYPE_JSON", + "CONTENT_TYPE_SSE", + "INITIALIZE_METHOD", + "SESSION_ID_HEADER", + "is_initialize_request", + "is_response_message", + "message_id_key", + "method_requires_session_header", + "session_id_from_message", + "session_id_from_params", + "session_id_from_result", +] + +# Header names (case-insensitive on the wire; we normalize to these spellings). +CONNECTION_ID_HEADER = "Acp-Connection-Id" +SESSION_ID_HEADER = "Acp-Session-Id" + +# MIME types. +CONTENT_TYPE_JSON = "application/json" +CONTENT_TYPE_SSE = "text/event-stream" + +# Endpoint path used by docs/examples (the adapter itself is path-agnostic). +ACP_ENDPOINT_PATH = "/acp" + +INITIALIZE_METHOD = AGENT_METHODS["initialize"] + +# Agent methods that operate on an *already-established* session and therefore +# require the ``Acp-Session-Id`` header on POST + session-scoped routing of their +# response on GET. Methods that mint/attach a session id (``session/new``, +# ``session/load``, ``session/fork``, ``session/resume``) are deliberately +# excluded: per the RFD their responses come back on the connection-scoped stream +# because the client does not yet have the session-scoped stream open. +# ``session/list`` is connection-level. +_SESSION_SCOPED_METHODS = frozenset({ + AGENT_METHODS["session_set_mode"], + AGENT_METHODS["session_set_config_option"], + AGENT_METHODS["session_prompt"], + AGENT_METHODS["session_cancel"], + AGENT_METHODS["session_close"], +}) + + +def is_initialize_request(message: dict[str, Any]) -> bool: + """True if the message is an ``initialize`` JSON-RPC request.""" + return message.get("method") == INITIALIZE_METHOD and "id" in message + + +def is_response_message(message: dict[str, Any]) -> bool: + """True if the message is a JSON-RPC response (has ``id`` and no ``method``).""" + return "id" in message and "method" not in message + + +def method_requires_session_header(method: str | None) -> bool: + """True if a POST for ``method`` must carry the ``Acp-Session-Id`` header.""" + return method in _SESSION_SCOPED_METHODS + + +def message_id_key(message_id: Any) -> str | None: + """Normalize a JSON-RPC ``id`` (int or str) to a stable string key. + + The Python core assigns integer request ids while the wire may echo them as + ints or strings; routing tables must key consistently. Returns ``None`` for + a missing id. + """ + if message_id is None: + return None + return str(message_id) + + +def session_id_from_params(params: Any) -> str | None: + """Extract ``sessionId`` from a request's ``params`` object, if present.""" + if isinstance(params, dict): + session_id = params.get("sessionId") + if isinstance(session_id, str): + return session_id + return None + + +def session_id_from_result(result: Any) -> str | None: + """Extract ``sessionId`` from a response's ``result`` object, if present.""" + if isinstance(result, dict): + session_id = result.get("sessionId") + if isinstance(session_id, str): + return session_id + return None + + +def session_id_from_message(message: dict[str, Any]) -> str | None: + """Extract a ``sessionId`` from either a request's params or a response's result.""" + return session_id_from_params(message.get("params")) or session_id_from_result(message.get("result")) diff --git a/src/acp/http/server.py b/src/acp/http/server.py new file mode 100644 index 0000000..6c4f00f --- /dev/null +++ b/src/acp/http/server.py @@ -0,0 +1,461 @@ +"""Framework-agnostic Streamable HTTP server core (port of #155 server.ts + connection.ts). + +:class:`AcpServer` owns an in-memory :class:`ConnectionRegistry`. For each +``initialize`` POST it mints a connection, binds an ``AgentSideConnection`` to an +in-memory transport pair, and returns an ``Acp-Connection-Id``. Subsequent +server→client messages produced by the agent are fanned out to the correct SSE +stream (connection-scoped or session-scoped) based on their ``sessionId`` / +correlated request id. + +The core exposes small, transport-neutral entry points: + +* :meth:`AcpServer.handle_post` — returns a :class:`PostResult` (status + body). +* :meth:`AcpServer.open_stream` — returns an async byte iterator of SSE frames. +* :meth:`AcpServer.handle_delete` — terminates a connection. + +The ASGI adapter in :mod:`acp.http.asgi` maps these onto ASGI messages. +""" + +from __future__ import annotations + +import asyncio +import contextlib +import uuid +from collections.abc import Callable +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Any + +from .._sse import serialize_sse_event, serialize_sse_keepalive +from .._transport import memory_transport_pair +from ..agent.connection import AgentSideConnection +from .protocol import ( + CONNECTION_ID_HEADER, + is_initialize_request, + is_response_message, + message_id_key, + method_requires_session_header, + session_id_from_params, + session_id_from_result, +) + +if TYPE_CHECKING: + from collections.abc import AsyncIterator + + from ..interfaces import Agent + +__all__ = [ + "AcpServer", + "AgentFactory", + "ConnectionRegistry", + "ConnectionState", + "OutboundStream", + "PostResult", +] + +AgentFactory = Callable[[AgentSideConnection], "Agent"] + +# How long an idle SSE stream waits before emitting a keepalive comment. Kept in +# sync with the TypeScript reference (15s) so intermediaries do not time out an +# otherwise-healthy but quiet stream. +SSE_KEEPALIVE_INTERVAL_SECONDS = 15.0 + +# How long ``initialize`` waits for the agent's response before giving up. The +# response is returned synchronously in the HTTP body, so a hung agent must not +# block the POST forever. +INITIALIZE_TIMEOUT_SECONDS = 30.0 + + +@dataclass +class PostResult: + """Outcome of a POST request.""" + + status: int + body: dict[str, Any] | None = None + headers: dict[str, str] = field(default_factory=dict) + + +class OutboundStream: + """A backpressure-aware buffer for server→client messages. + + Messages pushed before a subscriber attaches are buffered (bounded) and + replayed when :meth:`iterate` is first awaited. When the buffer is full, + :meth:`push` *awaits* until the consumer drains rather than dropping the + message — dropping a JSON-RPC response would permanently hang the peer's + pending request. Awaiting propagates backpressure up to the agent's message + pump, mirroring the ``ReadableStream`` backpressure in the TypeScript SDK. + """ + + def __init__(self, *, capacity: int = 1024) -> None: + self._queue: asyncio.Queue[dict[str, Any] | None] = asyncio.Queue(maxsize=capacity) + self._closed = asyncio.Event() + + async def push(self, message: dict[str, Any]) -> None: + if self._closed.is_set(): + return + putter = asyncio.ensure_future(self._queue.put(message)) + closed = asyncio.ensure_future(self._closed.wait()) + try: + await asyncio.wait({putter, closed}, return_when=asyncio.FIRST_COMPLETED) + finally: + # If the stream closed while we were blocked on a full queue, abandon + # the put; otherwise ensure the close-waiter task is cleaned up. + for task in (putter, closed): + if not task.done(): + task.cancel() + with contextlib.suppress(asyncio.CancelledError, Exception): + await task + + def close(self) -> None: + if self._closed.is_set(): + return + self._closed.set() + # Guarantee the consumer observes EOF even if the buffer is full: make + # room for the sentinel by dropping one buffered (tail) message, which is + # acceptable during teardown. + while not self._try_put_sentinel(): + with contextlib.suppress(asyncio.QueueEmpty): + self._queue.get_nowait() + + def _try_put_sentinel(self) -> bool: + try: + self._queue.put_nowait(None) + except asyncio.QueueFull: + return False + return True + + async def iterate(self) -> AsyncIterator[dict[str, Any]]: + while True: + message = await self._queue.get() + if message is None: + return + yield message + + +class ConnectionState: + """Owns an ``AgentSideConnection`` bound to an in-memory transport pair. + + The agent writes server→client messages onto the server end of the pair; a + pump task reads them and routes each to the connection-scoped stream or the + right session-scoped stream. + """ + + def __init__(self, connection_id: str, agent_factory: AgentFactory, *, multiplex: bool = False) -> None: + self.connection_id = connection_id + # ``server_side`` is what the AgentSideConnection talks over; ``pump_side`` + # is what we read agent→client traffic from and inject client→agent on. + server_side, pump_side = memory_transport_pair() + self._pump_side = pump_side + self._agent_conn = AgentSideConnection(agent_factory, server_side, listening=True) + self.connection_stream = OutboundStream() + self.session_streams: dict[str, OutboundStream] = {} + # WebSocket mode: multiplex *all* agent→client traffic onto one stream + # (the single socket) instead of splitting across SSE streams. + self._multiplex: OutboundStream | None = OutboundStream() if multiplex else None + # Maps a request id -> sessionId, so responses to session-scoped client + # requests route back onto the right session stream. + self._pending_routes: dict[str, str] = {} + # Request ids whose response should be captured (e.g. initialize) instead + # of being pushed to a stream. + self._response_waiters: dict[str, asyncio.Future[dict[str, Any]]] = {} + self._pump_task: asyncio.Task[None] | None = None + + def start(self) -> None: + self._pump_task = asyncio.ensure_future(self._pump()) + + async def _pump(self) -> None: + try: + while True: + message = await self._pump_side.receive() + if message is None: + return + await self._route_outbound(message) + except asyncio.CancelledError: + return + + async def _route_outbound(self, message: dict[str, Any]) -> None: + """Route an agent→client message to the correct SSE stream. + + Rules (matching the RFD): + + * A response to a session-*establishing* request (``session/new`` / + ``session/load`` — result carries a ``sessionId``) goes on the + **connection-scoped** stream, because the client does not yet have the + session-scoped stream open. We register the session so its stream can + be opened on the next GET. + * A response to an already-session-scoped client request routes onto that + session's stream (looked up via ``_pending_routes`` by request id). + * A server→client message carrying a ``sessionId`` in params (a + notification or request) routes onto that session's stream. + * Everything else goes on the connection-scoped stream. + """ + if is_response_message(message): + await self._route_response(message) + return + # Requests/notifications: route by sessionId in params if present. + if self._multiplex is not None: + await self._multiplex.push(message) + return + session_id = session_id_from_params(message.get("params")) + if session_id is not None and session_id in self.session_streams: + await self.session_streams[session_id].push(message) + return + await self.connection_stream.push(message) + + async def _route_response(self, message: dict[str, Any]) -> None: + key = message_id_key(message.get("id")) + # A captured response (e.g. initialize) resolves its waiter instead of + # being pushed to any stream. + if key is not None and key in self._response_waiters: + waiter = self._response_waiters.pop(key) + if not waiter.done(): + waiter.set_result(message) + return + # Register any newly-established session so unknown-session validation + # succeeds regardless of transport. + established = session_id_from_result(message.get("result")) + if established is not None: + self.ensure_session_stream(established) + routed = self._pending_routes.pop(key, None) if key is not None else None + if self._multiplex is not None: + await self._multiplex.push(message) + return + # session/new | session/load results (``established``) go on the + # connection-scoped stream; already-session-scoped responses route to the + # session stream recorded when the request came in. + if established is None and routed is not None and routed in self.session_streams: + await self.session_streams[routed].push(message) + return + await self.connection_stream.push(message) + + async def deliver_to_agent(self, message: dict[str, Any]) -> None: + """Inject a client→server message into the agent connection.""" + # Track session-scoped client requests so their responses route back. + if "id" in message and "method" in message: + session_id = session_id_from_params(message.get("params")) + if session_id is not None: + key = message_id_key(message["id"]) + if key is not None: + self._pending_routes[key] = session_id + await self._pump_side.send(message) + + async def request_response(self, message: dict[str, Any]) -> dict[str, Any]: + """Send a request to the agent and await its correlated response. + + Used for the ``initialize`` POST, which is the one request whose response + is returned synchronously in the HTTP body rather than over an SSE stream. + """ + key = message_id_key(message.get("id")) + loop = asyncio.get_running_loop() + future: asyncio.Future[dict[str, Any]] = loop.create_future() + if key is not None: + self._response_waiters[key] = future + await self.deliver_to_agent(message) + return await asyncio.wait_for(future, timeout=INITIALIZE_TIMEOUT_SECONDS) + + def ensure_session_stream(self, session_id: str) -> OutboundStream: + stream = self.session_streams.get(session_id) + if stream is None: + stream = OutboundStream() + self.session_streams[session_id] = stream + return stream + + def has_session(self, session_id: str) -> bool: + return session_id in self.session_streams + + async def iter_all_outbound(self) -> AsyncIterator[dict[str, Any]]: + """Iterate every agent→client message (WebSocket multiplex mode).""" + if self._multiplex is None: + msg = "iter_all_outbound requires a multiplex connection (WebSocket)" + raise RuntimeError(msg) + async for message in self._multiplex.iterate(): + yield message + + async def close(self) -> None: + if self._pump_task is not None: + self._pump_task.cancel() + with contextlib.suppress(asyncio.CancelledError, Exception): + await self._pump_task + self.connection_stream.close() + for stream in self.session_streams.values(): + stream.close() + if self._multiplex is not None: + self._multiplex.close() + with contextlib.suppress(Exception): + await self._pump_side.close() + with contextlib.suppress(Exception): + await self._agent_conn.close() + + +class ConnectionRegistry: + """In-memory ``connectionId -> ConnectionState`` registry.""" + + def __init__(self) -> None: + self._connections: dict[str, ConnectionState] = {} + + def create(self, agent_factory: AgentFactory) -> ConnectionState: + connection_id = uuid.uuid4().hex + state = ConnectionState(connection_id, agent_factory) + state.start() + self._connections[connection_id] = state + return state + + def create_multiplex(self, agent_factory: AgentFactory) -> ConnectionState: + """Create a connection whose agent→client traffic is multiplexed onto one + stream (used by the WebSocket transport).""" + connection_id = uuid.uuid4().hex + state = ConnectionState(connection_id, agent_factory, multiplex=True) + state.start() + self._connections[connection_id] = state + return state + + def get(self, connection_id: str) -> ConnectionState | None: + return self._connections.get(connection_id) + + async def remove(self, connection_id: str) -> None: + state = self._connections.pop(connection_id, None) + if state is not None: + await state.close() + + async def close_all(self) -> None: + for connection_id in list(self._connections): + await self.remove(connection_id) + + +class AcpServer: + """Framework-agnostic Streamable HTTP + WebSocket server core. + + Args: + agent_factory: Called once per connection with the bound + ``AgentSideConnection`` to produce a per-connection ``Agent``. + """ + + def __init__(self, agent_factory: AgentFactory) -> None: + self._agent_factory = agent_factory + self._registry = ConnectionRegistry() + + @property + def registry(self) -> ConnectionRegistry: + return self._registry + + def create_websocket_connection(self) -> ConnectionState: + """Create a new multiplexed connection for a WebSocket upgrade.""" + return self._registry.create_multiplex(self._agent_factory) + + # -- POST --------------------------------------------------------------- + + async def handle_post( + self, + message: Any, + *, + content_type: str | None, + connection_id: str | None, + session_id: str | None, + ) -> PostResult: + if content_type is None or not content_type.lower().startswith("application/json"): + return PostResult(415, {"error": "Content-Type must be application/json"}) + if isinstance(message, list): + return PostResult(501, {"error": "Batch requests are not supported"}) + if not isinstance(message, dict): + return PostResult(400, {"error": "Invalid JSON-RPC message"}) + + if is_initialize_request(message): + return await self._handle_initialize(message) + + if connection_id is None: + return PostResult(400, {"error": "Missing connection id"}) + state = self._registry.get(connection_id) + if state is None: + return PostResult(404, {"error": "Unknown connection id"}) + + method = message.get("method") + if method_requires_session_header(method) and session_id is None: + return PostResult(400, {"error": "Missing session id header"}) + if session_id is not None and not state.has_session(session_id): + # A session-scoped POST references an unknown session. + return PostResult(404, {"error": "Unknown session id"}) + + await state.deliver_to_agent(message) + return PostResult(202) + + async def _handle_initialize(self, message: dict[str, Any]) -> PostResult: + state = self._registry.create(self._agent_factory) + # Deliver initialize to the agent and await its response so we can return + # the 200 body synchronously (initialize is the one blocking POST). If the + # agent never responds (timeout) or errors, tear the just-created + # connection down instead of leaking its pump task + agent connection. + try: + response = await state.request_response(message) + except TimeoutError: + await self._registry.remove(state.connection_id) + return PostResult(504, {"error": "initialize timed out"}) + except Exception: + await self._registry.remove(state.connection_id) + return PostResult(500, {"error": "initialize failed"}) + return PostResult(200, response, {CONNECTION_ID_HEADER: state.connection_id}) + + # -- GET / SSE ---------------------------------------------------------- + + def validate_stream(self, *, connection_id: str | None, session_id: str | None) -> PostResult | None: + """Validate a GET SSE request. Returns an error PostResult, or None if OK.""" + if connection_id is None: + return PostResult(400, {"error": "Missing connection id"}) + state = self._registry.get(connection_id) + if state is None: + return PostResult(404, {"error": "Unknown connection id"}) + if session_id is not None and not state.has_session(session_id): + return PostResult(404, {"error": "Unknown session id"}) + return None + + async def open_stream( + self, + *, + connection_id: str, + session_id: str | None, + ) -> AsyncIterator[bytes]: + """Yield SSE byte frames for a connection- or session-scoped stream. + + Emits a keepalive comment whenever the stream is idle for longer than + :data:`SSE_KEEPALIVE_INTERVAL_SECONDS` so that idle-timeout intermediaries + (proxies, load balancers) do not close an otherwise-healthy stream. + """ + state = self._registry.get(connection_id) + if state is None: + return + stream = state.ensure_session_stream(session_id) if session_id is not None else state.connection_stream + messages = stream.iterate() + pending: asyncio.Task[dict[str, Any]] | None = None + try: + while True: + if pending is None: + pending = asyncio.ensure_future(messages.__anext__()) + done, _ = await asyncio.wait({pending}, timeout=SSE_KEEPALIVE_INTERVAL_SECONDS) + if not done: + # Idle: emit a keepalive and keep awaiting the same message. + yield serialize_sse_keepalive() + continue + try: + message = pending.result() + except StopAsyncIteration: + return + finally: + pending = None + yield serialize_sse_event(message) + finally: + if pending is not None: + pending.cancel() + with contextlib.suppress(asyncio.CancelledError, Exception): + await pending + await messages.aclose() + + # -- DELETE ------------------------------------------------------------- + + async def handle_delete(self, *, connection_id: str | None) -> PostResult: + if connection_id is None: + return PostResult(400, {"error": "Missing connection id"}) + if self._registry.get(connection_id) is None: + return PostResult(404, {"error": "Unknown connection id"}) + await self._registry.remove(connection_id) + return PostResult(202) + + async def close(self) -> None: + await self._registry.close_all() diff --git a/src/acp/ws/__init__.py b/src/acp/ws/__init__.py new file mode 100644 index 0000000..51ab2a9 --- /dev/null +++ b/src/acp/ws/__init__.py @@ -0,0 +1,23 @@ +"""WebSocket transport for ACP (experimental). + +Public exports are import-guarded behind the ``http`` extra (which provides the +``websockets`` dependency). +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +__all__ = ["create_websocket_stream"] + +if TYPE_CHECKING: + from .client import create_websocket_stream + + +def __getattr__(name: str) -> Any: + if name == "create_websocket_stream": + from .client import create_websocket_stream + + return create_websocket_stream + msg = f"module {__name__!r} has no attribute {name!r}" + raise AttributeError(msg) diff --git a/src/acp/ws/client.py b/src/acp/ws/client.py new file mode 100644 index 0000000..18acf5b --- /dev/null +++ b/src/acp/ws/client.py @@ -0,0 +1,117 @@ +"""WebSocket client transport (port of #155 ``ws-stream.ts``). + +``create_websocket_stream(url, ...)`` connects a WebSocket and returns a +:class:`~acp._transport.Transport`. Messages are JSON-RPC **text** frames; +binary frames are ignored. The client must still send ``initialize`` as the +first message over the socket. +""" + +from __future__ import annotations + +import contextlib +import json +from typing import TYPE_CHECKING, Any + +from .._cookies import MemoryAcpCookieStore + +try: + import websockets + from websockets.asyncio.client import connect as ws_connect +except ImportError as exc: # pragma: no cover - exercised via import guard message + msg = "The WebSocket transport requires the 'http' extra: pip install agent-client-protocol[http]" + raise ImportError(msg) from exc + +if TYPE_CHECKING: + from .._transport import Transport + +__all__ = ["MemoryAcpCookieStore", "create_websocket_stream"] + +# Case-insensitive header name a server uses to set connection-affinity cookies +# on the WebSocket upgrade response. +_SET_COOKIE_HEADER = "Set-Cookie" + + +class _WebSocketTransport: + """WebSocket client transport implementing the :class:`Transport` protocol.""" + + def __init__(self, connection: Any) -> None: + self._ws = connection + self._closed = False + + async def send(self, message: dict[str, Any]) -> None: + if self._closed: + raise ConnectionError("Transport closed") + await self._ws.send(json.dumps(message, separators=(",", ":"))) + + async def receive(self) -> dict[str, Any] | None: + while True: + try: + frame = await self._ws.recv() + except websockets.ConnectionClosed: + return None + # Ignore binary frames; only text JSON-RPC is meaningful. + if isinstance(frame, bytes): + continue + try: + return json.loads(frame) + except json.JSONDecodeError: + continue + + async def close(self) -> None: + if self._closed: + return + self._closed = True + with contextlib.suppress(Exception): + await self._ws.close() + + +async def create_websocket_stream( + url: str, + *, + headers: dict[str, str] | None = None, + cookie_store: MemoryAcpCookieStore | None = None, +) -> Transport: + """Connect a WebSocket and return a :class:`Transport`. + + Per the RFD, clients MUST accept, store, and return cookies on all HTTP-based + transports (including WebSocket) so servers can rely on cookies for session + affinity (e.g. sticky sessions behind a load balancer). A single WebSocket is + one long-lived connection, so cookie support matters across *reconnects*: + pass a caller-owned ``cookie_store`` reused between fresh streams. Any cookies + already in the store are sent as a ``Cookie`` header on the handshake, and any + ``Set-Cookie`` headers on the upgrade response are captured back into it. + + Args: + url: The ACP WebSocket endpoint (e.g. ``ws://host/acp``). + headers: Extra headers sent during the handshake. + cookie_store: Optional caller-owned affinity cookie store to reuse across + reconnects. If omitted, an ephemeral per-stream store is used. + + Returns: + A connected :class:`Transport` usable with :func:`acp.connect_to_agent`. + """ + store = cookie_store if cookie_store is not None else MemoryAcpCookieStore() + request_headers = dict(headers or {}) + cookie_header = store.cookie_header() + if cookie_header and not _has_header(request_headers, "Cookie"): + request_headers["Cookie"] = cookie_header + connection = await ws_connect(url, additional_headers=request_headers or None) + _capture_set_cookies(connection, store) + return _WebSocketTransport(connection) + + +def _has_header(headers: dict[str, str], name: str) -> bool: + lowered = name.lower() + return any(key.lower() == lowered for key in headers) + + +def _capture_set_cookies(connection: Any, store: MemoryAcpCookieStore) -> None: + """Store ``Set-Cookie`` headers from the WebSocket upgrade response.""" + response = getattr(connection, "response", None) + response_headers = getattr(response, "headers", None) + if response_headers is None: + return + get_all = getattr(response_headers, "get_all", None) + values = list(get_all(_SET_COOKIE_HEADER)) if get_all is not None else [] + if values: + store.store_set_cookies(values) diff --git a/src/acp/ws/server.py b/src/acp/ws/server.py new file mode 100644 index 0000000..e5ff43f --- /dev/null +++ b/src/acp/ws/server.py @@ -0,0 +1,79 @@ +"""WebSocket server handling for the ASGI adapter (port of #155 ws-server.ts). + +On upgrade we create a fresh :class:`~acp.http.server.ConnectionState` (bound to +its own ``AgentSideConnection``), accept the socket with an ``Acp-Connection-Id`` +header, then pump JSON-RPC text frames both directions. All server→client +traffic (across the connection- and every session-scoped stream) is multiplexed +onto the single socket. On disconnect the connection and its sessions are torn +down. +""" + +from __future__ import annotations + +import asyncio +import contextlib +import json +from collections.abc import Callable +from typing import TYPE_CHECKING, Any + +from ..http.protocol import CONNECTION_ID_HEADER + +if TYPE_CHECKING: + from ..http.server import AcpServer, ConnectionState + +__all__ = ["handle_asgi_websocket"] + + +async def handle_asgi_websocket( + server: AcpServer, + scope: dict[str, Any], + receive: Callable, + send: Callable, +) -> None: + """Handle an ASGI ``websocket`` scope by bridging it to a new ACP connection.""" + # Wait for the connect message. + message = await receive() + if message["type"] != "websocket.connect": + return + + state = server.create_websocket_connection() + await send({ + "type": "websocket.accept", + "headers": [(CONNECTION_ID_HEADER.lower().encode(), state.connection_id.encode())], + }) + + outbound_task = asyncio.ensure_future(_pump_outbound(state, send)) + try: + await _pump_inbound(state, receive) + finally: + outbound_task.cancel() + with contextlib.suppress(asyncio.CancelledError, Exception): + await outbound_task + await server.registry.remove(state.connection_id) + + +async def _pump_inbound(state: ConnectionState, receive: Callable) -> None: + """Read client→server text frames and deliver them to the agent.""" + while True: + message = await receive() + msg_type = message["type"] + if msg_type == "websocket.disconnect": + return + if msg_type != "websocket.receive": + continue + text = message.get("text") + if text is None: + # Ignore binary frames. + continue + try: + payload = json.loads(text) + except json.JSONDecodeError: + continue + if isinstance(payload, dict): + await state.deliver_to_agent(payload) + + +async def _pump_outbound(state: ConnectionState, send: Callable) -> None: + """Forward all agent→client messages onto the socket as text frames.""" + async for message in state.iter_all_outbound(): + await send({"type": "websocket.send", "text": json.dumps(message, separators=(",", ":"))}) diff --git a/tests/http/conftest.py b/tests/http/conftest.py new file mode 100644 index 0000000..f96355c --- /dev/null +++ b/tests/http/conftest.py @@ -0,0 +1,62 @@ +"""Shared fixtures for HTTP/WS loopback tests: run an ASGI app under uvicorn.""" + +from __future__ import annotations + +import asyncio +import contextlib +import socket +from collections.abc import AsyncIterator, Callable +from typing import Any + +import pytest_asyncio +import uvicorn + + +def _free_port() -> int: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.bind(("127.0.0.1", 0)) + return sock.getsockname()[1] + + +class RunningServer: + def __init__(self, host: str, port: int) -> None: + self.host = host + self.port = port + + @property + def http_url(self) -> str: + return f"http://{self.host}:{self.port}/acp" + + @property + def ws_url(self) -> str: + return f"ws://{self.host}:{self.port}/acp" + + +@pytest_asyncio.fixture +async def serve_asgi() -> AsyncIterator[Callable[[Any], Any]]: + """Yield a factory that boots an ASGI app under uvicorn and returns a RunningServer.""" + servers: list[uvicorn.Server] = [] + tasks: list[asyncio.Task[Any]] = [] + + async def _start(app: Any) -> RunningServer: + host, port = "127.0.0.1", _free_port() + config = uvicorn.Config(app, host=host, port=port, log_level="warning", lifespan="on") + server = uvicorn.Server(config) + servers.append(server) + task = asyncio.ensure_future(server.serve()) + tasks.append(task) + # Wait until the server is up. + for _ in range(100): + if server.started: + break + await asyncio.sleep(0.02) + return RunningServer(host, port) + + try: + yield _start + finally: + for server in servers: + server.should_exit = True + for task in tasks: + with contextlib.suppress(asyncio.CancelledError, Exception): + await asyncio.wait_for(task, timeout=5) diff --git a/tests/http/test_cookies.py b/tests/http/test_cookies.py new file mode 100644 index 0000000..5bc0ae4 --- /dev/null +++ b/tests/http/test_cookies.py @@ -0,0 +1,42 @@ +from __future__ import annotations + +from acp._cookies import MemoryAcpCookieStore + + +def test_store_and_render_single_cookie() -> None: + store = MemoryAcpCookieStore() + store.store_set_cookie("affinity=abc123; Path=/; HttpOnly") + assert store.cookie_header() == "affinity=abc123" + + +def test_store_multiple_cookies_preserves_all() -> None: + store = MemoryAcpCookieStore() + store.store_set_cookies(["a=1; Path=/", "b=2; Secure"]) + assert store.cookie_header() == "a=1; b=2" + + +def test_later_value_overwrites_same_name() -> None: + store = MemoryAcpCookieStore() + store.store_set_cookie("a=1") + store.store_set_cookie("a=2") + assert store.cookie_header() == "a=2" + assert len(store) == 1 + + +def test_empty_store_returns_none() -> None: + store = MemoryAcpCookieStore() + assert store.cookie_header() is None + + +def test_malformed_set_cookie_ignored() -> None: + store = MemoryAcpCookieStore() + store.store_set_cookie("garbage") + store.store_set_cookie("") + assert store.cookie_header() is None + + +def test_clear_drops_all() -> None: + store = MemoryAcpCookieStore() + store.store_set_cookie("a=1") + store.clear() + assert store.cookie_header() is None diff --git a/tests/http/test_fixes.py b/tests/http/test_fixes.py new file mode 100644 index 0000000..2a8c307 --- /dev/null +++ b/tests/http/test_fixes.py @@ -0,0 +1,186 @@ +"""Regression tests for reliability fixes on the HTTP/WS transport. + +Covers: +* OutboundStream backpressure (no silent message drops under a full buffer). +* SSE keepalive emission on idle streams. +* HTTP client surfacing disconnect (EOF) when the connection-scoped SSE stream ends. +* Server cleanup of a leaked connection when ``initialize`` fails/times out. +* WebSocket client cookie support (send stored Cookie; capture Set-Cookie). +""" + +from __future__ import annotations + +import asyncio +import json +from typing import Any + +import httpx +import pytest + +import acp.http.server as server_mod +from acp.http.client import create_http_stream +from acp.http.protocol import CONNECTION_ID_HEADER, CONTENT_TYPE_JSON +from acp.http.server import AcpServer, OutboundStream + +CT_JSON = "application/json" + + +# -- Finding 1: OutboundStream backpressure ------------------------------------ + + +@pytest.mark.asyncio +async def test_outbound_stream_does_not_drop_beyond_capacity() -> None: + """Pushing more than ``capacity`` messages must not silently drop any. + + With a bounded queue and ``put_nowait``, the (capacity+1)-th message was + dropped. Backpressure-aware push blocks the producer until a consumer drains, + so every message is eventually delivered in order. + """ + stream = OutboundStream(capacity=2) + total = 5 + + async def produce() -> None: + for i in range(total): + await stream.push({"n": i}) + stream.close() + + producer = asyncio.ensure_future(produce()) + received = [msg async for msg in stream.iterate()] + await producer + assert received == [{"n": i} for i in range(total)] + + +@pytest.mark.asyncio +async def test_outbound_stream_push_blocks_when_full() -> None: + """push must not complete once the buffer is full and no consumer drains.""" + stream = OutboundStream(capacity=1) + await stream.push({"n": 0}) # fills the buffer + blocked = asyncio.ensure_future(stream.push({"n": 1})) + await asyncio.sleep(0.05) + assert not blocked.done() + # Draining one message unblocks the producer. + it = stream.iterate() + assert await it.__anext__() == {"n": 0} + await asyncio.wait_for(blocked, timeout=1) + stream.close() + + +# -- Finding 3: SSE keepalive -------------------------------------------------- + + +@pytest.mark.asyncio +async def test_open_stream_emits_keepalive_when_idle(monkeypatch: pytest.MonkeyPatch) -> None: + """An idle connection-scoped stream must emit periodic SSE keepalive frames.""" + monkeypatch.setattr(server_mod, "SSE_KEEPALIVE_INTERVAL_SECONDS", 0.05) + + server = AcpServer(lambda conn: _NoopAgent()) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {"protocolVersion": 1}}, + content_type=CT_JSON, + connection_id=None, + session_id=None, + ) + connection_id = result.headers[CONNECTION_ID_HEADER] + + frames: list[bytes] = [] + + async def drain() -> None: + async for frame in server.open_stream(connection_id=connection_id, session_id=None): + frames.append(frame) + + task = asyncio.ensure_future(drain()) + await asyncio.sleep(0.2) + task.cancel() + with pytest.raises(asyncio.CancelledError): + await task + await server.close() + + assert any(frame == b": keepalive\n\n" for frame in frames) + + +# -- Finding 5: initialize failure cleanup ------------------------------------- + + +@pytest.mark.asyncio +async def test_initialize_timeout_cleans_up_connection(monkeypatch: pytest.MonkeyPatch) -> None: + """A hung ``initialize`` must not leak a registered connection.""" + monkeypatch.setattr(server_mod, "INITIALIZE_TIMEOUT_SECONDS", 0.1) + + server = AcpServer(lambda conn: _SilentInitAgent()) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {"protocolVersion": 1}}, + content_type=CT_JSON, + connection_id=None, + session_id=None, + ) + assert result.status >= 500 + # No connection should remain registered after a failed initialize. + assert server.registry.get(result.headers.get(CONNECTION_ID_HEADER, "")) is None + assert _registry_size(server) == 0 + await server.close() + + +# -- Finding 4: HTTP client surfaces disconnect on stream EOF ------------------ + + +@pytest.mark.asyncio +async def test_http_client_surfaces_eof_when_connection_stream_ends() -> None: + """When the connection-scoped SSE stream ends, receive() must return None.""" + conn_id = "conn-eof" + + def handler(request: httpx.Request) -> httpx.Response: + if request.method == "POST": + body = json.loads(request.content) + if body.get("method") == "initialize": + return httpx.Response( + 200, + headers={CONNECTION_ID_HEADER: conn_id, "Content-Type": CONTENT_TYPE_JSON}, + json={"jsonrpc": "2.0", "id": body["id"], "result": {}}, + ) + return httpx.Response(202) + if request.method == "GET": + # SSE stream that immediately ends (empty body -> EOF). + return httpx.Response(200, headers={"Content-Type": "text/event-stream"}, content=b"") + return httpx.Response(202) + + client = httpx.AsyncClient(transport=httpx.MockTransport(handler)) + transport = create_http_stream("http://testserver/acp", client=client) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + # Drain the initialize result. + assert await asyncio.wait_for(transport.receive(), timeout=1) == {"jsonrpc": "2.0", "id": 0, "result": {}} + # The connection stream ends -> transport must surface EOF, not hang. + assert await asyncio.wait_for(transport.receive(), timeout=1) is None + finally: + await transport.close() + await client.aclose() + + +# -- Helpers ------------------------------------------------------------------- + + +def _registry_size(server: AcpServer) -> int: + return len(server.registry._connections) # type: ignore[attr-defined] + + +class _NoopAgent: + def __init__(self) -> None: + self._conn: Any = None + + def on_connect(self, conn: Any) -> None: + self._conn = conn + + async def initialize(self, protocol_version: int = 1, **kwargs: Any) -> Any: + from acp.schema import InitializeResponse + + return InitializeResponse(protocol_version=1) + + +class _SilentInitAgent: + """An agent whose initialize never returns, forcing a server-side timeout.""" + + def on_connect(self, conn: Any) -> None: + pass + + async def initialize(self, protocol_version: int = 1, **kwargs: Any) -> Any: + await asyncio.sleep(3600) diff --git a/tests/http/test_http_client.py b/tests/http/test_http_client.py new file mode 100644 index 0000000..cacb296 --- /dev/null +++ b/tests/http/test_http_client.py @@ -0,0 +1,213 @@ +"""Unit tests for the Streamable HTTP client transport (ported from http-stream.test.ts).""" + +from __future__ import annotations + +import asyncio +import json +from typing import Any + +import httpx +import pytest + +from acp._sse import serialize_sse_event +from acp.http.client import AcpHttpStatusError, create_http_stream +from acp.http.protocol import CONNECTION_ID_HEADER, CONTENT_TYPE_JSON, SESSION_ID_HEADER + +CONN_ID = "conn-123" + + +class FakeServer: + """A minimal in-memory Streamable HTTP server backed by httpx.MockTransport.""" + + def __init__(self) -> None: + self.posts: list[dict[str, Any]] = [] + self.deleted = False + # Queues feeding the connection-scoped and session-scoped SSE streams. + self.conn_stream: asyncio.Queue[bytes | None] = asyncio.Queue() + self.session_streams: dict[str, asyncio.Queue[bytes | None]] = {} + + def handler(self, request: httpx.Request) -> httpx.Response: + if request.method == "POST": + return self._handle_post(request) + if request.method == "GET": + return self._handle_get(request) + if request.method == "DELETE": + self.deleted = True + return httpx.Response(202) + return httpx.Response(405) + + def _handle_post(self, request: httpx.Request) -> httpx.Response: + body = json.loads(request.content) + self.posts.append(body) + if body.get("method") == "initialize": + return httpx.Response( + 200, + headers={CONNECTION_ID_HEADER: CONN_ID, "Content-Type": CONTENT_TYPE_JSON}, + json={"jsonrpc": "2.0", "id": body["id"], "result": {"protocolVersion": 1}}, + ) + return httpx.Response(202) + + def _handle_get(self, request: httpx.Request) -> httpx.Response: + session_id = request.headers.get(SESSION_ID_HEADER) + if session_id is not None: + queue = self.session_streams.setdefault(session_id, asyncio.Queue()) + else: + queue = self.conn_stream + + async def body() -> Any: + while True: + chunk = await queue.get() + if chunk is None: + return + yield chunk + + return httpx.Response(200, headers={"Content-Type": "text/event-stream"}, stream=_AsyncByteStream(body())) + + def push_conn(self, message: dict[str, Any]) -> None: + self.conn_stream.put_nowait(serialize_sse_event(message)) + + def push_session(self, session_id: str, message: dict[str, Any]) -> None: + queue = self.session_streams.setdefault(session_id, asyncio.Queue()) + queue.put_nowait(serialize_sse_event(message)) + + +class _AsyncByteStream(httpx.AsyncByteStream): + def __init__(self, iterator: Any) -> None: + self._iterator = iterator + + async def __aiter__(self) -> Any: + async for chunk in self._iterator: + yield chunk + + +def _make_transport(server: FakeServer): + client = httpx.AsyncClient(transport=httpx.MockTransport(server.handler)) + return create_http_stream("http://testserver/acp", client=client), client + + +@pytest.mark.asyncio +async def test_initialize_posts_and_reads_connection_id() -> None: + server = FakeServer() + transport, client = _make_transport(server) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + # The initialize result is enqueued back for the core to correlate. + result = await asyncio.wait_for(transport.receive(), timeout=1) + assert result == {"jsonrpc": "2.0", "id": 0, "result": {"protocolVersion": 1}} + assert server.posts[0]["method"] == "initialize" + finally: + await transport.close() + await client.aclose() + + +@pytest.mark.asyncio +async def test_initialize_failure_raises() -> None: + def handler(request: httpx.Request) -> httpx.Response: + return httpx.Response(500) + + client = httpx.AsyncClient(transport=httpx.MockTransport(handler)) + transport = create_http_stream("http://testserver/acp", client=client) + try: + with pytest.raises(AcpHttpStatusError) as exc: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + assert exc.value.status_code == 500 # type: ignore[attr-defined] + finally: + await transport.close() + await client.aclose() + + +@pytest.mark.asyncio +async def test_connection_scoped_sse_delivers_new_session_result() -> None: + server = FakeServer() + transport, client = _make_transport(server) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + await asyncio.wait_for(transport.receive(), timeout=1) # drain initialize result + # session/new POST returns 202; the result comes over the connection stream. + await transport.send({"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {}}) + await asyncio.sleep(0.05) + server.push_conn({"jsonrpc": "2.0", "id": 1, "result": {"sessionId": "sess-1"}}) + msg = await asyncio.wait_for(transport.receive(), timeout=1) + assert msg == {"jsonrpc": "2.0", "id": 1, "result": {"sessionId": "sess-1"}} + assert any(p.get("method") == "session/new" for p in server.posts) + finally: + await transport.close() + await client.aclose() + + +@pytest.mark.asyncio +async def test_session_scoped_sse_opens_after_new_session() -> None: + server = FakeServer() + transport, client = _make_transport(server) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + await asyncio.wait_for(transport.receive(), timeout=1) + await transport.send({"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {}}) + await asyncio.sleep(0.05) + server.push_conn({"jsonrpc": "2.0", "id": 1, "result": {"sessionId": "sess-1"}}) + await asyncio.wait_for(transport.receive(), timeout=1) # session/new result + # Give the client time to open the session-scoped stream. + await asyncio.sleep(0.05) + assert "sess-1" in server.session_streams + # A session-scoped notification arrives on the merged feed. + server.push_session("sess-1", {"jsonrpc": "2.0", "method": "session/update", "params": {"sessionId": "sess-1"}}) + msg = await asyncio.wait_for(transport.receive(), timeout=1) + assert msg["method"] == "session/update" + finally: + await transport.close() + await client.aclose() + + +@pytest.mark.asyncio +async def test_session_scoped_post_sends_session_header() -> None: + server = FakeServer() + transport, client = _make_transport(server) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + await asyncio.wait_for(transport.receive(), timeout=1) + await transport.send({"jsonrpc": "2.0", "id": 2, "method": "session/prompt", "params": {"sessionId": "sess-1"}}) + prompt_post = next(p for p in server.posts if p.get("method") == "session/prompt") + assert prompt_post["params"]["sessionId"] == "sess-1" + finally: + await transport.close() + await client.aclose() + + +@pytest.mark.asyncio +async def test_close_deletes_connection() -> None: + server = FakeServer() + transport, client = _make_transport(server) + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + await asyncio.wait_for(transport.receive(), timeout=1) + await transport.close() + assert server.deleted is True + # After close, receive() yields EOF. + assert await asyncio.wait_for(transport.receive(), timeout=1) is None + await client.aclose() + + +@pytest.mark.asyncio +async def test_post_error_status_raises() -> None: + def handler(request: httpx.Request) -> httpx.Response: + if request.method == "POST": + body = json.loads(request.content) + if body.get("method") == "initialize": + return httpx.Response( + 200, + headers={CONNECTION_ID_HEADER: CONN_ID}, + json={"jsonrpc": "2.0", "id": body["id"], "result": {}}, + ) + return httpx.Response(404) + return httpx.Response(200, headers={"Content-Type": "text/event-stream"}) + + client = httpx.AsyncClient(transport=httpx.MockTransport(handler)) + transport = create_http_stream("http://testserver/acp", client=client) + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + await asyncio.wait_for(transport.receive(), timeout=1) + with pytest.raises(AcpHttpStatusError) as exc: + await transport.send({"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {}}) + assert exc.value.status_code == 404 # type: ignore[attr-defined] + finally: + await transport.close() + await client.aclose() diff --git a/tests/http/test_http_server.py b/tests/http/test_http_server.py new file mode 100644 index 0000000..92f9290 --- /dev/null +++ b/tests/http/test_http_server.py @@ -0,0 +1,233 @@ +"""Tests for the framework-agnostic AcpServer core (ported from server*.test.ts).""" + +from __future__ import annotations + +import asyncio +from typing import Any + +import pytest + +from acp.http.protocol import CONNECTION_ID_HEADER +from acp.http.server import AcpServer +from acp.schema import NewSessionResponse, PromptResponse +from tests.conftest import TestAgent + +CT_JSON = "application/json" + + +class _Agent(TestAgent): + """A test agent that streams a notification during prompt and can ask permission.""" + + def __init__(self) -> None: + super().__init__() + self._conn: Any = None + self.ask_permission = False + + def on_connect(self, conn: Any) -> None: + self._conn = conn + + async def new_session(self, cwd: str | None = None, mcp_servers: Any = None, **kwargs: Any) -> NewSessionResponse: + return NewSessionResponse(session_id="sess-1") + + async def prompt(self, session_id: str, prompt: Any = None, **kwargs: Any) -> PromptResponse: + # Emit a session-scoped notification back to the client. + await self._conn.session_update( + session_id=session_id, + update={"sessionUpdate": "agent_message_chunk", "content": {"type": "text", "text": "hi"}}, + ) + if self.ask_permission: + await self._conn.request_permission( + session_id=session_id, + tool_call={"toolCallId": "t1", "title": "run"}, + options=[{"optionId": "allow", "name": "Allow", "kind": "allow_once"}], + ) + return PromptResponse(stop_reason="end_turn") + + +def _agent_factory(agent: _Agent): + return lambda conn: agent + + +async def _drain_stream(server: AcpServer, connection_id: str, session_id: str | None, out: list[bytes]) -> None: + async for frame in server.open_stream(connection_id=connection_id, session_id=session_id): + out.append(frame) + + +@pytest.mark.asyncio +async def test_post_wrong_content_type_returns_415() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}, + content_type="text/plain", + connection_id=None, + session_id=None, + ) + assert result.status == 415 + await server.close() + + +@pytest.mark.asyncio +async def test_batch_returns_501() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_post([], content_type=CT_JSON, connection_id=None, session_id=None) + assert result.status == 501 + await server.close() + + +@pytest.mark.asyncio +async def test_initialize_creates_connection_and_returns_id() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {"protocolVersion": 1, "clientCapabilities": {}}}, + content_type=CT_JSON, + connection_id=None, + session_id=None, + ) + assert result.status == 200 + assert CONNECTION_ID_HEADER in result.headers + assert result.body is not None + assert result.body["id"] == 0 + await server.close() + + +@pytest.mark.asyncio +async def test_missing_connection_id_returns_400() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {}}, + content_type=CT_JSON, + connection_id=None, + session_id=None, + ) + assert result.status == 400 + await server.close() + + +@pytest.mark.asyncio +async def test_unknown_connection_id_returns_404() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {}}, + content_type=CT_JSON, + connection_id="nope", + session_id=None, + ) + assert result.status == 404 + await server.close() + + +async def _initialize(server: AcpServer) -> str: + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {"protocolVersion": 1, "clientCapabilities": {}}}, + content_type=CT_JSON, + connection_id=None, + session_id=None, + ) + return result.headers[CONNECTION_ID_HEADER] + + +@pytest.mark.asyncio +async def test_session_new_result_on_connection_stream() -> None: + server = AcpServer(_agent_factory(_Agent())) + conn_id = await _initialize(server) + frames: list[bytes] = [] + task = asyncio.ensure_future(_drain_stream(server, conn_id, None, frames)) + await asyncio.sleep(0.05) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {"cwd": ".", "mcpServers": []}}, + content_type=CT_JSON, + connection_id=conn_id, + session_id=None, + ) + assert result.status == 202 + await asyncio.sleep(0.1) + joined = b"".join(frames).decode() + assert '"sessionId":"sess-1"' in joined + assert '"id":1' in joined + task.cancel() + await server.close() + + +@pytest.mark.asyncio +async def test_session_scoped_missing_session_header_returns_400() -> None: + server = AcpServer(_agent_factory(_Agent())) + conn_id = await _initialize(server) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 2, "method": "session/prompt", "params": {"sessionId": "sess-1"}}, + content_type=CT_JSON, + connection_id=conn_id, + session_id=None, + ) + assert result.status == 400 + await server.close() + + +@pytest.mark.asyncio +async def test_prompt_streams_notification_on_session_stream() -> None: + server = AcpServer(_agent_factory(_Agent())) + conn_id = await _initialize(server) + # Create the session first. + await server.handle_post( + {"jsonrpc": "2.0", "id": 1, "method": "session/new", "params": {"cwd": ".", "mcpServers": []}}, + content_type=CT_JSON, + connection_id=conn_id, + session_id=None, + ) + await asyncio.sleep(0.05) + session_frames: list[bytes] = [] + conn_frames: list[bytes] = [] + st = asyncio.ensure_future(_drain_stream(server, conn_id, "sess-1", session_frames)) + ct = asyncio.ensure_future(_drain_stream(server, conn_id, None, conn_frames)) + await asyncio.sleep(0.05) + result = await server.handle_post( + {"jsonrpc": "2.0", "id": 2, "method": "session/prompt", "params": {"sessionId": "sess-1", "prompt": []}}, + content_type=CT_JSON, + connection_id=conn_id, + session_id="sess-1", + ) + assert result.status == 202 + await asyncio.sleep(0.15) + session_joined = b"".join(session_frames).decode() + # The agent_message_chunk notification is session-scoped. + assert "agent_message_chunk" in session_joined + # The prompt response (id 2) also routes to the session stream. + assert '"id":2' in session_joined + st.cancel() + ct.cancel() + await server.close() + + +@pytest.mark.asyncio +async def test_delete_terminates_connection() -> None: + server = AcpServer(_agent_factory(_Agent())) + conn_id = await _initialize(server) + result = await server.handle_delete(connection_id=conn_id) + assert result.status == 202 + # Subsequent use of the connection id 404s. + follow = await server.handle_post( + {"jsonrpc": "2.0", "id": 5, "method": "session/new", "params": {}}, + content_type=CT_JSON, + connection_id=conn_id, + session_id=None, + ) + assert follow.status == 404 + await server.close() + + +@pytest.mark.asyncio +async def test_delete_missing_connection_id_returns_400() -> None: + server = AcpServer(_agent_factory(_Agent())) + result = await server.handle_delete(connection_id=None) + assert result.status == 400 + await server.close() + + +@pytest.mark.asyncio +async def test_get_validation_errors() -> None: + server = AcpServer(_agent_factory(_Agent())) + assert server.validate_stream(connection_id=None, session_id=None).status == 400 # type: ignore[union-attr] + assert server.validate_stream(connection_id="nope", session_id=None).status == 404 # type: ignore[union-attr] + conn_id = await _initialize(server) + assert server.validate_stream(connection_id=conn_id, session_id="ghost").status == 404 # type: ignore[union-attr] + assert server.validate_stream(connection_id=conn_id, session_id=None) is None + await server.close() diff --git a/tests/http/test_loopback.py b/tests/http/test_loopback.py new file mode 100644 index 0000000..07b863d --- /dev/null +++ b/tests/http/test_loopback.py @@ -0,0 +1,131 @@ +"""End-to-end in-process loopback tests: Python client transport <-> ASGI server. + +Boots the ASGI app under a real uvicorn server (httpx's ASGITransport buffers +whole responses and cannot consume infinite SSE streams), then drives the full +ACP flow over both the Streamable HTTP and WebSocket transports. +""" + +from __future__ import annotations + +import asyncio +from typing import Any + +import pytest + +from acp import connect_to_agent +from acp.http.asgi import create_asgi_app +from acp.http.client import create_http_stream +from acp.schema import InitializeResponse, NewSessionResponse, PromptResponse, RequestPermissionResponse +from acp.ws.client import create_websocket_stream +from tests.conftest import TestAgent, TestClient + + +class _LoopbackAgent(TestAgent): + def __init__(self) -> None: + super().__init__() + self._conn: Any = None + self.ask_permission = False + + def on_connect(self, conn: Any) -> None: + self._conn = conn + + async def initialize(self, protocol_version: int = 1, **kwargs: Any) -> InitializeResponse: + return InitializeResponse(protocol_version=1) + + async def new_session(self, cwd: str | None = None, mcp_servers: Any = None, **kwargs: Any) -> NewSessionResponse: + return NewSessionResponse(session_id="sess-loop") + + async def prompt(self, session_id: str, prompt: Any = None, **kwargs: Any) -> PromptResponse: + await self._conn.session_update( + session_id=session_id, + update={"sessionUpdate": "agent_message_chunk", "content": {"type": "text", "text": "hello"}}, + ) + if self.ask_permission: + await self._conn.request_permission( + session_id=session_id, + tool_call={"toolCallId": "t1", "title": "run"}, + options=[{"optionId": "allow", "name": "Allow", "kind": "allow_once"}], + ) + return PromptResponse(stop_reason="end_turn") + + +def _make_app(agent: _LoopbackAgent) -> Any: + return create_asgi_app(lambda conn: agent) + + +class _CapturingClient(TestClient): + def __init__(self) -> None: + super().__init__() + self.updates: list[Any] = [] + self.permission_requested = False + + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + self.updates.append(update) + + async def request_permission(self, session_id: str, tool_call: Any, options: Any, **kwargs: Any): + self.permission_requested = True + return RequestPermissionResponse.model_validate({"outcome": {"outcome": "selected", "optionId": "allow"}}) + + +# -- Streamable HTTP ----------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_http_loopback_initialize_and_new_session(serve_asgi) -> None: + agent = _LoopbackAgent() + server = await serve_asgi(_make_app(agent)) + transport = create_http_stream(server.http_url) + conn = connect_to_agent(_CapturingClient(), transport) + try: + init = await asyncio.wait_for(conn.initialize(protocol_version=1), timeout=10) + assert init.protocol_version == 1 + new = await asyncio.wait_for(conn.new_session(cwd=".", mcp_servers=[]), timeout=10) + assert new.session_id == "sess-loop" + finally: + await conn.close() + await transport.close() + + +@pytest.mark.asyncio +async def test_http_loopback_prompt_streams_and_permission(serve_asgi) -> None: + agent = _LoopbackAgent() + agent.ask_permission = True + server = await serve_asgi(_make_app(agent)) + transport = create_http_stream(server.http_url) + client = _CapturingClient() + conn = connect_to_agent(client, transport) + try: + await asyncio.wait_for(conn.initialize(protocol_version=1), timeout=10) + new = await asyncio.wait_for(conn.new_session(cwd=".", mcp_servers=[]), timeout=10) + result = await asyncio.wait_for(conn.prompt(session_id=new.session_id, prompt=[]), timeout=10) + assert result.stop_reason == "end_turn" + await asyncio.sleep(0.2) + assert client.updates, "expected a session/update notification over SSE" + assert client.permission_requested, "expected a server->client permission request" + finally: + await conn.close() + await transport.close() + + +# -- WebSocket ----------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_ws_loopback_prompt_streams_and_permission(serve_asgi) -> None: + agent = _LoopbackAgent() + agent.ask_permission = True + server = await serve_asgi(_make_app(agent)) + transport = await create_websocket_stream(server.ws_url) + client = _CapturingClient() + conn = connect_to_agent(client, transport) + try: + await asyncio.wait_for(conn.initialize(protocol_version=1), timeout=10) + new = await asyncio.wait_for(conn.new_session(cwd=".", mcp_servers=[]), timeout=10) + result = await asyncio.wait_for(conn.prompt(session_id=new.session_id, prompt=[]), timeout=10) + assert result.stop_reason == "end_turn" + await asyncio.sleep(0.2) + assert client.updates, "expected a session/update notification over WS" + assert client.permission_requested, "expected a server->client permission request" + finally: + await conn.close() + await transport.close() diff --git a/tests/http/test_protocol.py b/tests/http/test_protocol.py new file mode 100644 index 0000000..8b58cba --- /dev/null +++ b/tests/http/test_protocol.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from acp.http.protocol import ( + INITIALIZE_METHOD, + is_initialize_request, + is_response_message, + message_id_key, + method_requires_session_header, + session_id_from_message, + session_id_from_params, + session_id_from_result, +) + + +def test_is_initialize_request() -> None: + assert is_initialize_request({"method": INITIALIZE_METHOD, "id": 1, "params": {}}) + assert not is_initialize_request({"method": "session/new", "id": 2}) + # A notification (no id) is not a request. + assert not is_initialize_request({"method": INITIALIZE_METHOD}) + + +def test_is_response_message() -> None: + assert is_response_message({"id": 1, "result": {}}) + assert is_response_message({"id": 1, "error": {"code": -1, "message": "x"}}) + assert not is_response_message({"id": 1, "method": "session/prompt"}) + assert not is_response_message({"method": "session/update", "params": {}}) + + +def test_method_requires_session_header() -> None: + assert method_requires_session_header("session/prompt") + assert method_requires_session_header("session/cancel") + assert method_requires_session_header("session/set_mode") + # Connection-level methods (and session-establishing ones) do not require the header. + assert not method_requires_session_header("initialize") + assert not method_requires_session_header("session/new") + assert not method_requires_session_header("session/load") + assert not method_requires_session_header("session/list") + assert not method_requires_session_header(None) + + +def test_message_id_key_normalizes_int_and_str() -> None: + assert message_id_key(1) == "1" + assert message_id_key("1") == "1" + assert message_id_key(1) == message_id_key("1") + assert message_id_key(None) is None + + +def test_session_id_extraction() -> None: + assert session_id_from_params({"sessionId": "s1"}) == "s1" + assert session_id_from_params({}) is None + assert session_id_from_params(None) is None + assert session_id_from_result({"sessionId": "s2"}) == "s2" + assert session_id_from_message({"params": {"sessionId": "s3"}}) == "s3" + assert session_id_from_message({"result": {"sessionId": "s4"}}) == "s4" + assert session_id_from_message({"result": {}}) is None diff --git a/tests/http/test_sse.py b/tests/http/test_sse.py new file mode 100644 index 0000000..2003c1b --- /dev/null +++ b/tests/http/test_sse.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +from collections.abc import AsyncIterator + +import pytest + +from acp._sse import parse_sse_stream, serialize_sse_event, serialize_sse_keepalive + + +def test_serialize_sse_event_frames_json_with_blank_line() -> None: + frame = serialize_sse_event({"jsonrpc": "2.0", "id": 1, "result": {"ok": True}}) + assert frame == b'data: {"jsonrpc":"2.0","id":1,"result":{"ok":true}}\n\n' + + +def test_serialize_sse_keepalive_is_a_comment() -> None: + assert serialize_sse_keepalive() == b": keepalive\n\n" + + +async def _aiter(chunks: list[bytes]) -> AsyncIterator[bytes]: + for chunk in chunks: + yield chunk + + +@pytest.mark.asyncio +async def test_parse_single_event() -> None: + stream = _aiter([b'data: {"id":1}\n\n']) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"id": 1}] + + +@pytest.mark.asyncio +async def test_parse_multiple_events_split_across_chunks() -> None: + stream = _aiter([b'data: {"id', b'":1}\n\ndata: {"id":2}', b"\n\n"]) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"id": 1}, {"id": 2}] + + +@pytest.mark.asyncio +async def test_parse_ignores_comments_and_other_fields() -> None: + stream = _aiter([b': keepalive\n\nevent: message\ndata: {"id":7}\n\n']) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"id": 7}] + + +@pytest.mark.asyncio +async def test_parse_multiline_data_is_joined() -> None: + stream = _aiter([b'data: {"a":1,\ndata: "b":2}\n\n']) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"a": 1, "b": 2}] + + +@pytest.mark.asyncio +async def test_parse_flushes_trailing_event_without_blank_line() -> None: + stream = _aiter([b'data: {"id":9}\n']) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"id": 9}] + + +@pytest.mark.asyncio +async def test_parse_skips_invalid_json() -> None: + stream = _aiter([b'data: not-json\n\ndata: {"id":1}\n\n']) + events = [event async for event in parse_sse_stream(stream)] + assert events == [{"id": 1}] diff --git a/tests/http/test_websocket.py b/tests/http/test_websocket.py new file mode 100644 index 0000000..cf21cf5 --- /dev/null +++ b/tests/http/test_websocket.py @@ -0,0 +1,182 @@ +"""WebSocket transport tests (client + ASGI server handler).""" + +from __future__ import annotations + +import asyncio +import json +from typing import Any + +import pytest +from websockets.asyncio.server import serve + +from acp.http.protocol import CONNECTION_ID_HEADER +from acp.http.server import AcpServer +from acp.schema import NewSessionResponse, PromptResponse +from acp.ws.client import create_websocket_stream +from acp.ws.server import handle_asgi_websocket +from tests.conftest import TestAgent + + +class _Agent(TestAgent): + def __init__(self) -> None: + super().__init__() + self._conn: Any = None + + def on_connect(self, conn: Any) -> None: + self._conn = conn + + async def new_session(self, cwd: str | None = None, mcp_servers: Any = None, **kwargs: Any) -> NewSessionResponse: + return NewSessionResponse(session_id="sess-ws") + + async def prompt(self, session_id: str, prompt: Any = None, **kwargs: Any) -> PromptResponse: + await self._conn.session_update( + session_id=session_id, + update={"sessionUpdate": "agent_message_chunk", "content": {"type": "text", "text": "yo"}}, + ) + return PromptResponse(stop_reason="end_turn") + + +# -- Client transport against a plain echo websocket server -------------------- + + +@pytest.mark.asyncio +async def test_client_transport_send_receive_text_frames() -> None: + async def echo(ws: Any) -> None: + async for msg in ws: + data = json.loads(msg) + await ws.send(json.dumps({"echo": data})) + + async with serve(echo, "localhost", 0) as server: + port = server.sockets[0].getsockname()[1] + transport = await create_websocket_stream(f"ws://localhost:{port}") + try: + await transport.send({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}) + received = await asyncio.wait_for(transport.receive(), timeout=1) + assert received == {"echo": {"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {}}} + finally: + await transport.close() + + +@pytest.mark.asyncio +async def test_client_transport_receive_returns_none_on_close() -> None: + async def close_immediately(ws: Any) -> None: + await ws.close() + + async with serve(close_immediately, "localhost", 0) as server: + port = server.sockets[0].getsockname()[1] + transport = await create_websocket_stream(f"ws://localhost:{port}") + try: + assert await asyncio.wait_for(transport.receive(), timeout=1) is None + finally: + await transport.close() + + +@pytest.mark.asyncio +async def test_client_transport_ignores_binary_frames() -> None: + async def send_binary_then_text(ws: Any) -> None: + await ws.send(b"\x00\x01") + await ws.send(json.dumps({"ok": True})) + await ws.recv() + + async with serve(send_binary_then_text, "localhost", 0) as server: + port = server.sockets[0].getsockname()[1] + transport = await create_websocket_stream(f"ws://localhost:{port}") + try: + received = await asyncio.wait_for(transport.receive(), timeout=1) + assert received == {"ok": True} + finally: + await transport.close() + + +# -- ASGI websocket server handler --------------------------------------------- + + +class _FakeAsgiSocket: + """In-memory ASGI websocket double driving handle_asgi_websocket.""" + + def __init__(self) -> None: + self._incoming: asyncio.Queue[dict[str, Any]] = asyncio.Queue() + self.sent: list[dict[str, Any]] = [] + self.accepted_headers: list[tuple[bytes, bytes]] = [] + self._sent_event = asyncio.Event() + + def client_connect(self) -> None: + self._incoming.put_nowait({"type": "websocket.connect"}) + + def client_send_text(self, message: dict[str, Any]) -> None: + self._incoming.put_nowait({"type": "websocket.receive", "text": json.dumps(message)}) + + def client_disconnect(self) -> None: + self._incoming.put_nowait({"type": "websocket.disconnect", "code": 1000}) + + async def receive(self) -> dict[str, Any]: + return await self._incoming.get() + + async def send(self, message: dict[str, Any]) -> None: + if message["type"] == "websocket.accept": + self.accepted_headers = message.get("headers", []) + elif message["type"] == "websocket.send": + self.sent.append(json.loads(message["text"])) + self._sent_event.set() + + async def wait_for_send(self, predicate, timeout: float = 1.0) -> dict[str, Any]: + async def _poll() -> dict[str, Any]: + while True: + for item in self.sent: + if predicate(item): + return item + self._sent_event.clear() + await self._sent_event.wait() + + return await asyncio.wait_for(_poll(), timeout=timeout) + + +@pytest.mark.asyncio +async def test_asgi_websocket_handshake_returns_connection_id() -> None: + server = AcpServer(lambda conn: _Agent()) + socket = _FakeAsgiSocket() + socket.client_connect() + handler = asyncio.ensure_future(handle_asgi_websocket(server, {"type": "websocket"}, socket.receive, socket.send)) + await asyncio.sleep(0.05) + header_names = [k for k, _ in socket.accepted_headers] + assert CONNECTION_ID_HEADER.lower().encode() in header_names + socket.client_disconnect() + await asyncio.wait_for(handler, timeout=1) + await server.close() + + +@pytest.mark.asyncio +async def test_asgi_websocket_full_flow() -> None: + server = AcpServer(lambda conn: _Agent()) + socket = _FakeAsgiSocket() + socket.client_connect() + handler = asyncio.ensure_future(handle_asgi_websocket(server, {"type": "websocket"}, socket.receive, socket.send)) + await asyncio.sleep(0.05) + + socket.client_send_text({"jsonrpc": "2.0", "id": 0, "method": "initialize", "params": {"protocolVersion": 1}}) + init_resp = await socket.wait_for_send(lambda m: m.get("id") == 0) + assert "result" in init_resp + + socket.client_send_text({ + "jsonrpc": "2.0", + "id": 1, + "method": "session/new", + "params": {"cwd": "/", "mcpServers": []}, + }) + new_resp = await socket.wait_for_send(lambda m: m.get("id") == 1) + assert new_resp["result"]["sessionId"] == "sess-ws" + + socket.client_send_text({ + "jsonrpc": "2.0", + "id": 2, + "method": "session/prompt", + "params": {"sessionId": "sess-ws", "prompt": []}, + }) + notif = await socket.wait_for_send(lambda m: m.get("method") == "session/update") + assert notif["params"]["sessionId"] == "sess-ws" + prompt_resp = await socket.wait_for_send(lambda m: m.get("id") == 2) + assert prompt_resp["result"]["stopReason"] == "end_turn" + + socket.client_disconnect() + await asyncio.wait_for(handler, timeout=1) + await server.close() diff --git a/tests/http/test_ws_cookies.py b/tests/http/test_ws_cookies.py new file mode 100644 index 0000000..a5fdd89 --- /dev/null +++ b/tests/http/test_ws_cookies.py @@ -0,0 +1,55 @@ +"""WebSocket client cookie support (RFD §5: cookies MUST work on WS transport).""" + +from __future__ import annotations + +import asyncio +from typing import Any + +import pytest +from websockets.asyncio.server import serve + +from acp._cookies import MemoryAcpCookieStore +from acp.ws.client import create_websocket_stream + + +@pytest.mark.asyncio +async def test_ws_client_captures_set_cookie_from_handshake() -> None: + """A caller-owned cookie store must capture Set-Cookie from the upgrade response.""" + + def process_response(connection: Any, request: Any, response: Any) -> Any: + response.headers["Set-Cookie"] = "affinity=abc123; Path=/" + return response + + async def handler(ws: Any) -> None: + await ws.close() + + store = MemoryAcpCookieStore() + async with serve(handler, "localhost", 0, process_response=process_response) as server: + port = server.sockets[0].getsockname()[1] + transport = await create_websocket_stream(f"ws://localhost:{port}", cookie_store=store) + try: + assert store.cookie_header() == "affinity=abc123" + finally: + await transport.close() + + +@pytest.mark.asyncio +async def test_ws_client_sends_stored_cookie_on_handshake() -> None: + """Stored cookies must be echoed back as a Cookie header on the next handshake.""" + seen: dict[str, Any] = {} + + async def handler(ws: Any) -> None: + seen["cookie"] = ws.request.headers.get("Cookie") + await ws.close() + + store = MemoryAcpCookieStore() + store.store_set_cookie("affinity=abc123") + + async with serve(handler, "localhost", 0) as server: + port = server.sockets[0].getsockname()[1] + transport = await create_websocket_stream(f"ws://localhost:{port}", cookie_store=store) + try: + await asyncio.sleep(0.05) + assert seen.get("cookie") == "affinity=abc123" + finally: + await transport.close() diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 4bdc0a9..5e8a917 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -744,7 +744,7 @@ async def test_connection_init_under_eager_task_factory(server): # Regression: under asyncio.eager_task_factory the receive loop runs synchronously # up to its first await inside Connection.__init__, so every attribute it reads - # (e.g. _receive_timeout) must be assigned before _tasks.create(_receive_loop()). + # (i.e. the message transport) must be assigned before _tasks.create(_receive_loop()). loop = asyncio.get_running_loop() previous_factory = loop.get_task_factory() loop.set_task_factory(eager_task_factory) @@ -758,7 +758,7 @@ async def test_connection_init_under_eager_task_factory(server): finally: loop.set_task_factory(previous_factory) - assert conn._receive_timeout == 0.5 + assert conn._transport._receive_timeout == 0.5 # type: ignore[attr-defined] # Let the loop tick once so any deferred receive-task crash would land. await asyncio.sleep(0) assert conn._disconnected is False diff --git a/uv.lock b/uv.lock index d8abdd3..a319fad 100644 --- a/uv.lock +++ b/uv.lock @@ -11,6 +11,10 @@ dependencies = [ ] [package.optional-dependencies] +http = [ + { name = "httpx", extra = ["http2"] }, + { name = "websockets" }, +] logfire = [ { name = "logfire" }, { name = "opentelemetry-sdk" }, @@ -20,6 +24,7 @@ logfire = [ dev = [ { name = "datamodel-code-generator" }, { name = "deptry" }, + { name = "httpx", extra = ["http2"] }, { name = "mkdocs" }, { name = "mkdocs-material" }, { name = "mkdocstrings", extra = ["python"] }, @@ -30,20 +35,25 @@ dev = [ { name = "ruff" }, { name = "tox-uv" }, { name = "ty" }, + { name = "uvicorn" }, + { name = "websockets" }, ] [package.metadata] requires-dist = [ + { name = "httpx", extras = ["http2"], marker = "extra == 'http'", specifier = ">=0.27" }, { name = "logfire", marker = "extra == 'logfire'", specifier = ">=0.14" }, { name = "opentelemetry-sdk", marker = "extra == 'logfire'", specifier = ">=1.28.0" }, { name = "pydantic", specifier = ">=2.7" }, + { name = "websockets", marker = "extra == 'http'", specifier = ">=12.0" }, ] -provides-extras = ["logfire"] +provides-extras = ["logfire", "http"] [package.metadata.requires-dev] dev = [ { name = "datamodel-code-generator", specifier = ">=0.25" }, { name = "deptry", specifier = ">=0.23.0" }, + { name = "httpx", extras = ["http2"], specifier = ">=0.27" }, { name = "mkdocs", specifier = ">=1.4.2" }, { name = "mkdocs-material", specifier = ">=8.5.10" }, { name = "mkdocstrings", extras = ["python"], specifier = ">=0.26.1" }, @@ -54,6 +64,8 @@ dev = [ { name = "ruff", specifier = ">=0.11.5" }, { name = "tox-uv", specifier = ">=1.11.3" }, { name = "ty", specifier = ">=0.0.1a16" }, + { name = "uvicorn", specifier = ">=0.30" }, + { name = "websockets", specifier = ">=12.0" }, ] [[package]] @@ -65,6 +77,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] +[[package]] +name = "anyio" +version = "4.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/72/5562aabb8dd7181e8e860622a38bea08d17842b99ecd4c91f84ac95251b0/anyio-4.14.1.tar.gz", hash = "sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e", size = 254831, upload-time = "2026-06-24T20:56:06.017Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/7b/90df4a0a816d98d6ea26f559d87836d494a2cf1fcf063be67df50a7bcc30/anyio-4.14.1-py3-none-any.whl", hash = "sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72", size = 124875, upload-time = "2026-06-24T20:56:04.413Z" }, +] + [[package]] name = "argcomplete" version = "3.6.3" @@ -352,7 +378,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -422,6 +448,79 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/b1/9ff6578d789a89812ff21e4e0f80ffae20a65d5dd84e7a17873fe3b365be/griffe-1.14.0-py3-none-any.whl", hash = "sha256:0e9d52832cccf0f7188cfe585ba962d2674b241c01916d780925df34873bceb0", size = 144439, upload-time = "2025-09-05T15:02:27.511Z" }, ] +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "h2" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack" }, + { name = "hyperframe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, +] + +[[package]] +name = "hpack" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/5b/fcabf6028144a8723726318b07a32c2f3314acdff6265743cf08a344b18e/hpack-4.2.0.tar.gz", hash = "sha256:0895cfa3b5531fc65fe439c05eb65144f123bf7a394fcaa56aa423548d8e45c0", size = 51300, upload-time = "2026-06-23T18:34:46.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/b4/4a9fcfb2aef6ba44d9073ecd301443aa00b3dac95de5619f2a7de7ec8a91/hpack-4.2.0-py3-none-any.whl", hash = "sha256:858ac0b02280fa582b5080d68db0899c62a80375e0e5413a74970c5e518b6986", size = 34246, upload-time = "2026-06-23T18:34:45.472Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[package.optional-dependencies] +http2 = [ + { name = "h2" }, +] + +[[package]] +name = "hyperframe" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload-time = "2025-01-22T21:41:49.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload-time = "2025-01-22T21:41:47.295Z" }, +] + [[package]] name = "idna" version = "3.15" @@ -1536,6 +1635,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/7d/fa3a9960c95af9bbe2a629048760d0b9b4fead8ccd4f2235af747ec7cdf0/uv-0.11.15-py3-none-win_arm64.whl", hash = "sha256:4f39426a13dee24897aed60c4b98058c66f18bd983885ac5f4a54a04b24fbddf", size = 23198178, upload-time = "2026-05-18T19:57:14.68Z" }, ] +[[package]] +name = "uvicorn" +version = "0.51.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a2/65/b7c6c443ccc58678c91e1e973bbe2a878591538655d6e1d47f24ba1c51f3/uvicorn-0.51.0.tar.gz", hash = "sha256:f6f4b69b657c312f516dd2d268ab9ae6f254b11e4bac504f37b2ab58b24dd0b0", size = 94412, upload-time = "2026-07-08T10:59:05.962Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/ec/dbb7e5a6b91f86bfb9eb7d2988a2730907b6a729875b949c7f022e8b88fa/uvicorn-0.51.0-py3-none-any.whl", hash = "sha256:5d38af6cd620f2ae3849fb44fd4879e0890aa1febe8d47eb355fb45d93fe6a5b", size = 73219, upload-time = "2026-07-08T10:59:04.44Z" }, +] + [[package]] name = "virtualenv" version = "20.36.1" @@ -1583,6 +1696,122 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] +[[package]] +name = "websockets" +version = "16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/02/b9a097e1e16fee4e2fd1ec8c39f6a9c5d6257bae8fa12640caf869f54436/websockets-16.1.tar.gz", hash = "sha256:299468cbe42e2b9981134c7c51d99387d8a7bf562b00183b3eec53f882846dad", size = 182530, upload-time = "2026-07-10T06:32:57.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/31/cd11d2796b95c93645bac8e396b0f4bac0896a07a7b87d473bfc359f02c3/websockets-16.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de72a9c611178b15557d98eabd3101c9663c4d68938510478a6d162f99afd213", size = 179772, upload-time = "2026-07-10T06:30:22.983Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9b/34306d802f9b599eab041688a2086318037560cfae616a860234cca575b6/websockets-16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:37b0e4d726ffea3776670092d3d13e1cb605076f036a695fd1259de0d9b9fe02", size = 177457, upload-time = "2026-07-10T06:30:24.636Z" }, + { url = "https://files.pythonhosted.org/packages/06/3a/36ebbb978a7af70ff952afe5b22561264967164e9ad68b6734cae94efeb4/websockets-16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:00d50c0a27098fcb7ab47b3d99a1b1159b534dbcd959fbf05113ebc37e5f927b", size = 177737, upload-time = "2026-07-10T06:30:25.954Z" }, + { url = "https://files.pythonhosted.org/packages/17/d7/944f341d0d3c0450ffd3d171479531df1818cb1df1623af4065113999c44/websockets-16.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1acb698bff1da1782b31aebd8d7a24d7d05453964abcd7d03dbf6e25893908e8", size = 186244, upload-time = "2026-07-10T06:30:27.235Z" }, + { url = "https://files.pythonhosted.org/packages/32/e5/a9b98fc49ef0214718a9c839c6c63856a921877256ec46f371be32decfa8/websockets-16.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc2c453f3b5f99c56b16e233aad5299860558487d26adb2ed27a00c14ca24b8c", size = 187484, upload-time = "2026-07-10T06:30:28.615Z" }, + { url = "https://files.pythonhosted.org/packages/ad/7a/a575b52ca090b1976ffbe4b5f0762d03f399dfcb48eab883101331be71a9/websockets-16.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1a9f08a0728b0835f1c6abe1d9b746ab3de49b7336a0e1919cf96be1e76273eb", size = 190143, upload-time = "2026-07-10T06:30:29.91Z" }, + { url = "https://files.pythonhosted.org/packages/7c/40/705fbbd5677242fd36f724e9a94103e6bbdcb7d71e8f4498bfc1a8a7d413/websockets-16.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a089979d6173b27af18026c8d8b0077f83669a9169174482c4651e9f5739a5b6", size = 188004, upload-time = "2026-07-10T06:30:31.357Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0c/58227c8d66b1c4060c53bac8e066fb4fe2603060408e934f48660a448d72/websockets-16.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3c18dba232ec2b92a68579c9fed8ff5a18f853d1e09fc0b6ca3159e94f689fe", size = 186689, upload-time = "2026-07-10T06:30:32.712Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d0/5c1314782594aa347e0f18808ee277a61986a2a2f9f470df9893183995bd/websockets-16.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c1eb7df4170d5068892a8834fb5c07b9552353deb0dbeb0bff3820481ae4792", size = 184559, upload-time = "2026-07-10T06:30:34.127Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e6/109c6f16850fd674b7e3d0e58b8987f05d3881abaa25f42a9faf5e85f097/websockets-16.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c522bd48e625b6d557aa228967258d6d3da031c4cc21d3352fb302479aa9ba0a", size = 186997, upload-time = "2026-07-10T06:30:35.397Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ec/6afa1aebc59426438b85cf7a3868c53a89005e2250a648c99e99943b90a4/websockets-16.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d106396927a7f00b0f3a69215c3357f87bf0bca6844247121f7e8291e826a3b1", size = 185621, upload-time = "2026-07-10T06:30:36.88Z" }, + { url = "https://files.pythonhosted.org/packages/27/24/c038fe8682e9345bfa422d2cc5cc68b0491ab942c92e176bf8dfa6e8331f/websockets-16.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d71bed12909b8039955536e192867d02d76cd3797cedfd0facf822e7668636c3", size = 187384, upload-time = "2026-07-10T06:30:38.096Z" }, + { url = "https://files.pythonhosted.org/packages/30/ca/dc0ef2be39c67394e24bc982a0af59cd6249bf2f4e4272813c5c505d0da9/websockets-16.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:9c1cf6f9a936b030b5bed0e800c5ee32069338129084546baf5ff5014dc62fa9", size = 185258, upload-time = "2026-07-10T06:30:39.579Z" }, + { url = "https://files.pythonhosted.org/packages/17/6b/3ffecd83ca3404b41fbdf8e9b178e55b529cd59bf64ea08b5a37b616b568/websockets-16.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3fd3e6a7af2c8fcdcf4ffbeaf7f54a567b91a83267204187797f31faaa2a4efa", size = 186050, upload-time = "2026-07-10T06:30:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/75/26/2e068497c78f31591a610ab7ef6d8d383ecadbe98f9121e1ebda77ef6d2b/websockets-16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dddd27175bf640acae5561fa79b77e8ec71fc445816200523e5c19b6a556fb72", size = 186273, upload-time = "2026-07-10T06:30:42.309Z" }, + { url = "https://files.pythonhosted.org/packages/44/ab/4dc049cb2c9e1be3a2c6fef77118f9c5049979e99cd56a97759d2f40f980/websockets-16.1-cp310-cp310-win32.whl", hash = "sha256:cce36c80b3f2fede7942f1756d3d885fa6fa086766c8c1bcf00695ab80f0d51a", size = 180157, upload-time = "2026-07-10T06:30:43.565Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4f/5e010ce5f66a8e5df380843f704ada508195a021c0c8a0f933639c9ee1c0/websockets-16.1-cp310-cp310-win_amd64.whl", hash = "sha256:115fc4695b94bb855995b23fb1abcb66099a5995575d3d5bc5605a616c58d0eb", size = 180458, upload-time = "2026-07-10T06:30:45.01Z" }, + { url = "https://files.pythonhosted.org/packages/9e/13/d47429afcc2c28616c32640009c84ea3f95660dab805766345b9682468e0/websockets-16.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a9b1d7a63cba8e6b9b77e499a81eab29d31100298d090ad4507d1048c0b9cae0", size = 179770, upload-time = "2026-07-10T06:30:46.308Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c7/2f0a722039a1e0107be73ed672ba604449b4956e48733e8e6b8a005aea42/websockets-16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bedbc5efeb96621aa2921d2d92608246691399418cac22acba427eb11877ea1f", size = 177455, upload-time = "2026-07-10T06:30:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/43/6a/c26b0ae449e93d256ce5cdd50d5fe97b575a63e8dcd311a1faa972fd6bc6/websockets-16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fd847ab82133015afe65d778e7966ab42dba16bd7ad2e5b8a7918db6539f3f94", size = 177731, upload-time = "2026-07-10T06:30:49.102Z" }, + { url = "https://files.pythonhosted.org/packages/cc/3f/381550b344a02f0d2f84cda25e79b54575291bc7022128a41163fe8ba5b0/websockets-16.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e2fb33ccb16ee40a95cc676d7b0ff451a9a2632f11a0dbc2e666326892b2e1de", size = 187066, upload-time = "2026-07-10T06:30:50.505Z" }, + { url = "https://files.pythonhosted.org/packages/4a/87/5ab1ec2086910f23cfb9ec0c1c29fbcc24a9d190b5198b1557c00ce4a47e/websockets-16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f15b6d9ea9c2eaf6ccab964a082b09bfa6634a495bb0c2e9e7ee6943f58976", size = 188301, upload-time = "2026-07-10T06:30:51.835Z" }, + { url = "https://files.pythonhosted.org/packages/75/4b/bbbb8e6fac4cfc53d7aaa69a3d531bf10799354b0021f4b58914aced8c1a/websockets-16.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:638cf57c48b4ad8ac1ff1e453f4f97db2426b690ddc111e6da96b27b4a340bc3", size = 191594, upload-time = "2026-07-10T06:30:53.229Z" }, + { url = "https://files.pythonhosted.org/packages/5c/da/6c0c349443d6e999f481e3d9a0e57e7ac2956d75d6391bec24b92af3fe13/websockets-16.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2c1c85f61bc9d5eac57ce705d848dc2d2ce3680638300bf4e1da7d749e2cf4ce", size = 188862, upload-time = "2026-07-10T06:30:54.744Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ea/a368d37c010425a5451f42052fe804e754e23333e8448aef5d55c8a8d64f/websockets-16.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:eeab6d27f51c7e579023c971f5e6dff200deadf01faf6831beaecd32052dfaef", size = 187633, upload-time = "2026-07-10T06:30:56.055Z" }, + { url = "https://files.pythonhosted.org/packages/0d/4e/2ecd59add10d0855ec03dbdedfcdacdbd1aaabcd44b7dcbeda27538662e9/websockets-16.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2ed64e5a97b0b97a0b66e18bfe281317a75fbbd5afe692f939ea8d14a4292f2c", size = 185089, upload-time = "2026-07-10T06:30:57.444Z" }, + { url = "https://files.pythonhosted.org/packages/6f/eb/c6c3dcd7a01097bb0d42f4e9ef21a2c2a491d36b77cd0870ab59f9e8e77f/websockets-16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9b3b021d0ed4bc16eea9775f62c9fa71acdacba0fc790b38581754dedf29ca60", size = 187790, upload-time = "2026-07-10T06:30:58.731Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3e/775d36885d5e48ab8020aaf377de0ff5fbeb8bc2682a7e46419e4a14521c/websockets-16.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6eb604a4167f0a0d53c2243dfc667a29f0b43c3436057184e070bb82a1000fa2", size = 186381, upload-time = "2026-07-10T06:31:00.355Z" }, + { url = "https://files.pythonhosted.org/packages/ad/90/6305c00812a92e47d0582604c02bd759db0118bbafc13f707d712dbcf898/websockets-16.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9a3f125e44c3e34d61d111652e608e0f5b85ce08c225c8d56ad0eb822fa40030", size = 188193, upload-time = "2026-07-10T06:31:01.677Z" }, + { url = "https://files.pythonhosted.org/packages/f6/32/96bf8302c81d961585b4d34a2ddd3f229782f9b8c57bc78bbf98f1b1a4ac/websockets-16.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8fdf0b00d0d1f30d1f06a92cab46fe542eec3eb302a7aee7163f142d0780f216", size = 185771, upload-time = "2026-07-10T06:31:03.062Z" }, + { url = "https://files.pythonhosted.org/packages/e8/1f/e8fe44b1d2dc417d740d9959d28fd2a846f268e7df38a686c04ac7dfe947/websockets-16.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:67b56828712f5fa7852de4c0265c28827311a657a4d275b7312ed0d1a918bee4", size = 186803, upload-time = "2026-07-10T06:31:04.34Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/b07d3a4e1eb2ab03e94e7f53f0c7a628e85fde6ad86011f7afd08f27b985/websockets-16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39c7e7730be33b8f0cd6f0aa8e8c82f9cdd1813f159765e073b2ece65f4824b5", size = 187041, upload-time = "2026-07-10T06:31:05.567Z" }, + { url = "https://files.pythonhosted.org/packages/a6/fd/e0abb8acc435642ac4a671490f6cf781c882f3fe682cdced9080ea455ab5/websockets-16.1-cp311-cp311-win32.whl", hash = "sha256:c54fe94fb2f11e11b48920c5f971e298cec73ac35db56efe57a49db63dfc95d4", size = 180158, upload-time = "2026-07-10T06:31:06.929Z" }, + { url = "https://files.pythonhosted.org/packages/81/06/85574d9458d3b913090087b817df0cc47b68e9a01dd0ab6ac04b77f49b0a/websockets-16.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9f4fb9ae8b802e55609685db98382d48fd3feb1397804e1e774968dea0f28c7", size = 180456, upload-time = "2026-07-10T06:31:08.247Z" }, + { url = "https://files.pythonhosted.org/packages/a1/52/748c014f07f4e0e170c8932de7e647a1511d5ab3049cd978797136aee577/websockets-16.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b6aa3f7ad345cf3862c21f4fbf2ef5e14d911348476c2845e137c091fe3a3f0b", size = 179798, upload-time = "2026-07-10T06:31:09.664Z" }, + { url = "https://files.pythonhosted.org/packages/8b/5e/2a2e64d977d084e49d37c187c26c056daaff41965be7300cd5dbde6f8b07/websockets-16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b43fcfb521ac2f34ba80b7b8ea16303e4ad82dd8af667bf40839ad3a5d37b164", size = 177478, upload-time = "2026-07-10T06:31:11.072Z" }, + { url = "https://files.pythonhosted.org/packages/aa/12/5b85b4e75d697e548a94962ce5c036b05dd21cb9545759d555c5586422fc/websockets-16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2bd3e12cd9afbe2baedae0b1eeade8ba64329b60fe2f9abdc966bd10fd2c2ef5", size = 177746, upload-time = "2026-07-10T06:31:12.386Z" }, + { url = "https://files.pythonhosted.org/packages/9d/62/79b1c8f0cee0da648b4899e1c5b0dbd3aa59846985136a54854db6827ab4/websockets-16.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35f41979c8623df9bd30d949d82010a8fda5c56ff12cd8508a5b7272b6d4b53a", size = 187345, upload-time = "2026-07-10T06:31:13.754Z" }, + { url = "https://files.pythonhosted.org/packages/25/34/b7c5c52c2f24280e1c017acb7ad491a566750a5cceca7f3cf999373bba21/websockets-16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a24d1f35aef07d794a16c853c688e74956c50239bec37b4f2de080056046419b", size = 188581, upload-time = "2026-07-10T06:31:15.075Z" }, + { url = "https://files.pythonhosted.org/packages/bc/37/604193bebcbeffe96fdf795960b83a15d600880c64dc17ec9c31c5b3427d/websockets-16.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c64c024ddf7a35331b21fcddb562a039c275d2c82e8c2d12939e7da23997270", size = 191362, upload-time = "2026-07-10T06:31:16.395Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b4/5ee27575b367d7110d4d13945e2a9de067ec84dc71e54b87f01e38550d9a/websockets-16.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c3e99757f5baafe20fc598e202ea6f5b0b265186ad38d0a17bd8beca16296955", size = 189216, upload-time = "2026-07-10T06:31:17.776Z" }, + { url = "https://files.pythonhosted.org/packages/7e/22/3e2dcc78d85fc5d9d814895ce6d07d0dfacc0f6aaa1d151f2b8c8d772299/websockets-16.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:353f3bc6e058ac1ccab4b3588e8598837a8c04cfc8351233e6d523be675d844c", size = 187971, upload-time = "2026-07-10T06:31:19.152Z" }, + { url = "https://files.pythonhosted.org/packages/9e/2f/cd271717b93d5ee19626cb5e38a85baab745c86e33db7c31a3ac729b31b8/websockets-16.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0352f5b38b40e857b6428d468fa21dbb4dd4a567d933c26d9831b4efe1b92f43", size = 185381, upload-time = "2026-07-10T06:31:20.665Z" }, + { url = "https://files.pythonhosted.org/packages/78/91/6ad6f2f1426317b5001bd490534208c7360636b35bac1dec2e0c22bfc40e/websockets-16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:70bd789afab579602968c39f21cb925466505f3edff22f0ae852bca54978a4f9", size = 188015, upload-time = "2026-07-10T06:31:22.024Z" }, + { url = "https://files.pythonhosted.org/packages/c7/6d/533733132ab4c07540efd4a8f0b9a435d3a5059b2f26cc476ace1abf7f45/websockets-16.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d0fb4b46f121eccd539353baebd1083a8767a9a351109453d1d1caecd1ba40c2", size = 186619, upload-time = "2026-07-10T06:31:23.376Z" }, + { url = "https://files.pythonhosted.org/packages/08/73/16c059f3d73b3331eba10793704afa4faa9939234fb08ef7dca35794e8f0/websockets-16.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c14b6634af01541e4efe2954fd8f263386f7aa6d37c01e55dd8109fd17661452", size = 188497, upload-time = "2026-07-10T06:31:25.024Z" }, + { url = "https://files.pythonhosted.org/packages/4d/89/9a8fae7dd2acdcfb1a8844c29fe42b518a04b64fce38a0923b6290e452f1/websockets-16.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a58532c49a851bcb481e58c1be23b315c17fe2fbbed509d75aeea12f543d2c15", size = 186051, upload-time = "2026-07-10T06:31:26.291Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/b240c7dd6a0e0c59c1f68377cc3015263521080c327c15f5e753c1f6d378/websockets-16.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4e969170c3b08e1d8dabd990fef1fa702c4233aeaabec33f871806e444f6a0e4", size = 187029, upload-time = "2026-07-10T06:31:27.605Z" }, + { url = "https://files.pythonhosted.org/packages/50/35/524e3fac40e47d6fdcf6c4b2c95ef1bc8a97e01593c90eff86621df7b716/websockets-16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff9b000064b88787ba9f7a3cb2af2b68a658ca5aad76458a46469e7124b678a0", size = 187308, upload-time = "2026-07-10T06:31:28.927Z" }, + { url = "https://files.pythonhosted.org/packages/00/13/56840cf62c8859af6ba22b9529da937332468c80f32b598753e8a66d3990/websockets-16.1-cp312-cp312-win32.whl", hash = "sha256:b9f5d83f80f4d7c4bba6d97f3755ac05850c784dce0fd2ab371c4e41172f53ff", size = 180161, upload-time = "2026-07-10T06:31:30.316Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ff/87eb9eb44cb62424a8d729834f2b0515a47e2669fabec29820268f4d50a1/websockets-16.1-cp312-cp312-win_amd64.whl", hash = "sha256:6852c9f653966c16109d3b6f31181fd734f7914927e3f0fa1117af7a18c9aa21", size = 180462, upload-time = "2026-07-10T06:31:31.708Z" }, + { url = "https://files.pythonhosted.org/packages/d9/63/df158b155420b566f025e75613424ad9649a24bcb0e9f259321ab3d58bea/websockets-16.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b0232ed141cec3df2af5a3959a071c51f40036336b0d37e17faf9ef52fc73e47", size = 179791, upload-time = "2026-07-10T06:31:33.108Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/00fe9414dfeafa6fe54eae9f5716c8c8e9ac59d192be3b893c096d395846/websockets-16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a71b73d143991714144e159f767b698f03c4a70b8a65ae1733b650cff488045b", size = 177472, upload-time = "2026-07-10T06:31:34.522Z" }, + { url = "https://files.pythonhosted.org/packages/8b/76/b10633424d40681b4e892ffd08ca5226322b2426e62d4ab71eae484c3a32/websockets-16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:187323204c3b2fc465e8fc2609e60437c521790cb9c1acb49c4c452a33e57f37", size = 177737, upload-time = "2026-07-10T06:31:35.964Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/d3bb03b2229bb1afd72008742d586cf1ea240dce64dd48c71c8c7fd3294c/websockets-16.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9dba74233c8c3ce368850818c98354dad2570f57231b3fd3bd00d7aa57628881", size = 187403, upload-time = "2026-07-10T06:31:37.496Z" }, + { url = "https://files.pythonhosted.org/packages/26/16/cc2e80478f688fc3c39c67dc1fac6a0783858058914ebc2489917462cb42/websockets-16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:63339bc8c63c86a463177775cb7c677691f5bcfac7b3b2f01b286d42acd41600", size = 188639, upload-time = "2026-07-10T06:31:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/15/d6/ad87b2507e57de1cbf897a56c963f2925962ed5e85fbe06aaa83ced27acd/websockets-16.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23e545ea8ae4263e37cdfd4e22a217f519e48e432728bc461185bbf585f38a83", size = 190078, upload-time = "2026-07-10T06:31:40.218Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1a/5b37b3fd335d5811f29fc829f2646a3e6d1463a4bf09c3100708684c766e/websockets-16.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2237081454846fb40403a80ba86d82e2038b9c45865ab96af0abe7d002a91045", size = 189267, upload-time = "2026-07-10T06:31:41.523Z" }, + { url = "https://files.pythonhosted.org/packages/42/98/06afc33e9450d4230f94c664db78875d90f5f6a5fb77f0bc6ec15ae74e1c/websockets-16.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5f5218de1ed047385ca53744caba9435d65f75d008364970a3fae95a05812cf9", size = 188022, upload-time = "2026-07-10T06:31:42.838Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bf/42fef5d5887c18cf2d148b02debf56cecb9cfbffc68027cde9b12c8f432c/websockets-16.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:75c98e3920039d0edff03b74478ada504b7ce3a1bc406db2cabfca84320f7baf", size = 185435, upload-time = "2026-07-10T06:31:44.219Z" }, + { url = "https://files.pythonhosted.org/packages/a0/9b/8021c133add5fe40ed40312553a6cd1408c069d7efe3444ad483d4973ed3/websockets-16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1facd189d8190af30487a55b4c3688484dd50801628a3b5b2ccd26db08e67057", size = 188080, upload-time = "2026-07-10T06:31:45.986Z" }, + { url = "https://files.pythonhosted.org/packages/69/54/1e37384f395eaa127383aab15c1c45e200890a7d7b99db5c312233d193e0/websockets-16.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cc0c6a6eef613c7da32d4fb068f82ef834b58134f6a16b54e6c1e5bf9529ab3d", size = 186678, upload-time = "2026-07-10T06:31:47.449Z" }, + { url = "https://files.pythonhosted.org/packages/68/79/1caeacab5bc2081e4519288d248bc8bd2de30652e6eaa94be6be09a1fe5b/websockets-16.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ad9411eded8988b879be6038206698bf7106c85a78f642c004485bcb95be17eb", size = 188554, upload-time = "2026-07-10T06:31:48.886Z" }, + { url = "https://files.pythonhosted.org/packages/ee/83/b3dca5fad71487b726e31cb0acf56f226792c1cc34e6ab18cbf146bd2d74/websockets-16.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:cd68f0914f3b64694895bc5e9b14e8b447e41d7bf5ffaf989bb8dcb5e2dfdce7", size = 186109, upload-time = "2026-07-10T06:31:50.508Z" }, + { url = "https://files.pythonhosted.org/packages/5b/0b/8f246c3712f07f207b52ea5fb47f3b2b66fafec7303162644c74aed51c6a/websockets-16.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fef2debfe7f7ebdda12176f26166f95b7af17af05ba06150fcf889032e0213e9", size = 187061, upload-time = "2026-07-10T06:31:51.861Z" }, + { url = "https://files.pythonhosted.org/packages/47/eb/27d6c92a01696b6495386af4fc941d7d0a13f2eab2bf9c336111d7321491/websockets-16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3cd6c9b798218798f4bb7b2e71c38f0e744bb94ca537b13376f88019d46384d", size = 187347, upload-time = "2026-07-10T06:31:53.246Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d5/eeee439921f55d5eaeabcea18d0f7ce32cdc39cb8fc1e185431a094c5c7b/websockets-16.1-cp313-cp313-win32.whl", hash = "sha256:84c170c6869633536921e4474b1cce7254c0c9b0053ef5725f966cee47e718e4", size = 180149, upload-time = "2026-07-10T06:31:55.058Z" }, + { url = "https://files.pythonhosted.org/packages/a3/03/971e98d4a4864cf263f9e94c5b2b7c9a9b7682d77bfbba4e732c55ee85a9/websockets-16.1-cp313-cp313-win_amd64.whl", hash = "sha256:bef52d327d70fa75dad93ee61ea2cb1d1489aca9f35c188833563f5a3b4df0a5", size = 180458, upload-time = "2026-07-10T06:31:56.767Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e6/da1dc11507f8118145a81c751fe0c77e5e1c11b8554496addb39389e2dc2/websockets-16.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:f881fca0a45dd6789939bd6637cd98169b92f1c3fdc78262f2cb9ec2cb1f324e", size = 179833, upload-time = "2026-07-10T06:31:58.19Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ac/c0d46f62e31e232487b2c123bc3cfd9a4e45684ca7dc0c37f0987f29baae/websockets-16.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:30c379d5b207d3a7f0ba4c2e4602a895b0bcc63fb5f5371a4ae7fbddb03b672b", size = 177524, upload-time = "2026-07-10T06:31:59.563Z" }, + { url = "https://files.pythonhosted.org/packages/4a/33/abd966074b34a51e4f134e0aaed80f5a4a0a35163ea5ac58a1bc5a076d23/websockets-16.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:98ab58a4faa72b46da0127ccc1931dcbfc0985b0778892300a092185910c4cbe", size = 177743, upload-time = "2026-07-10T06:32:00.959Z" }, + { url = "https://files.pythonhosted.org/packages/ea/30/646e47b8a8dff04e227bdab512e6dde60663a647eeac7bbd6edddd92bbc5/websockets-16.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e9c4e369fc181b2d41a99e01477215cecdc8546a39f7d41a59cc0a7065a0b09", size = 187474, upload-time = "2026-07-10T06:32:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/d2/72/890ab9d77494af93ea65268230bfbc0a90ba789401ed7a44356a44785644/websockets-16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0704df094b2d5fa7f6f410925a594c2a5c9a09167731a76292e5410934208209", size = 188717, upload-time = "2026-07-10T06:32:04.156Z" }, + { url = "https://files.pythonhosted.org/packages/d5/aa/baedbbaa6bf9ed6029617ed5e8976535bd805f483ca9b3484e7ad9ee08bf/websockets-16.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b22b1f4950f6ab7126623329c3b47b3b90a14c05db517f2db2a026ad6c928352", size = 190090, upload-time = "2026-07-10T06:32:05.822Z" }, + { url = "https://files.pythonhosted.org/packages/52/4f/d813ec94e18002571ef4959d87a630eff6e01b72a51bcb0832b75ae8c51a/websockets-16.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1ae4a686a662964a6671069f84f7f908cc3475e782227726b0c622c715962105", size = 189320, upload-time = "2026-07-10T06:32:07.223Z" }, + { url = "https://files.pythonhosted.org/packages/b8/3c/8ec52a6662f3df64090fba28cd521d405d54759268d8e820477037e8c80d/websockets-16.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:856bdd638f8277f86465057bfdd4da097c73058fb0f9d2bd5baea29e2bf2d367", size = 188068, upload-time = "2026-07-10T06:32:08.586Z" }, + { url = "https://files.pythonhosted.org/packages/96/7f/f0ae6042b14f86fa5f996c6563ea4cf107adc036ccbedc9d4f418d0095f9/websockets-16.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9003a1fde1c21a322a3ca3fa0c4bda8c639da81dbc925162766086643b05ba87", size = 185493, upload-time = "2026-07-10T06:32:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/89/ad/5ffc53af9939c49fd653d147fa5b8f78ced1f6bce6c49a7446860945b0ce/websockets-16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39e947b1f5fdab045174306e3916785bf3ed537648acc1549827c08c33b10953", size = 188141, upload-time = "2026-07-10T06:32:11.434Z" }, + { url = "https://files.pythonhosted.org/packages/67/62/729206c0ee577a4db8eae6dd06e0eef725a1287c6df11b2ef831d003df31/websockets-16.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5dd0e666b5931c0509cf65714686a1c5126771e663a79ac5d40da4f58b1f9502", size = 186653, upload-time = "2026-07-10T06:32:12.845Z" }, + { url = "https://files.pythonhosted.org/packages/1b/86/e8806a99ec4589914f255e6b658853fe537bf359c05e6ba5762ad9c27917/websockets-16.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:a0285df7925657ad65a65fb8dc330808bce082827538fd50ef45fa12d1fc5bca", size = 188614, upload-time = "2026-07-10T06:32:14.236Z" }, + { url = "https://files.pythonhosted.org/packages/89/38/ac554e2fc6ff0b8deeff9798b92e7abd8f99e2bd9731532e7033de208220/websockets-16.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:82d1c2cab3c133e9d059b3a5420bed9376bd30e21c185c63dda4ddadf6ddda47", size = 186165, upload-time = "2026-07-10T06:32:15.626Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c5/4ef4d8e53342f94f3c49e1ae089b32c1e8b3878e15e0022c7708c647f351/websockets-16.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:c39907f1eaf11f6277def65aa02d68f30576b693d0c1ca332aafa3caa723ac6d", size = 187119, upload-time = "2026-07-10T06:32:17.114Z" }, + { url = "https://files.pythonhosted.org/packages/3a/33/4788b1dd417bd97eeb2698af3b9df6775ac656f96e9987da0419a067602f/websockets-16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:45c5ea55446171949eb99fd34b771ceddd511ca21958d40d0197ced33159e5ee", size = 187411, upload-time = "2026-07-10T06:32:18.629Z" }, + { url = "https://files.pythonhosted.org/packages/30/38/00d37aad6dc3244ce349e2864815362e50b3cfc00cac28d216db20efe40f/websockets-16.1-cp314-cp314-win32.whl", hash = "sha256:b8ef8b1c8d6bd029a475ac432e730fba2dfd456715d26c473e2a82291024b99c", size = 179822, upload-time = "2026-07-10T06:32:20.233Z" }, + { url = "https://files.pythonhosted.org/packages/9d/37/2a8cb0eaddee5eaebda47a90a3ba0898d1ce3d866b02a4857fea17d82e5b/websockets-16.1-cp314-cp314-win_amd64.whl", hash = "sha256:7358ff21632b5d062707f73e859c824f1c3807e73d8ca25e71caca7c4cdcf145", size = 180167, upload-time = "2026-07-10T06:32:21.749Z" }, + { url = "https://files.pythonhosted.org/packages/07/5a/262ad5fcaef4198997b165060f09a63f861e76939b1786ab546ccc3f8120/websockets-16.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d0f38f4c3e9b359e257c339c2cc1967ccaeedb102e57c1c986bdce4bf4f32268", size = 180166, upload-time = "2026-07-10T06:32:23.278Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c7/36377db690f4292826e4501a6dec2801dc55fd1cf0405923b04937e478df/websockets-16.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:3c3d2cbd1602593bad49bd86fa3fbb25407d87a3b4bf8857c0ac5ac4914e1901", size = 177697, upload-time = "2026-07-10T06:32:25.164Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c7/07171abce1e39799a76f473608580fe98bd43a1230f5146159622c02bccf/websockets-16.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:36069b74671e7e667f48a7484249f84c45a825a134c8b1bdc01875d0daa10d79", size = 177902, upload-time = "2026-07-10T06:32:26.564Z" }, + { url = "https://files.pythonhosted.org/packages/14/17/c831f48e250bc4749f57c00dcce73337c41cd32f6d59a64567b84e782601/websockets-16.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:587f83c2ce8a5d628e166384d77fa7f0ac69b9007d515ab442123e6615aa8da3", size = 187766, upload-time = "2026-07-10T06:32:27.981Z" }, + { url = "https://files.pythonhosted.org/packages/2c/2e/4dfe63e245b0ecfaf470cf082d25c6ce35808159135fd88c82653a6b11ab/websockets-16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6db7972d52bc1b66cefe2246902e256cbaebc9ba8a45eac09343d7eb6671b2", size = 188939, upload-time = "2026-07-10T06:32:29.365Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e5/5faf65aebd9562f6b4bc473d24ce38cc56f84eb5f5bee66ed9b86733f93c/websockets-16.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e7d6014888a0632e1ed7a4095248bb3095232999447f2d83bfb1900987dd9ed9", size = 191081, upload-time = "2026-07-10T06:32:30.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/cd/2634f2f2c0556c1aae6501ed6840019cc569dd6fdbcac6494378daea4dc0/websockets-16.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9cb074d150e4ad2a77aa8a332c2be85f3f64f2681519d2570c1225c12c9821ff", size = 189513, upload-time = "2026-07-10T06:32:32.399Z" }, + { url = "https://files.pythonhosted.org/packages/59/bb/2c700b51196104f09715b326b1f092ed25326bdf79a03e00a4842e503743/websockets-16.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d19c9067e1fe9490f974bffbc0e443b80a7674c5efb4980c429cc00771f07c5a", size = 188240, upload-time = "2026-07-10T06:32:33.897Z" }, + { url = "https://files.pythonhosted.org/packages/f1/20/86283636e499a1a357fa9441f690ba34f255e731f2fea174132b3b762b57/websockets-16.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d440ff0c6c7469ad59c0a412c383c235935b43635e89425e3f6a0c36de90c31b", size = 185955, upload-time = "2026-07-10T06:32:35.279Z" }, + { url = "https://files.pythonhosted.org/packages/91/23/d7fb734b0095d43bc7f1c9f68afd50adb4176e7e513403e8c70ad7daa4fa/websockets-16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8613129a2533f08de24505e69a3e403cedaadae49abdb043c4d170ca71b7e4bd", size = 188491, upload-time = "2026-07-10T06:32:36.673Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5e/168a192689db468405ecf3b8e4a2c18811936b0724d017ad7e6d252734f0/websockets-16.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:a5bf9c23f197b4ec88290fd5463f33db67362a1bb10f85fc2e8e7627f0ddab97", size = 186983, upload-time = "2026-07-10T06:32:38.207Z" }, + { url = "https://files.pythonhosted.org/packages/7e/9b/66795fa91ebe49019ebe4fa910282172252e37046b80e08fc52e0c365150/websockets-16.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:520b0fd0395f075febb283c76755af724ab9fd19dffa4f3bfd18cb4e622790a3", size = 188890, upload-time = "2026-07-10T06:32:39.545Z" }, + { url = "https://files.pythonhosted.org/packages/5a/32/126bbc844be5afb3613fd43211dac10a9645f4cf39741d04acaa2ec7030c/websockets-16.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:7143aa09a67e1c013be44e81a88dfe90fc6244198ab86c7edd064152cf619805", size = 186583, upload-time = "2026-07-10T06:32:41.038Z" }, + { url = "https://files.pythonhosted.org/packages/22/b9/0b5db9cbcf6e4970db4496893244a8d92e07f71a8ef27cf34b08aa02fef1/websockets-16.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:7acb811fad08e611755800d1560e395c67e11a6bd563598ea6abb319afb86938", size = 187353, upload-time = "2026-07-10T06:32:42.501Z" }, + { url = "https://files.pythonhosted.org/packages/99/2e/254b2131a10d831b76e2c18dfe7add9729c6292c674a8085bf8de01ad151/websockets-16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c5cf88e3faa2f7931bc6baeee7599c97656a3f6ac7f831f4fccba233e141783a", size = 187784, upload-time = "2026-07-10T06:32:43.929Z" }, + { url = "https://files.pythonhosted.org/packages/21/dc/e7288aa8e3ac5a88a0924619984d663c1abf2a87d0ea98290c66fdaee0ec/websockets-16.1-cp314-cp314t-win32.whl", hash = "sha256:589f8842521c8307684ce0b40ce4ad70c5e0aa46484c6f1225a94ef4b8970341", size = 179947, upload-time = "2026-07-10T06:32:45.495Z" }, + { url = "https://files.pythonhosted.org/packages/d3/de/37edf1260ff0fbbd2f82433489c4cfbe799ac2ff21355331609879329fe6/websockets-16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c0e0857c30bbbc2bb5c30687508f0b7ec19aa026cd9f2ff8424d0fee42dcc07", size = 180291, upload-time = "2026-07-10T06:32:47.119Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f4/84ef884775bbe77c46cce79bc7d705ea3bc6574cc00acf81af89754c077d/websockets-16.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7289d899c79e763e6221c8dcb8959361cb43274418538d7c7ad16a43b01d12f9", size = 177387, upload-time = "2026-07-10T06:32:48.574Z" }, + { url = "https://files.pythonhosted.org/packages/d3/d9/6831ec6f65e1eeac770375f4f4b604f23df9bafaa1b47004bc5f9488d513/websockets-16.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e22e9e3719f5131bd62da4db63c8da63eb8c91cc99e16c1cbd122f130e1ae07a", size = 177663, upload-time = "2026-07-10T06:32:50.043Z" }, + { url = "https://files.pythonhosted.org/packages/9d/d4/21d4922fa7fe855813a8b38f181a0ecf02a586e16c1f095fd05471f78cc2/websockets-16.1-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:83bdabafef431247e6b11a9aab8a0893fd8e82e1ed95b32e0373625b03ffce4a", size = 178501, upload-time = "2026-07-10T06:32:51.439Z" }, + { url = "https://files.pythonhosted.org/packages/91/87/7a0320df854dacd09507ca972cb04a4dc5aae279583cc5b80ad5f5819533/websockets-16.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b8d13ceabc5c60995f201b5211d76876e17e68706ebf5d3bc666b32eefff1a6", size = 179397, upload-time = "2026-07-10T06:32:52.892Z" }, + { url = "https://files.pythonhosted.org/packages/31/6a/0da1eb8c8da2ace7b578c8523d32618af85e62a9ebad56051d4a14a38a1c/websockets-16.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:81495f9c0085361c582efbc3207fb877174cfe03370f17d9cd70624404aa526f", size = 180546, upload-time = "2026-07-10T06:32:54.619Z" }, + { url = "https://files.pythonhosted.org/packages/66/58/bd83247f39ddc26ffc2c24eb05087a3b749e00cb4509fc6d19daa23c8495/websockets-16.1-py3-none-any.whl", hash = "sha256:c5149dfe490ec7e5ee5dbf624c642fb725f93a5575c7f00ab594ca9eddb8dd81", size = 174031, upload-time = "2026-07-10T06:32:56.079Z" }, +] + [[package]] name = "wrapt" version = "1.17.3" From 34477bf520ef4358d11ab383c7ac21b15b17512f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 00:47:09 +0800 Subject: [PATCH 45/52] chore(deps-dev): bump datamodel-code-generator (#123) Bumps the uv group with 1 update in the / directory: [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator). Updates `datamodel-code-generator` from 0.35.0 to 0.64.0 - [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases) - [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md) - [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.35.0...0.64.0) --- updated-dependencies: - dependency-name: datamodel-code-generator dependency-version: 0.64.0 dependency-type: direct:development dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/uv.lock b/uv.lock index a319fad..5c62ff3 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,10 @@ version = 1 revision = 3 requires-python = ">=3.10, <3.15" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version < '3.14'", +] [[package]] name = "agent-client-protocol" @@ -315,23 +319,22 @@ wheels = [ [[package]] name = "datamodel-code-generator" -version = "0.35.0" +version = "0.64.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, - { name = "black" }, + { name = "black", marker = "sys_platform != 'emscripten'" }, { name = "genson" }, { name = "inflect" }, - { name = "isort" }, + { name = "isort", marker = "sys_platform != 'emscripten'" }, { name = "jinja2" }, - { name = "packaging" }, { name = "pydantic" }, { name = "pyyaml" }, - { name = "tomli", marker = "python_full_version < '3.12'" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/e1/dbf7c2edb1b1db1f4fd472ee92f985ec97d58902512013d9c4584108329c/datamodel_code_generator-0.35.0.tar.gz", hash = "sha256:46805fa2515d3871f6bfafce9aa63128e735a7a6a4cfcbf9c27b3794ee4ea846", size = 459915, upload-time = "2025-10-09T19:26:49.837Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/d2/86c94a2836ed42231653a7ddaefa0a5bc23418167a876bba7376c96b3a35/datamodel_code_generator-0.64.0.tar.gz", hash = "sha256:9c592900a00b20e416494273c22435f5a9aef6ea8c7b9190747522a60497a1cb", size = 1316440, upload-time = "2026-06-14T17:24:50.528Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/ef/0ed17459fe6076219fcd45f69a0bb4bd1cb041b39095ca2946808a9b5f04/datamodel_code_generator-0.35.0-py3-none-any.whl", hash = "sha256:c356d1e4a555f86667a4262db03d4598a30caeda8f51786555fd269c8abb806b", size = 121436, upload-time = "2025-10-09T19:26:48.437Z" }, + { url = "https://files.pythonhosted.org/packages/23/94/71338e2f0146ac10747a5537b3a1e45256e66b7c229869eb0ee787111b41/datamodel_code_generator-0.64.0-py3-none-any.whl", hash = "sha256:b7cd8bd41a312aa997aec6150670bad781847c5b674f17e4d70e78208a0fb990", size = 374698, upload-time = "2026-06-14T17:24:48.809Z" }, ] [[package]] @@ -378,7 +381,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ From 750c6ee7216d527cedcbd5b33b4e6178138e9f04 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sat, 1 Aug 2026 23:56:55 +0800 Subject: [PATCH 46/52] release: 0.12.0 (#124) --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 220b908..edde99b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.11.1" +version = "0.12.0" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 5c62ff3..fca93fb 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "agent-client-protocol" -version = "0.11.1" +version = "0.12.0" source = { editable = "." } dependencies = [ { name = "pydantic" }, From 40faed9eee947ea4765e4164cef7cc527906372a Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Sun, 2 Aug 2026 02:27:11 +0800 Subject: [PATCH 47/52] fix(codegen): support datamodel-code-generator 0.71 (#127) * fix(codegen): support datamodel-code-generator 0.64 * chore(deps-dev): require datamodel-code-generator 0.71.0 * refactor(schema): stop duplicating field descriptions * refactor(schema): generate field descriptions as docstrings * test(schema): verify generated descriptions are readable --- pyproject.toml | 2 +- scripts/gen_schema.py | 210 +- scripts/gen_signature.py | 6 +- src/acp/schema.py | 9166 +++++++++++++++++--------------------- tests/test_gen_all.py | 11 + uv.lock | 8 +- 6 files changed, 4242 insertions(+), 5161 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index edde99b..d9c8e1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ Documentation = "https://agentclientprotocol.github.io/python-sdk/" [dependency-groups] dev = [ - "datamodel-code-generator>=0.25", + "datamodel-code-generator>=0.71.0", "pytest>=7.2.0", "pytest-asyncio>=0.21.0", "tox-uv>=1.11.3", diff --git a/scripts/gen_schema.py b/scripts/gen_schema.py index 936f6a4..638bbe7 100644 --- a/scripts/gen_schema.py +++ b/scripts/gen_schema.py @@ -20,13 +20,6 @@ VERSION_FILE = SCHEMA_DIR / "VERSION" SCHEMA_OUT = ROOT / "src" / "acp" / "schema.py" -# Pattern caches used when post-processing generated schema. -FIELD_DECLARATION_PATTERN = re.compile(r"[A-Za-z_][A-Za-z0-9_]*\s*:") -DESCRIPTION_PATTERN = re.compile( - r"description\s*=\s*(?P[rRbBuU]*)?(?P'''|\"\"\"|'|\")(?P.*?)(?P=quote)", - re.DOTALL, -) - STDIO_TYPE_LITERAL = 'Literal["2#-datamodel-code-generator-#-object-#-special-#"]' MODELS_TO_REMOVE = [ "AgentClientProtocol", @@ -137,6 +130,31 @@ "ToolKind": ("read", "edit", "delete", "move", "search", "execute", "think", "fetch", "switch_mode", "other"), } +# datamodel-code-generator 0.64 promotes referenced string enums to Enum classes. +# Keep the existing Python API, where these schema types are plain strings; the +# selected public fields below are narrowed back to the named Literal aliases. +STRING_ENUM_TYPES = ( + *ENUM_LITERAL_MAP, + "ElicitationSchemaType", + "NesDiagnosticSeverity", + "NesRejectReason", + "NesTriggerKind", + "PositionEncodingKind", + "Role", + "StringFormat", + "TextDocumentSyncKind", +) + +# Preserve RootModel classes that existed in the generated public surface before +# 0.64; other unreferenced RootModels are intermediates left after collapsing. +PUBLIC_ROOT_MODELS = { + "AgentResponse", + "ClientResponse", + "ElicitationContentValue", + "ElicitationFormMode", + "ElicitationUrlMode", +} + FIELD_TYPE_OVERRIDES: tuple[tuple[str, str, str, bool], ...] = ( ("PermissionOption", "kind", "PermissionOptionKind", False), ("PlanEntry", "priority", "PlanEntryPriority", False), @@ -259,7 +277,16 @@ def generate_schema() -> None: "--collapse-root-models", "--output-model-type", "pydantic_v2.BaseModel", + "--no-use-specialized-enum", + "--no-use-standard-collections", + "--no-use-union-operator", + "--type-overrides", + json.dumps(dict.fromkeys(STRING_ENUM_TYPES, "builtins.str")), + "--formatters", + "black", + "isort", "--use-annotated", + "--use-field-description", "--snake-case-field", ] @@ -474,6 +501,9 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: header_block = _build_header_block() content = _strip_existing_header(raw_content) + # Type overrides for builtins are rendered as imports in 0.64, but the + # annotations should continue to use Python's builtin `str` directly. + content = content.replace("from builtins import str\n", "") content = _remove_unused_models(content) content, leftover_classes = _rename_numbered_models(content) @@ -481,8 +511,8 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: _ProcessingStep("apply field overrides", _apply_field_overrides), _ProcessingStep("apply default overrides", _apply_default_overrides), _ProcessingStep("restore required nullable fields", _restore_required_nullable_fields), - _ProcessingStep("attach description comments", _add_description_comments), _ProcessingStep("ensure custom BaseModel", _ensure_custom_base_model), + _ProcessingStep("enable RootModel attribute docstrings", _enable_root_model_attribute_docstrings), _ProcessingStep("inject field validators", _inject_field_validators), _ProcessingStep("inject deserialize defaults", _inject_deserialize_defaults), _ProcessingStep("inject schema aliases", _inject_schema_aliases), @@ -494,6 +524,7 @@ def postprocess_generated_schema(output_path: Path) -> list[str]: missing_targets = _find_missing_targets(content) content = _inject_enum_aliases(content) + content = _remove_unreferenced_root_models(content) final_content = header_block + content.rstrip() + "\n" if not final_content.endswith("\n"): final_content += "\n" @@ -646,7 +677,7 @@ def _ensure_custom_base_model(content: str) -> str: lines[idx] = "from pydantic import " + ", ".join(new_imports) to_insert = textwrap.dedent("""\ class BaseModel(_BaseModel): - model_config = ConfigDict(populate_by_name=True) + model_config = ConfigDict(populate_by_name=True, use_attribute_docstrings=True) def __getattr__(self, item: str) -> Any: if item.lower() != item: @@ -662,6 +693,24 @@ def __getattr__(self, item: str) -> Any: return "\n".join(lines) + "\n" +def _enable_root_model_attribute_docstrings(content: str) -> str: + lines = content.splitlines(keepends=True) + tree = ast.parse(content) + insertion_points = [ + node.body[0].lineno - 1 + for node in tree.body + if isinstance(node, ast.ClassDef) + and node.body + and any( + isinstance(base, ast.Subscript) and isinstance(base.value, ast.Name) and base.value.id == "RootModel" + for base in node.bases + ) + ] + for line_index in reversed(insertion_points): + lines.insert(line_index, " model_config = ConfigDict(use_attribute_docstrings=True)\n\n") + return "".join(lines) + + def _ensure_pydantic_import(content: str, name: str) -> str: """Add *name* to the ``from pydantic import ...`` line if not already present.""" lines = content.splitlines() @@ -916,8 +965,14 @@ def _restore_required_nullable_fields(content: str, schema: dict[str, Any] | Non def restore_block(match: re.Match[str], _field_names: list[str] = field_names) -> str: header, block = match.group(1), match.group(2) for field_name in _field_names: - field_pattern = re.compile(rf"(\n\s+{re.escape(field_name)}:\s+Annotated\[[\s\S]*?\n\s+\]\s*)=\s*None") - block = field_pattern.sub(r"\1", block, count=1) + field_patterns = ( + re.compile(rf"(\n\s+{re.escape(field_name)}:[^\n]*?)\s*=\s*None(?=\n)"), + re.compile(rf"(\n\s+{re.escape(field_name)}:[^\n]*\[\s*\n[\s\S]*?\n\s+\]\s*)=\s*None"), + ) + for field_pattern in field_patterns: + block, count = field_pattern.subn(r"\1", block, count=1) + if count: + break return header + block content = class_pattern.sub(restore_block, content, count=1) @@ -926,18 +981,14 @@ def restore_block(match: re.Match[str], _field_names: list[str] = field_names) - def _apply_field_overrides(content: str) -> str: for class_name, field_name, new_type, optional in FIELD_TYPE_OVERRIDES: - if optional: - pattern = re.compile( - rf"(class {class_name}\(BaseModel\):.*?\n\s+{field_name}:\s+Annotated\[\s*)Optional\[str],", - re.DOTALL, - ) - content, count = pattern.subn(rf"\1Optional[{new_type}],", content) - else: - pattern = re.compile( - rf"(class {class_name}\(BaseModel\):.*?\n\s+{field_name}:\s+Annotated\[\s*)str,", - re.DOTALL, - ) - content, count = pattern.subn(rf"\1{new_type},", content) + old_type = "Optional[str]" if optional else "str" + replacement_type = f"Optional[{new_type}]" if optional else new_type + pattern = re.compile( + rf"(class {re.escape(class_name)}\(BaseModel\):.*?\n\s+{re.escape(field_name)}:\s+" + rf"(?:Annotated\[\s*)?){re.escape(old_type)}(?=\s*(?:,|=|\n))", + re.DOTALL, + ) + content, count = pattern.subn(rf"\g<1>{replacement_type}", content, count=1) if count == 0: print( f"Warning: failed to apply type override for {class_name}.{field_name} -> {new_type}", @@ -963,7 +1014,8 @@ def replace_block( field_patterns: tuple[tuple[re.Pattern[str], Callable[[re.Match[str]], str]], ...] = ( ( re.compile( - rf"(\n\s+{_field_name}:.*?\]\s*=\s*)([\s\S]*?)(?=\n\s{{4}}[A-Za-z_]|$)", + rf"(\n\s+{_field_name}:.*?\]\s*=\s*)([\s\S]*?)" + rf"(?=\n\s{{4}}(?:[A-Za-z_][A-Za-z0-9_]*\s*:|[rRuUbBfF]*(?:'''|\"\"\"))|$)", re.DOTALL, ), lambda m, _rep=_replacement: m.group(1) + _rep, @@ -995,77 +1047,6 @@ def replace_block( return content -def _add_description_comments(content: str) -> str: - lines = content.splitlines() - new_lines: list[str] = [] - index = 0 - - while index < len(lines): - line = lines[index] - stripped = line.lstrip() - indent = len(line) - len(stripped) - - if indent == 4 and FIELD_DECLARATION_PATTERN.match(stripped or ""): - block_lines, next_index = _collect_field_block(lines, index, indent) - block_text = "\n".join(block_lines) - description = _extract_description(block_text) - - if description: - indent_str = " " * indent - comment_lines = [ - f"{indent_str}# {comment_line}" if comment_line else f"{indent_str}#" - for comment_line in description.splitlines() - ] - if comment_lines: - new_lines.extend(comment_lines) - - new_lines.extend(block_lines) - index = next_index - continue - - new_lines.append(line) - index += 1 - - return "\n".join(new_lines) - - -def _collect_field_block(lines: list[str], start: int, indent: int) -> tuple[list[str], int]: - block: list[str] = [] - index = start - - while index < len(lines): - current_line = lines[index] - current_indent = len(current_line) - len(current_line.lstrip()) - if index != start and current_line.strip() and current_indent <= indent: - break - - block.append(current_line) - index += 1 - - return block, index - - -def _extract_description(block_text: str) -> str | None: - match = DESCRIPTION_PATTERN.search(block_text) - if not match: - return None - - prefix = match.group("prefix") or "" - quote = match.group("quote") - value = match.group("value") - literal = f"{prefix}{quote}{value}{quote}" - - # datamodel-code-generator emits standard string literals, but fall back to raw text on parse errors. - try: - parsed = ast.literal_eval(literal) - except (SyntaxError, ValueError): - return value.replace("\\n", "\n") - - if isinstance(parsed, str): - return parsed - return str(parsed) - - def _inject_enum_aliases(content: str) -> str: enum_lines = [ f"{name} = Literal[{', '.join(repr(value) for value in values)}]" for name, values in ENUM_LITERAL_MAP.items() @@ -1080,6 +1061,45 @@ def _inject_enum_aliases(content: str) -> str: return content[:insertion_point] + block + content[insertion_point:] +def _remove_unreferenced_root_models(content: str) -> str: + tree = ast.parse(content) + root_models = { + node.name: node + for node in tree.body + if isinstance(node, ast.ClassDef) + and any( + isinstance(base, ast.Subscript) and isinstance(base.value, ast.Name) and base.value.id == "RootModel" + for base in node.bases + ) + } + + referenced_roots = set(PUBLIC_ROOT_MODELS) + root_dependencies: dict[str, set[str]] = {} + for statement in tree.body: + loaded_names = { + node.id + for node in ast.walk(statement) + if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Load) and node.id in root_models + } + if isinstance(statement, ast.ClassDef) and statement.name in root_models: + root_dependencies[statement.name] = loaded_names + else: + referenced_roots.update(loaded_names) + + pending = list(referenced_roots) + while pending: + root_name = pending.pop() + for dependency in root_dependencies.get(root_name, set()) - referenced_roots: + referenced_roots.add(dependency) + pending.append(dependency) + + unused_models = [model for name, model in root_models.items() if name not in referenced_roots] + lines = content.splitlines(keepends=True) + for model in sorted(unused_models, key=lambda item: item.lineno, reverse=True): + del lines[model.lineno - 1 : model.end_lineno] + return re.sub(r"\n{4,}", "\n\n\n", "".join(lines)) + + def _remove_unused_models(content: str) -> str: for model_name in MODELS_TO_REMOVE: pattern = re.compile( diff --git a/scripts/gen_signature.py b/scripts/gen_signature.py index 412071b..f311b3d 100644 --- a/scripts/gen_signature.py +++ b/scripts/gen_signature.py @@ -127,7 +127,10 @@ def _to_param_def(self, name: str, field: FieldInfo) -> tuple[ast.arg, ast.expr return arg, default def _format_annotation(self, annotation: t.Any) -> ast.expr: - if t.get_origin(annotation) is t.Literal and annotation in self._literals.values(): + origin = t.get_origin(annotation) + if origin is t.Annotated: + return self._format_annotation(t.get_args(annotation)[0]) + if origin is t.Literal and annotation in self._literals.values(): name = next(name for name, value in self._literals.items() if value is annotation) self._add_schema_import(name) return ast.Name(id=name) @@ -139,7 +142,6 @@ def _format_annotation(self, annotation: t.Any) -> ast.expr: self._add_schema_import(annotation.__name__) return ast.Name(id=annotation.__name__) elif args := t.get_args(annotation): - origin = t.get_origin(annotation) return ast.Subscript( value=self._format_annotation(origin), slice=ast.Tuple(elts=[self._format_annotation(arg) for arg in args], ctx=ast.Load()) diff --git a/src/acp/schema.py b/src/acp/schema.py index e2dd1f1..5e1be37 100644 --- a/src/acp/schema.py +++ b/src/acp/schema.py @@ -18,7 +18,7 @@ class BaseModel(_BaseModel): - model_config = ConfigDict(populate_by_name=True) + model_config = ConfigDict(populate_by_name=True, use_attribute_docstrings=True) def __getattr__(self, item: str) -> Any: if item.lower() != item: @@ -37,29 +37,30 @@ class Jsonrpc(Enum): class ReadTextFileRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # Absolute path to the file to read. - path: Annotated[str, Field(description="Absolute path to the file to read.")] - # Line number to start reading from (1-based). - line: Annotated[ - Optional[int], - Field(description="Line number to start reading from (1-based).", ge=0), - ] = None - # Maximum number of lines to read. - limit: Annotated[Optional[int], Field(description="Maximum number of lines to read.", ge=0)] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + path: str + """ + Absolute path to the file to read. + """ + line: Annotated[Optional[int], Field(ge=0)] = None + """ + Line number to start reading from (1-based). + """ + limit: Annotated[Optional[int], Field(ge=0)] = None + """ + Maximum number of lines to read. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("limit", "line", mode="wrap") @classmethod @@ -68,30 +69,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class TextResourceContents(BaseModel): - # MIME type describing the encoded media payload. - mime_type: Annotated[ - Optional[str], - Field( - alias="mimeType", - description="MIME type describing the encoded media payload.", - ), - ] = None - # Text payload carried by this content block. - text: Annotated[str, Field(description="Text payload carried by this content block.")] - # URI associated with this resource or media payload. - uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None + """ + MIME type describing the encoded media payload. + """ + text: str + """ + Text payload carried by this content block. + """ + uri: str + """ + URI associated with this resource or media payload. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("mime_type", mode="wrap") @classmethod @@ -100,30 +97,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class BlobResourceContents(BaseModel): - # Base64-encoded bytes for a binary resource payload. - blob: Annotated[str, Field(description="Base64-encoded bytes for a binary resource payload.")] - # MIME type describing the encoded media payload. - mime_type: Annotated[ - Optional[str], - Field( - alias="mimeType", - description="MIME type describing the encoded media payload.", - ), - ] = None - # URI associated with this resource or media payload. - uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + blob: str + """ + Base64-encoded bytes for a binary resource payload. + """ + mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None + """ + MIME type describing the encoded media payload. + """ + uri: str + """ + URI associated with this resource or media payload. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("mime_type", mode="wrap") @classmethod @@ -132,27 +125,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class Diff(BaseModel): - # The absolute file path being modified. - path: Annotated[str, Field(description="The absolute file path being modified.")] - # The original content (None for new files). - old_text: Annotated[ - Optional[str], - Field(alias="oldText", description="The original content (None for new files)."), - ] = None - # The new content after modification. - new_text: Annotated[str, Field(alias="newText", description="The new content after modification.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + path: str + """ + The absolute file path being modified. + """ + old_text: Annotated[Optional[str], Field(alias="oldText")] = None + """ + The original content (None for new files). + """ + new_text: Annotated[str, Field(alias="newText")] + """ + The new content after modification. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("old_text", mode="wrap") @classmethod @@ -161,45 +153,37 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class Terminal(BaseModel): - # Identifier of the terminal instance to embed in the content stream. - terminal_id: Annotated[ - str, - Field( - alias="terminalId", - description="Identifier of the terminal instance to embed in the content stream.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + Identifier of the terminal instance to embed in the content stream. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ToolCallLocation(BaseModel): - # The absolute file path being accessed or modified. - path: Annotated[str, Field(description="The absolute file path being accessed or modified.")] - # Optional line number within the file. - line: Annotated[Optional[int], Field(description="Optional line number within the file.", ge=0)] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + path: str + """ + The absolute file path being accessed or modified. + """ + line: Annotated[Optional[int], Field(ge=0)] = None + """ + Optional line number within the file. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("line", mode="wrap") @classmethod @@ -208,138 +192,124 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class EnvVariable(BaseModel): - # The name of the environment variable. - name: Annotated[str, Field(description="The name of the environment variable.")] - # The value to set for the environment variable. - value: Annotated[str, Field(description="The value to set for the environment variable.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + The name of the environment variable. + """ + value: str + """ + The value to set for the environment variable. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class TerminalOutputRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to get output from. - terminal_id: Annotated[ - str, - Field(alias="terminalId", description="The ID of the terminal to get output from."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + The ID of the terminal to get output from. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ReleaseTerminalRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to release. - terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to release.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + The ID of the terminal to release. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class WaitForTerminalExitRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to wait for. - terminal_id: Annotated[ - str, - Field(alias="terminalId", description="The ID of the terminal to wait for."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + The ID of the terminal to wait for. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class KillTerminalRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The ID of the terminal to kill. - terminal_id: Annotated[str, Field(alias="terminalId", description="The ID of the terminal to kill.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + The ID of the terminal to kill. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CreateOtherElicitationRequest(BaseModel): model_config = ConfigDict( extra="allow", ) - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # Custom or future elicitation mode. - # - # Values beginning with `_` are reserved for implementation-specific - # extensions. Unknown values that do not begin with `_` are reserved for - # future ACP variants. - mode: Annotated[ - str, - Field( - description="Custom or future elicitation mode.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." - ), - ] + message: str + """ + A human-readable message describing what input is needed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ + mode: str + """ + Custom or future elicitation mode. + + Values beginning with `_` are reserved for implementation-specific + extensions. Unknown values that do not begin with `_` are reserved for + future ACP variants. + """ @field_validator("mode", mode="before") @classmethod @@ -353,16 +323,14 @@ def _reject_known_mode(cls, value: Any) -> Any: class ElicitationSessionScope(BaseModel): - # The session this elicitation is tied to. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session this elicitation is tied to."), - ] - # Optional tool call within the session. - tool_call_id: Annotated[ - Optional[str], - Field(alias="toolCallId", description="Optional tool call within the session."), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session this elicitation is tied to. + """ + tool_call_id: Annotated[Optional[str], Field(alias="toolCallId")] = None + """ + Optional tool call within the session. + """ @field_validator("tool_call_id", mode="wrap") @classmethod @@ -371,28 +339,24 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ElicitationRequestScope(BaseModel): - # The request this elicitation is tied to. - request_id: Annotated[ - Optional[Union[int, str]], - Field(alias="requestId", description="The request this elicitation is tied to."), - ] + request_id: Annotated[Optional[Union[int, str]], Field(alias="requestId")] + """ + The request this elicitation is tied to. + """ class ElicitationOtherPropertySchema(BaseModel): model_config = ConfigDict( extra="allow", ) - # Custom or future elicitation property schema type. - # - # Values beginning with `_` are reserved for implementation-specific - # extensions. Unknown values that do not begin with `_` are reserved for - # future ACP variants. - type: Annotated[ - str, - Field( - description="Custom or future elicitation property schema type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." - ), - ] + type: str + """ + Custom or future elicitation property schema type. + + Values beginning with `_` are reserved for implementation-specific + extensions. Unknown values that do not begin with `_` are reserved for + future ACP variants. + """ @field_validator("type", mode="before") @classmethod @@ -406,24 +370,26 @@ def _reject_known_type(cls, value: Any) -> Any: class EnumOption(BaseModel): - # The constant value for this option. - const: Annotated[str, Field(description="The constant value for this option.")] - # Human-readable title for this option. - title: Annotated[str, Field(description="Human-readable title for this option.")] - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + const: str + """ + The constant value for this option. + """ + title: str + """ + Human-readable title for this option. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", mode="wrap") @classmethod @@ -432,51 +398,50 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class StringPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Minimum string length. - min_length: Annotated[ - Optional[int], - Field(alias="minLength", description="Minimum string length.", ge=0), - ] = None - # Maximum string length. - max_length: Annotated[ - Optional[int], - Field(alias="maxLength", description="Maximum string length.", ge=0), - ] = None - # Pattern the string must match. - pattern: Annotated[Optional[str], Field(description="Pattern the string must match.")] = None - # String format. - format: Annotated[Optional[str], Field(description="String format.")] = None - # Default value. - default: Annotated[Optional[str], Field(description="Default value.")] = None - # Enum values for untitled single-select enums. - enum: Annotated[ - Optional[List[str]], - Field(description="Enum values for untitled single-select enums."), - ] = None - # Titled enum options for titled single-select enums. - one_of: Annotated[ - Optional[List[EnumOption]], - Field( - alias="oneOf", - description="Titled enum options for titled single-select enums.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Optional title for the property. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + min_length: Annotated[Optional[int], Field(alias="minLength", ge=0)] = None + """ + Minimum string length. + """ + max_length: Annotated[Optional[int], Field(alias="maxLength", ge=0)] = None + """ + Maximum string length. + """ + pattern: Optional[str] = None + """ + Pattern the string must match. + """ + format: Optional[str] = None + """ + String format. + """ + default: Optional[str] = None + """ + Default value. + """ + enum: Optional[List[str]] = None + """ + Enum values for untitled single-select enums. + """ + one_of: Annotated[Optional[List[EnumOption]], Field(alias="oneOf")] = None + """ + Titled enum options for titled single-select enums. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("default", "description", "title", mode="wrap") @classmethod @@ -485,28 +450,34 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NumberPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Minimum value (inclusive). - minimum: Annotated[Optional[float], Field(description="Minimum value (inclusive).")] = None - # Maximum value (inclusive). - maximum: Annotated[Optional[float], Field(description="Maximum value (inclusive).")] = None - # Default value. - default: Annotated[Optional[float], Field(description="Default value.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Optional title for the property. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + minimum: Optional[float] = None + """ + Minimum value (inclusive). + """ + maximum: Optional[float] = None + """ + Maximum value (inclusive). + """ + default: Optional[float] = None + """ + Default value. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("default", "description", "title", mode="wrap") @classmethod @@ -515,28 +486,34 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class IntegerPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Minimum value (inclusive). - minimum: Annotated[Optional[int], Field(description="Minimum value (inclusive).")] = None - # Maximum value (inclusive). - maximum: Annotated[Optional[int], Field(description="Maximum value (inclusive).")] = None - # Default value. - default: Annotated[Optional[int], Field(description="Default value.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Optional title for the property. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + minimum: Optional[int] = None + """ + Minimum value (inclusive). + """ + maximum: Optional[int] = None + """ + Maximum value (inclusive). + """ + default: Optional[int] = None + """ + Default value. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("default", "description", "title", mode="wrap") @classmethod @@ -545,24 +522,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class BooleanPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Default value. - default: Annotated[Optional[bool], Field(description="Default value.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Optional title for the property. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + default: Optional[bool] = None + """ + Default value. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("default", "description", "title", mode="wrap") @classmethod @@ -574,17 +553,14 @@ class OtherMultiSelectItems(BaseModel): model_config = ConfigDict( extra="allow", ) - # Custom or future multi-select item type. - # - # Values beginning with `_` are reserved for implementation-specific - # extensions. Unknown values that do not begin with `_` are reserved for - # future ACP variants. - type: Annotated[ - str, - Field( - description="Custom or future multi-select item type.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." - ), - ] + type: str + """ + Custom or future multi-select item type. + + Values beginning with `_` are reserved for implementation-specific + extensions. Unknown values that do not begin with `_` are reserved for + future ACP variants. + """ @field_validator("type", mode="before") @classmethod @@ -598,127 +574,109 @@ def _reject_known_type(cls, value: Any) -> Any: class _StringMultiSelectItems(BaseModel): - # Allowed enum values. - enum: Annotated[List[str], Field(description="Allowed enum values.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + enum: List[str] + """ + Allowed enum values. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class TitledMultiSelectItems(BaseModel): - # Titled enum options. - any_of: Annotated[List[EnumOption], Field(alias="anyOf", description="Titled enum options.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + any_of: Annotated[List[EnumOption], Field(alias="anyOf")] + """ + Titled enum options. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ElicitationUrlSessionMode(ElicitationSessionScope): - # The unique identifier for this elicitation. - elicitation_id: Annotated[ - str, - Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", - ), - ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + elicitation_id: Annotated[str, Field(alias="elicitationId")] + """ + The unique identifier for this elicitation. + """ + url: AnyUrl + """ + The URL to direct the user to. + """ class ElicitationUrlRequestMode(ElicitationRequestScope): - # The unique identifier for this elicitation. - elicitation_id: Annotated[ - str, - Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", - ), - ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + elicitation_id: Annotated[str, Field(alias="elicitationId")] + """ + The unique identifier for this elicitation. + """ + url: AnyUrl + """ + The URL to direct the user to. + """ class ElicitationUrlMode(RootModel[Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode]]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # URL-based elicitation mode where the client directs the user to a URL. - root: Annotated[ - Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nURL-based elicitation mode where the client directs the user to a URL." - ), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: Union[ElicitationUrlSessionMode, ElicitationUrlRequestMode] + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + URL-based elicitation mode where the client directs the user to a URL. + """ class DisconnectMcpRequest(BaseModel): - # The MCP-over-ACP connection to close. - connection_id: Annotated[ - str, - Field(alias="connectionId", description="The MCP-over-ACP connection to close."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + connection_id: Annotated[str, Field(alias="connectionId")] + """ + The MCP-over-ACP connection to close. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class PromptCapabilities(BaseModel): - # Agent supports [`ContentBlock::Image`]. - image: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Image`].")] = False - # Agent supports [`ContentBlock::Audio`]. - audio: Annotated[Optional[bool], Field(description="Agent supports [`ContentBlock::Audio`].")] = False - # Agent supports embedded context in `session/prompt` requests. - # - # When enabled, the Client is allowed to include [`ContentBlock::Resource`] - # in prompt requests for pieces of context that are referenced in the message. - embedded_context: Annotated[ - Optional[bool], - Field( - alias="embeddedContext", - description="Agent supports embedded context in `session/prompt` requests.\n\nWhen enabled, the Client is allowed to include [`ContentBlock::Resource`]\nin prompt requests for pieces of context that are referenced in the message.", - ), - ] = False - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + image: Optional[bool] = False + """ + Agent supports [`ContentBlock::Image`]. + """ + audio: Optional[bool] = False + """ + Agent supports [`ContentBlock::Audio`]. + """ + embedded_context: Annotated[Optional[bool], Field(alias="embeddedContext")] = False + """ + Agent supports embedded context in `session/prompt` requests. + + When enabled, the Client is allowed to include [`ContentBlock::Resource`] + in prompt requests for pieces of context that are referenced in the message. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("audio", "embedded_context", "image", mode="wrap") @classmethod @@ -727,33 +685,30 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class McpCapabilities(BaseModel): - # Agent supports [`McpServer::Http`]. - http: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Http`].")] = False - # Agent supports [`McpServer::Sse`]. - sse: Annotated[Optional[bool], Field(description="Agent supports [`McpServer::Sse`].")] = False - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Agent supports [`McpServer::Acp`]. - acp: Annotated[ - Optional[bool], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAgent supports [`McpServer::Acp`]." - ), - ] = False - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + http: Optional[bool] = False + """ + Agent supports [`McpServer::Http`]. + """ + sse: Optional[bool] = False + """ + Agent supports [`McpServer::Sse`]. + """ + acp: Optional[bool] = False + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Agent supports [`McpServer::Acp`]. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("acp", "http", "sse", mode="wrap") @classmethod @@ -762,207 +717,150 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class SessionListCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionDeleteCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionAdditionalDirectoriesCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionForkCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionResumeCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionCloseCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class LogoutCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ProvidersCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesDocumentDidOpenCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesDocumentDidCloseCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesDocumentDidSaveCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesDocumentDidFocusCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesRecentFilesCapabilities(BaseModel): - # Maximum number of recent files the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of recent files the agent can use.", - ge=0, - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + max_count: Annotated[Optional[int], Field(alias="maxCount", ge=0)] = None + """ + Maximum number of recent files the agent can use. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("max_count", mode="wrap") @classmethod @@ -971,42 +869,29 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesRelatedSnippetsCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesEditHistoryCapabilities(BaseModel): - # Maximum number of edit history entries the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of edit history entries the agent can use.", - ge=0, - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + max_count: Annotated[Optional[int], Field(alias="maxCount", ge=0)] = None + """ + Maximum number of edit history entries the agent can use. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("max_count", mode="wrap") @classmethod @@ -1015,27 +900,18 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesUserActionsCapabilities(BaseModel): - # Maximum number of user actions the agent can use. - max_count: Annotated[ - Optional[int], - Field( - alias="maxCount", - description="Maximum number of user actions the agent can use.", - ge=0, - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + max_count: Annotated[Optional[int], Field(alias="maxCount", ge=0)] = None + """ + Maximum number of user actions the agent can use. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("max_count", mode="wrap") @classmethod @@ -1044,75 +920,57 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesOpenFilesCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesDiagnosticsCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AuthEnvVar(BaseModel): - # The environment variable name (e.g. `"OPENAI_API_KEY"`). - name: Annotated[ - str, - Field(description='The environment variable name (e.g. `"OPENAI_API_KEY"`).'), - ] - # Human-readable label for this variable, displayed in client UI. - label: Annotated[ - Optional[str], - Field(description="Human-readable label for this variable, displayed in client UI."), - ] = None - # Whether this value is a secret (e.g. API key, token). - # Clients should use a password-style input for secret vars. - # - # Defaults to `true`. - secret: Annotated[ - Optional[bool], - Field( - description="Whether this value is a secret (e.g. API key, token).\nClients should use a password-style input for secret vars.\n\nDefaults to `true`." - ), - ] = True - # Whether this variable is optional. - # - # Defaults to `false`. - optional: Annotated[ - Optional[bool], - Field(description="Whether this variable is optional.\n\nDefaults to `false`."), - ] = False - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + The environment variable name (e.g. `"OPENAI_API_KEY"`). + """ + label: Optional[str] = None + """ + Human-readable label for this variable, displayed in client UI. + """ + secret: Optional[bool] = True + """ + Whether this value is a secret (e.g. API key, token). + Clients should use a password-style input for secret vars. + + Defaults to `true`. + """ + optional: Optional[bool] = False + """ + Whether this variable is optional. + + Defaults to `false`. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("optional", mode="wrap") @classmethod @@ -1131,37 +989,34 @@ def _salvage_on_error_2(cls, value: Any, handler: Any) -> Any: class AuthMethodEnvVar(BaseModel): - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # The environment variables the client should set. - vars: Annotated[ - List[AuthEnvVar], - Field(description="The environment variables the client should set."), - ] - # Optional link to a page where the user can obtain their credentials. - link: Annotated[ - Optional[str], - Field(description="Optional link to a page where the user can obtain their credentials."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for this authentication method. + """ + name: str + """ + Human-readable name of the authentication method. + """ + description: Optional[str] = None + """ + Optional description providing more details about this authentication method. + """ + vars: List[AuthEnvVar] + """ + The environment variables the client should set. + """ + link: Optional[str] = None + """ + Optional link to a page where the user can obtain their credentials. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", "link", mode="wrap") @classmethod @@ -1175,37 +1030,34 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class AuthMethodTerminal(BaseModel): - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # Additional arguments to pass when running the agent binary for terminal auth. - args: Annotated[ - Optional[List[str]], - Field(description="Additional arguments to pass when running the agent binary for terminal auth."), - ] = None - # Additional environment variables to set when running the agent binary for terminal auth. - env: Annotated[ - Optional[Dict[str, str]], - Field(description="Additional environment variables to set when running the agent binary for terminal auth."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for this authentication method. + """ + name: str + """ + Human-readable name of the authentication method. + """ + description: Optional[str] = None + """ + Optional description providing more details about this authentication method. + """ + args: Optional[List[str]] = None + """ + Additional arguments to pass when running the agent binary for terminal auth. + """ + env: Optional[Dict[str, str]] = None + """ + Additional environment variables to set when running the agent binary for terminal auth. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", "env", mode="wrap") @classmethod @@ -1219,27 +1071,26 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class AuthMethodAgent(BaseModel): - # Unique identifier for this authentication method. - id: Annotated[str, Field(description="Unique identifier for this authentication method.")] - # Human-readable name of the authentication method. - name: Annotated[str, Field(description="Human-readable name of the authentication method.")] - # Optional description providing more details about this authentication method. - description: Annotated[ - Optional[str], - Field(description="Optional description providing more details about this authentication method."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for this authentication method. + """ + name: str + """ + Human-readable name of the authentication method. + """ + description: Optional[str] = None + """ + Optional description providing more details about this authentication method. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", mode="wrap") @classmethod @@ -1248,44 +1099,31 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class Implementation(BaseModel): - # Intended for programmatic or logical use, but can be used as a display - # name fallback if title isn’t present. - name: Annotated[ - str, - Field( - description="Intended for programmatic or logical use, but can be used as a display\nname fallback if title isn’t present." - ), - ] - # Intended for UI and end-user contexts — optimized to be human-readable - # and easily understood. - # - # If not provided, the name should be used for display. - title: Annotated[ - Optional[str], - Field( - description="Intended for UI and end-user contexts — optimized to be human-readable\nand easily understood.\n\nIf not provided, the name should be used for display." - ), - ] = None - # Version of the implementation. Can be displayed to the user or used - # for debugging or metrics purposes. (e.g. "1.0.0"). - version: Annotated[ - str, - Field( - description='Version of the implementation. Can be displayed to the user or used\nfor debugging or metrics purposes. (e.g. "1.0.0").' - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Intended for programmatic or logical use, but can be used as a display + name fallback if title isn’t present. + """ + title: Optional[str] = None + """ + Intended for UI and end-user contexts — optimized to be human-readable + and easily understood. + + If not provided, the name should be used for display. + """ + version: str + """ + Version of the implementation. Can be displayed to the user or used + for debugging or metrics purposes. (e.g. "1.0.0"). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("title", mode="wrap") @classmethod @@ -1294,115 +1132,99 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class AuthenticateResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ProviderCurrentConfig(BaseModel): - # Protocol currently used by this provider. api_type: Annotated[ - Union[str, Dict[str, Any]], - Field(alias="apiType", description="Protocol currently used by this provider."), - ] - # Base URL currently used by this provider. - base_url: Annotated[ - str, - Field(alias="baseUrl", description="Base URL currently used by this provider."), + Union[ + Literal["anthropic"], + Literal["openai"], + Literal["azure"], + Literal["vertex"], + Literal["bedrock"], + Dict[str, Any], + ], + Field(alias="apiType"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + Protocol currently used by this provider. + """ + base_url: Annotated[str, Field(alias="baseUrl")] + """ + Base URL currently used by this provider. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SetProviderResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DisableProviderResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class LogoutResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionMode(BaseModel): - # Stable identifier used to refer to this protocol object in later messages. - id: Annotated[ - str, - Field(description="Stable identifier used to refer to this protocol object in later messages."), - ] - # Human-readable name shown for this protocol object. - name: Annotated[str, Field(description="Human-readable name shown for this protocol object.")] - # Optional human-readable details shown with this protocol object. - description: Annotated[ - Optional[str], - Field(description="Optional human-readable details shown with this protocol object."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Stable identifier used to refer to this protocol object in later messages. + """ + name: str + """ + Human-readable name shown for this protocol object. + """ + description: Optional[str] = None + """ + Optional human-readable details shown with this protocol object. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", mode="wrap") @classmethod @@ -1411,24 +1233,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class SessionConfigSelectOption(BaseModel): - # Unique identifier for this option value. - value: Annotated[str, Field(description="Unique identifier for this option value.")] - # Human-readable label for this option value. - name: Annotated[str, Field(description="Human-readable label for this option value.")] - # Optional description for this option value. - description: Annotated[Optional[str], Field(description="Optional description for this option value.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + value: str + """ + Unique identifier for this option value. + """ + name: str + """ + Human-readable label for this option value. + """ + description: Optional[str] = None + """ + Optional description for this option value. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", mode="wrap") @classmethod @@ -1437,52 +1261,45 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class SessionConfigBoolean(BaseModel): - # The current value of the boolean option. - current_value: Annotated[ - bool, - Field(alias="currentValue", description="The current value of the boolean option."), - ] + current_value: Annotated[bool, Field(alias="currentValue")] + """ + The current value of the boolean option. + """ class SessionInfo(BaseModel): - # Unique identifier for the session - session_id: Annotated[str, Field(alias="sessionId", description="Unique identifier for the session")] - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Additional workspace roots reported for this session. Each path must be absolute. - # - # When present, this is the complete ordered additional-root list reported - # by the Agent. Omitted and empty values are equivalent: the response - # reports no additional roots. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots reported for this session. Each path must be absolute.\n\nWhen present, this is the complete ordered additional-root list reported\nby the Agent. Omitted and empty values are equivalent: the response\nreports no additional roots.", - ), - ] = None - # Human-readable title for the session - title: Annotated[Optional[str], Field(description="Human-readable title for the session")] = None - # ISO 8601 timestamp of last activity - updated_at: Annotated[ - Optional[str], - Field(alias="updatedAt", description="ISO 8601 timestamp of last activity"), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + Unique identifier for the session + """ + cwd: str + """ + The working directory for this session. Must be an absolute path. + """ + additional_directories: Annotated[Optional[List[str]], Field(alias="additionalDirectories")] = None + """ + Additional workspace roots reported for this session. Each path must be absolute. + + When present, this is the complete ordered additional-root list reported + by the Agent. Omitted and empty values are equivalent: the response + reports no additional roots. + """ + title: Optional[str] = None + """ + Human-readable title for the session + """ + updated_at: Annotated[Optional[str], Field(alias="updatedAt")] = None + """ + ISO 8601 timestamp of last activity + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("title", "updated_at", mode="wrap") @classmethod @@ -1496,105 +1313,71 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class DeleteSessionResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CloseSessionResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SetSessionModeResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class Usage(BaseModel): - # Sum of all token types across session. - total_tokens: Annotated[ - int, - Field( - alias="totalTokens", - description="Sum of all token types across session.", - ge=0, - ), - ] - # Total input tokens across all turns. - input_tokens: Annotated[ - int, - Field( - alias="inputTokens", - description="Total input tokens across all turns.", - ge=0, - ), - ] - # Total output tokens across all turns. - output_tokens: Annotated[ - int, - Field( - alias="outputTokens", - description="Total output tokens across all turns.", - ge=0, - ), - ] - # Total thought/reasoning tokens - thought_tokens: Annotated[ - Optional[int], - Field(alias="thoughtTokens", description="Total thought/reasoning tokens", ge=0), - ] = None - # Total cache read tokens. - cached_read_tokens: Annotated[ - Optional[int], - Field(alias="cachedReadTokens", description="Total cache read tokens.", ge=0), - ] = None - # Total cache write tokens. - cached_write_tokens: Annotated[ - Optional[int], - Field(alias="cachedWriteTokens", description="Total cache write tokens.", ge=0), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + total_tokens: Annotated[int, Field(alias="totalTokens", ge=0)] + """ + Sum of all token types across session. + """ + input_tokens: Annotated[int, Field(alias="inputTokens", ge=0)] + """ + Total input tokens across all turns. + """ + output_tokens: Annotated[int, Field(alias="outputTokens", ge=0)] + """ + Total output tokens across all turns. + """ + thought_tokens: Annotated[Optional[int], Field(alias="thoughtTokens", ge=0)] = None + """ + Total thought/reasoning tokens + """ + cached_read_tokens: Annotated[Optional[int], Field(alias="cachedReadTokens", ge=0)] = None + """ + Total cache read tokens. + """ + cached_write_tokens: Annotated[Optional[int], Field(alias="cachedWriteTokens", ge=0)] = None + """ + Total cache write tokens. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("cached_read_tokens", "cached_write_tokens", "thought_tokens", mode="wrap") @classmethod @@ -1603,258 +1386,231 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class StartNesResponse(BaseModel): - # The session ID for the newly started NES session. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The session ID for the newly started NES session.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for the newly started NES session. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class Position(BaseModel): - # Zero-based line number. - line: Annotated[int, Field(description="Zero-based line number.", ge=0)] - # Zero-based character offset (encoding-dependent). - character: Annotated[ - int, - Field(description="Zero-based character offset (encoding-dependent).", ge=0), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + line: Annotated[int, Field(ge=0)] + """ + Zero-based line number. + """ + character: Annotated[int, Field(ge=0)] + """ + Zero-based character offset (encoding-dependent). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesJumpSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The file to navigate to. - uri: Annotated[str, Field(description="The file to navigate to.")] - # The target position within the file. - position: Annotated[Position, Field(description="The target position within the file.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for accept/reject tracking. + """ + uri: str + """ + The file to navigate to. + """ + position: Position + """ + The target position within the file. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesRenameSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The file URI containing the symbol. - uri: Annotated[str, Field(description="The file URI containing the symbol.")] - # The position of the symbol to rename. - position: Annotated[Position, Field(description="The position of the symbol to rename.")] - # The new name for the symbol. - new_name: Annotated[str, Field(alias="newName", description="The new name for the symbol.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for accept/reject tracking. + """ + uri: str + """ + The file URI containing the symbol. + """ + position: Position + """ + The position of the symbol to rename. + """ + new_name: Annotated[str, Field(alias="newName")] + """ + The new name for the symbol. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesSearchAndReplaceSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The file URI to search within. - uri: Annotated[str, Field(description="The file URI to search within.")] - # The text or pattern to find. - search: Annotated[str, Field(description="The text or pattern to find.")] - # The replacement text. - replace: Annotated[str, Field(description="The replacement text.")] - # Whether `search` is a regular expression. Defaults to `false`. - is_regex: Annotated[ - Optional[bool], - Field( - alias="isRegex", - description="Whether `search` is a regular expression. Defaults to `false`.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for accept/reject tracking. + """ + uri: str + """ + The file URI to search within. + """ + search: str + """ + The text or pattern to find. + """ + replace: str + """ + The replacement text. + """ + is_regex: Annotated[Optional[bool], Field(alias="isRegex")] = None + """ + Whether `search` is a regular expression. Defaults to `false`. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CloseNesResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class PlanFile(BaseModel): - # The plan ID to update. - plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] - # The URI of the file containing the plan. - uri: Annotated[str, Field(description="The URI of the file containing the plan.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + plan_id: Annotated[str, Field(alias="planId")] + """ + The plan ID to update. + """ + uri: str + """ + The URI of the file containing the plan. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class PlanMarkdown(BaseModel): - # The plan ID to update. - plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] - # Markdown content for the plan. - content: Annotated[str, Field(description="Markdown content for the plan.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + plan_id: Annotated[str, Field(alias="planId")] + """ + The plan ID to update. + """ + content: str + """ + Markdown content for the plan. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class PlanRemoved(BaseModel): - # The plan ID to remove. - plan_id: Annotated[str, Field(alias="planId", description="The plan ID to remove.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + plan_id: Annotated[str, Field(alias="planId")] + """ + The plan ID to remove. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class UnstructuredCommandInput(BaseModel): - # A hint to display when the input hasn't been provided yet - hint: Annotated[ - str, - Field(description="A hint to display when the input hasn't been provided yet"), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + hint: str + """ + A hint to display when the input hasn't been provided yet + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class _CurrentModeUpdate(BaseModel): - # The ID of the current mode - current_mode_id: Annotated[str, Field(alias="currentModeId", description="The ID of the current mode")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + current_mode_id: Annotated[str, Field(alias="currentModeId")] + """ + The ID of the current mode + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class _SessionInfoUpdate(BaseModel): - # Human-readable title for the session. Set to null to clear. - title: Annotated[ - Optional[str], - Field(description="Human-readable title for the session. Set to null to clear."), - ] = None - # ISO 8601 timestamp of last activity. Set to null to clear. - updated_at: Annotated[ - Optional[str], - Field( - alias="updatedAt", - description="ISO 8601 timestamp of last activity. Set to null to clear.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Human-readable title for the session. Set to null to clear. + """ + updated_at: Annotated[Optional[str], Field(alias="updatedAt")] = None + """ + ISO 8601 timestamp of last activity. Set to null to clear. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("title", "updated_at", mode="wrap") @classmethod @@ -1863,43 +1619,45 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class Cost(BaseModel): - # Total cumulative cost for session. - amount: Annotated[float, Field(description="Total cumulative cost for session.")] - # ISO 4217 currency code (e.g., "USD", "EUR"). - currency: Annotated[str, Field(description='ISO 4217 currency code (e.g., "USD", "EUR").')] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + amount: float + """ + Total cumulative cost for session. + """ + currency: str + """ + ISO 4217 currency code (e.g., "USD", "EUR"). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class _UsageUpdate(BaseModel): - # Tokens currently in context. - used: Annotated[int, Field(description="Tokens currently in context.", ge=0)] - # Total context window size in tokens. - size: Annotated[int, Field(description="Total context window size in tokens.", ge=0)] - # Cumulative session cost (optional). - cost: Annotated[Optional[Cost], Field(description="Cumulative session cost (optional).")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + used: Annotated[int, Field(ge=0)] + """ + Tokens currently in context. + """ + size: Annotated[int, Field(ge=0)] + """ + Total context window size in tokens. + """ + cost: Optional[Cost] = None + """ + Cumulative session cost (optional). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("cost", mode="wrap") @classmethod @@ -1908,60 +1666,43 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class CompleteElicitationNotification(BaseModel): - # The ID of the elicitation that completed. - elicitation_id: Annotated[ - str, - Field( - alias="elicitationId", - description="The ID of the elicitation that completed.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + elicitation_id: Annotated[str, Field(alias="elicitationId")] + """ + The ID of the elicitation that completed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class MessageMcpNotification(BaseModel): - # The MCP-over-ACP connection this message is sent on. - connection_id: Annotated[ - str, - Field( - alias="connectionId", - description="The MCP-over-ACP connection this message is sent on.", - ), - ] - # The inner MCP method name. - method: Annotated[str, Field(description="The inner MCP method name.")] - # Optional inner MCP params. - # - # If omitted or set to `null`, the inner MCP message has no params. - params: Annotated[ - Optional[Dict[str, Any]], - Field( - description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + connection_id: Annotated[str, Field(alias="connectionId")] + """ + The MCP-over-ACP connection this message is sent on. + """ + method: str + """ + The inner MCP method name. + """ + params: Optional[Dict[str, Any]] = None + """ + Optional inner MCP params. + + If omitted or set to `null`, the inner MCP message has no params. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("params", mode="wrap") @classmethod @@ -1970,34 +1711,22 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class FileSystemCapabilities(BaseModel): - # Whether the Client supports `fs/read_text_file` requests. - read_text_file: Annotated[ - Optional[bool], - Field( - alias="readTextFile", - description="Whether the Client supports `fs/read_text_file` requests.", - ), - ] = False - # Whether the Client supports `fs/write_text_file` requests. - write_text_file: Annotated[ - Optional[bool], - Field( - alias="writeTextFile", - description="Whether the Client supports `fs/write_text_file` requests.", - ), - ] = False - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + read_text_file: Annotated[Optional[bool], Field(alias="readTextFile")] = False + """ + Whether the Client supports `fs/read_text_file` requests. + """ + write_text_file: Annotated[Optional[bool], Field(alias="writeTextFile")] = False + """ + Whether the Client supports `fs/write_text_file` requests. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("read_text_file", "write_text_file", mode="wrap") @classmethod @@ -2006,57 +1735,42 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class BooleanConfigOptionCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class PlanCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AuthCapabilities(BaseModel): - # Whether the client supports `terminal` authentication methods. - # - # When `true`, the agent may include `terminal` entries in its authentication methods. - terminal: Annotated[ - Optional[bool], - Field( - description="Whether the client supports `terminal` authentication methods.\n\nWhen `true`, the agent may include `terminal` entries in its authentication methods." - ), - ] = False - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + terminal: Optional[bool] = False + """ + Whether the client supports `terminal` authentication methods. + + When `true`, the agent may include `terminal` entries in its authentication methods. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("terminal", mode="wrap") @classmethod @@ -2065,652 +1779,553 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ElicitationFormCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ElicitationUrlCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesJumpCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesRenameCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesSearchAndReplaceCapabilities(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AuthenticateRequest(BaseModel): - # The ID of the authentication method to use. - # Must be one of the methods advertised in the initialize response. - method_id: Annotated[ - str, - Field( - alias="methodId", - description="The ID of the authentication method to use.\nMust be one of the methods advertised in the initialize response.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + method_id: Annotated[str, Field(alias="methodId")] + """ + The ID of the authentication method to use. + Must be one of the methods advertised in the initialize response. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ListProvidersRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SetProviderRequest(BaseModel): - # Provider ID to configure. - provider_id: Annotated[str, Field(alias="providerId", description="Provider ID to configure.")] - # Protocol type for this provider. + provider_id: Annotated[str, Field(alias="providerId")] + """ + Provider ID to configure. + """ api_type: Annotated[ - Union[str, Dict[str, Any]], - Field(alias="apiType", description="Protocol type for this provider."), - ] - # Base URL for requests sent through this provider. - base_url: Annotated[ - str, - Field( - alias="baseUrl", - description="Base URL for requests sent through this provider.", - ), - ] - # Full headers map for this provider. - # May include authorization, routing, or other integration-specific headers. - headers: Annotated[ - Optional[Dict[str, str]], - Field( - description="Full headers map for this provider.\nMay include authorization, routing, or other integration-specific headers." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + Union[ + Literal["anthropic"], + Literal["openai"], + Literal["azure"], + Literal["vertex"], + Literal["bedrock"], + Dict[str, Any], + ], + Field(alias="apiType"), + ] + """ + Protocol type for this provider. + """ + base_url: Annotated[str, Field(alias="baseUrl")] + """ + Base URL for requests sent through this provider. + """ + headers: Optional[Dict[str, str]] = None + """ + Full headers map for this provider. + May include authorization, routing, or other integration-specific headers. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DisableProviderRequest(BaseModel): - # Provider ID to disable. - provider_id: Annotated[str, Field(alias="providerId", description="Provider ID to disable.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + provider_id: Annotated[str, Field(alias="providerId")] + """ + Provider ID to disable. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class LogoutRequest(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class HttpHeader(BaseModel): - # The name of the HTTP header. - name: Annotated[str, Field(description="The name of the HTTP header.")] - # The value to set for the HTTP header. - value: Annotated[str, Field(description="The value to set for the HTTP header.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + The name of the HTTP header. + """ + value: str + """ + The value to set for the HTTP header. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class McpServerHttp(BaseModel): - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # URL to the MCP server. - url: Annotated[str, Field(description="URL to the MCP server.")] - # HTTP headers to set when making requests to the MCP server. - headers: Annotated[ - List[HttpHeader], - Field(description="HTTP headers to set when making requests to the MCP server."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Human-readable name identifying this MCP server. + """ + url: str + """ + URL to the MCP server. + """ + headers: List[HttpHeader] + """ + HTTP headers to set when making requests to the MCP server. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class McpServerSse(BaseModel): - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # URL to the MCP server. - url: Annotated[str, Field(description="URL to the MCP server.")] - # HTTP headers to set when making requests to the MCP server. - headers: Annotated[ - List[HttpHeader], - Field(description="HTTP headers to set when making requests to the MCP server."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Human-readable name identifying this MCP server. + """ + url: str + """ + URL to the MCP server. + """ + headers: List[HttpHeader] + """ + HTTP headers to set when making requests to the MCP server. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class McpServerAcp(BaseModel): - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # Unique identifier for this MCP server, generated by the component providing it. - # - # Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible - # on the same ACP connection. - server_id: Annotated[ - str, - Field( - alias="serverId", - description="Unique identifier for this MCP server, generated by the component providing it.\n\nProviders MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible\non the same ACP connection.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Human-readable name identifying this MCP server. + """ + server_id: Annotated[str, Field(alias="serverId")] + """ + Unique identifier for this MCP server, generated by the component providing it. + + Providers MUST NOT reuse an ID for multiple ACP-transport MCP servers that are visible + on the same ACP connection. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class McpServerStdio(BaseModel): - # Human-readable name identifying this MCP server. - name: Annotated[str, Field(description="Human-readable name identifying this MCP server.")] - # Absolute path to the MCP server executable. - command: Annotated[str, Field(description="Absolute path to the MCP server executable.")] - # Command-line arguments to pass to the MCP server. - args: Annotated[ - List[str], - Field(description="Command-line arguments to pass to the MCP server."), - ] - # Environment variables to set when launching the MCP server. - env: Annotated[ - List[EnvVariable], - Field(description="Environment variables to set when launching the MCP server."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Human-readable name identifying this MCP server. + """ + command: str + """ + Absolute path to the MCP server executable. + """ + args: List[str] + """ + Command-line arguments to pass to the MCP server. + """ + env: List[EnvVariable] + """ + Environment variables to set when launching the MCP server. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ListSessionsRequest(BaseModel): - # Filter sessions by working directory. Must be an absolute path. - cwd: Annotated[ - Optional[str], - Field(description="Filter sessions by working directory. Must be an absolute path."), - ] = None - # Opaque cursor token from a previous response's nextCursor field for cursor-based pagination - cursor: Annotated[ - Optional[str], - Field( - description="Opaque cursor token from a previous response's nextCursor field for cursor-based pagination" - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + cwd: Optional[str] = None + """ + Filter sessions by working directory. Must be an absolute path. + """ + cursor: Optional[str] = None + """ + Opaque cursor token from a previous response's nextCursor field for cursor-based pagination + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DeleteSessionRequest(BaseModel): - # The ID of the session to delete. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to delete.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to delete. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CloseSessionRequest(BaseModel): - # The ID of the session to close. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to close.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to close. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SetSessionModeRequest(BaseModel): - # The ID of the session to set the mode for. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The ID of the session to set the mode for."), - ] - # The ID of the mode to set. - mode_id: Annotated[str, Field(alias="modeId", description="The ID of the mode to set.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to set the mode for. + """ + mode_id: Annotated[str, Field(alias="modeId")] + """ + The ID of the mode to set. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SetSessionConfigOptionBooleanRequest(BaseModel): - # The ID of the session to set the configuration option for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", - ), - ] - # The ID of the configuration option to set. - config_id: Annotated[ - str, - Field(alias="configId", description="The ID of the configuration option to set."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # The boolean value. - value: Annotated[bool, Field(description="The boolean value.")] + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to set the configuration option for. + """ + config_id: Annotated[str, Field(alias="configId")] + """ + The ID of the configuration option to set. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ + value: bool + """ + The boolean value. + """ type: Literal["boolean"] class SetSessionConfigOptionSelectRequest(BaseModel): - # The ID of the session to set the configuration option for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to set the configuration option for.", - ), - ] - # The ID of the configuration option to set. - config_id: Annotated[ - str, - Field(alias="configId", description="The ID of the configuration option to set."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # The value ID. - value: Annotated[str, Field(description="The value ID.")] + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to set the configuration option for. + """ + config_id: Annotated[str, Field(alias="configId")] + """ + The ID of the configuration option to set. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ + value: str + """ + The value ID. + """ class WorkspaceFolder(BaseModel): - # The URI of the folder. - uri: Annotated[str, Field(description="The URI of the folder.")] - # The display name of the folder. - name: Annotated[str, Field(description="The display name of the folder.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the folder. + """ + name: str + """ + The display name of the folder. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesRepository(BaseModel): - # The repository name. - name: Annotated[str, Field(description="The repository name.")] - # The repository owner. - owner: Annotated[str, Field(description="The repository owner.")] - # The remote URL of the repository. - remote_url: Annotated[str, Field(alias="remoteUrl", description="The remote URL of the repository.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + The repository name. + """ + owner: str + """ + The repository owner. + """ + remote_url: Annotated[str, Field(alias="remoteUrl")] + """ + The remote URL of the repository. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesRecentFile(BaseModel): - # The URI of the file. - uri: Annotated[str, Field(description="The URI of the file.")] - # The language identifier. - language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] - # The full text content of the file. - text: Annotated[str, Field(description="The full text content of the file.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the file. + """ + language_id: Annotated[str, Field(alias="languageId")] + """ + The language identifier. + """ + text: str + """ + The full text content of the file. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesExcerpt(BaseModel): - # The start line of the excerpt (zero-based). - start_line: Annotated[ - int, - Field( - alias="startLine", - description="The start line of the excerpt (zero-based).", - ge=0, - ), - ] - # The end line of the excerpt (zero-based). - end_line: Annotated[ - int, - Field( - alias="endLine", - description="The end line of the excerpt (zero-based).", - ge=0, - ), - ] - # The text content of the excerpt. - text: Annotated[str, Field(description="The text content of the excerpt.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + start_line: Annotated[int, Field(alias="startLine", ge=0)] + """ + The start line of the excerpt (zero-based). + """ + end_line: Annotated[int, Field(alias="endLine", ge=0)] + """ + The end line of the excerpt (zero-based). + """ + text: str + """ + The text content of the excerpt. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesEditHistoryEntry(BaseModel): - # The URI of the edited file. - uri: Annotated[str, Field(description="The URI of the edited file.")] - # A diff representing the edit. - diff: Annotated[str, Field(description="A diff representing the edit.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the edited file. + """ + diff: str + """ + A diff representing the edit. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesUserAction(BaseModel): - # The kind of action (e.g., "insertChar", "cursorMovement"). - action: Annotated[ - str, - Field(description='The kind of action (e.g., "insertChar", "cursorMovement").'), - ] - # The URI of the file where the action occurred. - uri: Annotated[str, Field(description="The URI of the file where the action occurred.")] - # The position where the action occurred. - position: Annotated[Position, Field(description="The position where the action occurred.")] - # Timestamp in milliseconds since epoch. - timestamp_ms: Annotated[ - int, - Field( - alias="timestampMs", - description="Timestamp in milliseconds since epoch.", - ge=0, - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + action: str + """ + The kind of action (e.g., "insertChar", "cursorMovement"). + """ + uri: str + """ + The URI of the file where the action occurred. + """ + position: Position + """ + The position where the action occurred. + """ + timestamp_ms: Annotated[int, Field(alias="timestampMs", ge=0)] + """ + Timestamp in milliseconds since epoch. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CloseNesRequest(BaseModel): - # The ID of the NES session to close. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the NES session to close.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the NES session to close. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class WriteTextFileResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ReadTextFileResponse(BaseModel): - # Content payload returned by this response. - content: Annotated[str, Field(description="Content payload returned by this response.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + content: str + """ + Content payload returned by this response. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DeniedOutcome(BaseModel): @@ -2718,75 +2333,52 @@ class DeniedOutcome(BaseModel): class SelectedPermissionOutcome(BaseModel): - # The ID of the option the user selected. - option_id: Annotated[ - str, - Field(alias="optionId", description="The ID of the option the user selected."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + option_id: Annotated[str, Field(alias="optionId")] + """ + The ID of the option the user selected. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CreateTerminalResponse(BaseModel): - # The unique identifier for the created terminal. - terminal_id: Annotated[ - str, - Field( - alias="terminalId", - description="The unique identifier for the created terminal.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + terminal_id: Annotated[str, Field(alias="terminalId")] + """ + The unique identifier for the created terminal. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class TerminalExitStatus(BaseModel): - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], - Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, - ), - ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + exit_code: Annotated[Optional[int], Field(alias="exitCode", ge=0)] = None + """ + The process exit code (may be null if terminated by signal). + """ + signal: Optional[str] = None + """ + The signal that terminated the process (may be null if exited normally). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("exit_code", "signal", mode="wrap") @classmethod @@ -2795,47 +2387,33 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ReleaseTerminalResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class WaitForTerminalExitResponse(BaseModel): - # The process exit code (may be null if terminated by signal). - exit_code: Annotated[ - Optional[int], - Field( - alias="exitCode", - description="The process exit code (may be null if terminated by signal).", - ge=0, - ), - ] = None - # The signal that terminated the process (may be null if exited normally). - signal: Annotated[ - Optional[str], - Field(description="The signal that terminated the process (may be null if exited normally)."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + exit_code: Annotated[Optional[int], Field(alias="exitCode", ge=0)] = None + """ + The process exit code (may be null if terminated by signal). + """ + signal: Optional[str] = None + """ + The signal that terminated the process (may be null if exited normally). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("exit_code", "signal", mode="wrap") @classmethod @@ -2844,49 +2422,37 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class KillTerminalResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DeclineElicitationResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ action: Literal["decline"] class CancelElicitationResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ action: Literal["cancel"] @@ -2894,29 +2460,22 @@ class OtherElicitationResponse(BaseModel): model_config = ConfigDict( extra="allow", ) - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - # Custom or future elicitation action. - # - # Values beginning with `_` are reserved for implementation-specific - # extensions. Unknown values that do not begin with `_` are reserved for - # future ACP variants. - action: Annotated[ - str, - Field( - description="Custom or future elicitation action.\n\nValues beginning with `_` are reserved for implementation-specific\nextensions. Unknown values that do not begin with `_` are reserved for\nfuture ACP variants." - ), - ] + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ + action: str + """ + Custom or future elicitation action. + + Values beginning with `_` are reserved for implementation-specific + extensions. Unknown values that do not begin with `_` are reserved for + future ACP variants. + """ @field_validator("action", mode="before") @classmethod @@ -2930,221 +2489,186 @@ def _reject_known_action(cls, value: Any) -> Any: class ElicitationContentValue(RootModel[Union[str, int, float, bool, List[str]]]): - # Allowed wire representations for [`ElicitationContentValue`]. - root: Annotated[ - Union[str, int, float, bool, List[str]], - Field(description="Allowed wire representations for [`ElicitationContentValue`]."), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: Union[str, int, float, bool, List[str]] + """ + Allowed wire representations for [`ElicitationContentValue`]. + """ class ElicitationAcceptAction(BaseModel): - # The user-provided content, if any, as an object matching the requested schema. - content: Annotated[ - Optional[Dict[str, Any]], - Field(description="The user-provided content, if any, as an object matching the requested schema."), - ] = None + content: Optional[Dict[str, Any]] = None + """ + The user-provided content, if any, as an object matching the requested schema. + """ class ConnectMcpResponse(BaseModel): - # The unique identifier for this MCP-over-ACP connection. - connection_id: Annotated[ - str, - Field( - alias="connectionId", - description="The unique identifier for this MCP-over-ACP connection.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + connection_id: Annotated[str, Field(alias="connectionId")] + """ + The unique identifier for this MCP-over-ACP connection. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DisconnectMcpResponse(BaseModel): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CancelNotification(BaseModel): - # The ID of the session to cancel operations for. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to cancel operations for.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to cancel operations for. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DidOpenDocumentNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the opened document. - uri: Annotated[str, Field(description="The URI of the opened document.")] - # The language identifier of the document (e.g., "rust", "python"). - language_id: Annotated[ - str, - Field( - alias="languageId", - description='The language identifier of the document (e.g., "rust", "python").', - ), - ] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] - # The full text content of the document. - text: Annotated[str, Field(description="The full text content of the document.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + uri: str + """ + The URI of the opened document. + """ + language_id: Annotated[str, Field(alias="languageId")] + """ + The language identifier of the document (e.g., "rust", "python"). + """ + version: int + """ + The version number of the document. + """ + text: str + """ + The full text content of the document. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DidCloseDocumentNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the closed document. - uri: Annotated[str, Field(description="The URI of the closed document.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + uri: str + """ + The URI of the closed document. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DidSaveDocumentNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the saved document. - uri: Annotated[str, Field(description="The URI of the saved document.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + uri: str + """ + The URI of the saved document. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AcceptNesNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The ID of the accepted suggestion. - id: Annotated[str, Field(description="The ID of the accepted suggestion.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + id: str + """ + The ID of the accepted suggestion. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CancelRequestNotification(BaseModel): - # The ID of the request to cancel. - request_id: Annotated[ - Optional[Union[int, str]], - Field(alias="requestId", description="The ID of the request to cancel."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + request_id: Annotated[Optional[Union[int, str]], Field(alias="requestId")] + """ + The ID of the request to cancel. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class WriteTextFileRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # Absolute path to the file to write. - path: Annotated[str, Field(description="Absolute path to the file to write.")] - # The text content to write to the file. - content: Annotated[str, Field(description="The text content to write to the file.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + path: str + """ + Absolute path to the file to write. + """ + content: str + """ + The text content to write to the file. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class FileEditToolCallContent(Diff): @@ -3156,36 +2680,26 @@ class TerminalToolCallContent(Terminal): class Annotations(BaseModel): - # Intended recipients for this content, such as the user or assistant. - audience: Annotated[ - Optional[List[str]], - Field(description="Intended recipients for this content, such as the user or assistant."), - ] = None - # Timestamp indicating when the underlying resource was last modified. - last_modified: Annotated[ - Optional[str], - Field( - alias="lastModified", - description="Timestamp indicating when the underlying resource was last modified.", - ), - ] = None - # Relative importance of this content when clients choose what to surface. - priority: Annotated[ - Optional[float], - Field(description="Relative importance of this content when clients choose what to surface."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + audience: Optional[List[str]] = None + """ + Intended recipients for this content, such as the user or assistant. + """ + last_modified: Annotated[Optional[str], Field(alias="lastModified")] = None + """ + Timestamp indicating when the underlying resource was last modified. + """ + priority: Optional[float] = None + """ + Relative importance of this content when clients choose what to surface. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("last_modified", "priority", mode="wrap") @classmethod @@ -3199,25 +2713,22 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class TextContent(BaseModel): - # Optional annotations that help clients decide how to display or route this content. - annotations: Annotated[ - Optional[Annotations], - Field(description="Optional annotations that help clients decide how to display or route this content."), - ] = None - # Text payload carried by this content block. - text: Annotated[str, Field(description="Text payload carried by this content block.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + annotations: Optional[Annotations] = None + """ + Optional annotations that help clients decide how to display or route this content. + """ + text: str + """ + Text payload carried by this content block. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("annotations", mode="wrap") @classmethod @@ -3226,38 +2737,30 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ImageContent(BaseModel): - # Optional annotations that help clients decide how to display or route this content. - annotations: Annotated[ - Optional[Annotations], - Field(description="Optional annotations that help clients decide how to display or route this content."), - ] = None - # Base64-encoded media payload. - data: Annotated[str, Field(description="Base64-encoded media payload.")] - # MIME type describing the encoded media payload. - mime_type: Annotated[ - str, - Field( - alias="mimeType", - description="MIME type describing the encoded media payload.", - ), - ] - # URI associated with this resource or media payload. - uri: Annotated[ - Optional[str], - Field(description="URI associated with this resource or media payload."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + annotations: Optional[Annotations] = None + """ + Optional annotations that help clients decide how to display or route this content. + """ + data: str + """ + Base64-encoded media payload. + """ + mime_type: Annotated[str, Field(alias="mimeType")] + """ + MIME type describing the encoded media payload. + """ + uri: Optional[str] = None + """ + URI associated with this resource or media payload. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("annotations", "uri", mode="wrap") @classmethod @@ -3266,33 +2769,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class AudioContent(BaseModel): - # Optional annotations that help clients decide how to display or route this content. - annotations: Annotated[ - Optional[Annotations], - Field(description="Optional annotations that help clients decide how to display or route this content."), - ] = None - # Base64-encoded media payload. - data: Annotated[str, Field(description="Base64-encoded media payload.")] - # MIME type describing the encoded media payload. - mime_type: Annotated[ - str, - Field( - alias="mimeType", - description="MIME type describing the encoded media payload.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + annotations: Optional[Annotations] = None + """ + Optional annotations that help clients decide how to display or route this content. + """ + data: str + """ + Base64-encoded media payload. + """ + mime_type: Annotated[str, Field(alias="mimeType")] + """ + MIME type describing the encoded media payload. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("annotations", mode="wrap") @classmethod @@ -3301,47 +2797,42 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ResourceLink(BaseModel): - # Optional annotations that help clients decide how to display or route this content. - annotations: Annotated[ - Optional[Annotations], - Field(description="Optional annotations that help clients decide how to display or route this content."), - ] = None - # Optional human-readable details shown with this protocol object. - description: Annotated[ - Optional[str], - Field(description="Optional human-readable details shown with this protocol object."), - ] = None - # MIME type describing the encoded media payload. - mime_type: Annotated[ - Optional[str], - Field( - alias="mimeType", - description="MIME type describing the encoded media payload.", - ), - ] = None - # Human-readable name shown for this protocol object. - name: Annotated[str, Field(description="Human-readable name shown for this protocol object.")] - # Optional size of the linked resource in bytes, if known. - size: Annotated[ - Optional[int], - Field(description="Optional size of the linked resource in bytes, if known."), - ] = None - # Optional display title for end-user UI. - title: Annotated[Optional[str], Field(description="Optional display title for end-user UI.")] = None - # URI associated with this resource or media payload. - uri: Annotated[str, Field(description="URI associated with this resource or media payload.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + annotations: Optional[Annotations] = None + """ + Optional annotations that help clients decide how to display or route this content. + """ + description: Optional[str] = None + """ + Optional human-readable details shown with this protocol object. + """ + mime_type: Annotated[Optional[str], Field(alias="mimeType")] = None + """ + MIME type describing the encoded media payload. + """ + name: str + """ + Human-readable name shown for this protocol object. + """ + size: Optional[int] = None + """ + Optional size of the linked resource in bytes, if known. + """ + title: Optional[str] = None + """ + Optional display title for end-user UI. + """ + uri: str + """ + URI associated with this resource or media payload. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("annotations", "description", "mime_type", "size", "title", mode="wrap") @classmethod @@ -3350,28 +2841,22 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class EmbeddedResource(BaseModel): - # Optional annotations that help clients decide how to display or route this content. - annotations: Annotated[ - Optional[Annotations], - Field(description="Optional annotations that help clients decide how to display or route this content."), - ] = None - # Embedded resource payload, either text or binary data. - resource: Annotated[ - Union[TextResourceContents, BlobResourceContents], - Field(description="Embedded resource payload, either text or binary data."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + annotations: Optional[Annotations] = None + """ + Optional annotations that help clients decide how to display or route this content. + """ + resource: Union[TextResourceContents, BlobResourceContents] + """ + Embedded resource payload, either text or binary data. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("annotations", mode="wrap") @classmethod @@ -3380,77 +2865,68 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class PermissionOption(BaseModel): - # Unique identifier for this permission option. - option_id: Annotated[ - str, - Field( - alias="optionId", - description="Unique identifier for this permission option.", - ), - ] - # Human-readable label to display to the user. - name: Annotated[str, Field(description="Human-readable label to display to the user.")] - # Hint about the nature of this permission option. - kind: Annotated[PermissionOptionKind, Field(description="Hint about the nature of this permission option.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + option_id: Annotated[str, Field(alias="optionId")] + """ + Unique identifier for this permission option. + """ + name: str + """ + Human-readable label to display to the user. + """ + kind: PermissionOptionKind + """ + Hint about the nature of this permission option. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class CreateTerminalRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The command to execute. - command: Annotated[str, Field(description="The command to execute.")] - # Array of command arguments. - args: Annotated[Optional[List[str]], Field(description="Array of command arguments.")] = None - # Environment variables for the command. - env: Annotated[ - Optional[List[EnvVariable]], - Field(description="Environment variables for the command."), - ] = None - # Working directory for the command. Must be an absolute path. - cwd: Annotated[ - Optional[str], - Field(description="Working directory for the command. Must be an absolute path."), - ] = None - # Maximum number of output bytes to retain. - # - # When the limit is exceeded, the Client truncates from the beginning of the output - # to stay within the limit. - # - # The Client MUST ensure truncation happens at a character boundary to maintain valid - # string output, even if this means the retained output is slightly less than the - # specified limit. - output_byte_limit: Annotated[ - Optional[int], - Field( - alias="outputByteLimit", - description="Maximum number of output bytes to retain.\n\nWhen the limit is exceeded, the Client truncates from the beginning of the output\nto stay within the limit.\n\nThe Client MUST ensure truncation happens at a character boundary to maintain valid\nstring output, even if this means the retained output is slightly less than the\nspecified limit.", - ge=0, - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + command: str + """ + The command to execute. + """ + args: Optional[List[str]] = None + """ + Array of command arguments. + """ + env: Optional[List[EnvVariable]] = None + """ + Environment variables for the command. + """ + cwd: Optional[str] = None + """ + Working directory for the command. Must be an absolute path. + """ + output_byte_limit: Annotated[Optional[int], Field(alias="outputByteLimit", ge=0)] = None + """ + Maximum number of output bytes to retain. + + When the limit is exceeded, the Client truncates from the beginning of the output + to stay within the limit. + + The Client MUST ensure truncation happens at a character boundary to maintain valid + string output, even if this means the retained output is slightly less than the + specified limit. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("cwd", "output_byte_limit", mode="wrap") @classmethod @@ -3469,65 +2945,51 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class CreateUrlSessionElicitationRequest(ElicitationSessionScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + message: str + """ + A human-readable message describing what input is needed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ mode: Literal["url"] - # The unique identifier for this elicitation. - elicitation_id: Annotated[ - str, - Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", - ), - ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + elicitation_id: Annotated[str, Field(alias="elicitationId")] + """ + The unique identifier for this elicitation. + """ + url: AnyUrl + """ + The URL to direct the user to. + """ class CreateUrlRequestElicitationRequest(ElicitationRequestScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + message: str + """ + A human-readable message describing what input is needed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ mode: Literal["url"] - # The unique identifier for this elicitation. - elicitation_id: Annotated[ - str, - Field( - alias="elicitationId", - description="The unique identifier for this elicitation.", - ), - ] - # The URL to direct the user to. - url: Annotated[AnyUrl, Field(description="The URL to direct the user to.")] + elicitation_id: Annotated[str, Field(alias="elicitationId")] + """ + The unique identifier for this elicitation. + """ + url: AnyUrl + """ + The URL to direct the user to. + """ class ElicitationStringPropertySchema(StringPropertySchema): @@ -3551,39 +3013,38 @@ class StringMultiSelectItems(_StringMultiSelectItems): class MultiSelectPropertySchema(BaseModel): - # Optional title for the property. - title: Annotated[Optional[str], Field(description="Optional title for the property.")] = None - # Human-readable description. - description: Annotated[Optional[str], Field(description="Human-readable description.")] = None - # Minimum number of items to select. - min_items: Annotated[ - Optional[int], - Field(alias="minItems", description="Minimum number of items to select.", ge=0), - ] = None - # Maximum number of items to select. - max_items: Annotated[ - Optional[int], - Field(alias="maxItems", description="Maximum number of items to select.", ge=0), - ] = None - # The items definition describing allowed values. - items: Annotated[ - Union[StringMultiSelectItems, OtherMultiSelectItems, TitledMultiSelectItems], - Field(description="The items definition describing allowed values."), - ] - # Default selected values. - default: Annotated[Optional[List[str]], Field(description="Default selected values.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + title: Optional[str] = None + """ + Optional title for the property. + """ + description: Optional[str] = None + """ + Human-readable description. + """ + min_items: Annotated[Optional[int], Field(alias="minItems", ge=0)] = None + """ + Minimum number of items to select. + """ + max_items: Annotated[Optional[int], Field(alias="maxItems", ge=0)] = None + """ + Maximum number of items to select. + """ + items: Union[StringMultiSelectItems, OtherMultiSelectItems, TitledMultiSelectItems] + """ + The items definition describing allowed values. + """ + default: Optional[List[str]] = None + """ + Default selected values. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("description", "title", mode="wrap") @classmethod @@ -3597,145 +3058,108 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ConnectMcpRequest(BaseModel): - # The ACP MCP server ID that was provided by the component declaring the MCP server. - server_id: Annotated[ - str, - Field( - alias="serverId", - description="The ACP MCP server ID that was provided by the component declaring the MCP server.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + server_id: Annotated[str, Field(alias="serverId")] + """ + The ACP MCP server ID that was provided by the component declaring the MCP server. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class MessageMcpRequest(BaseModel): - # The MCP-over-ACP connection this message is sent on. - connection_id: Annotated[ - str, - Field( - alias="connectionId", - description="The MCP-over-ACP connection this message is sent on.", - ), - ] - # The inner MCP method name. - method: Annotated[str, Field(description="The inner MCP method name.")] - # Optional inner MCP params. - # - # If omitted or set to `null`, the inner MCP message has no params. - params: Annotated[ - Optional[Dict[str, Any]], - Field( - description="Optional inner MCP params.\n\nIf omitted or set to `null`, the inner MCP message has no params." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + connection_id: Annotated[str, Field(alias="connectionId")] + """ + The MCP-over-ACP connection this message is sent on. + """ + method: str + """ + The inner MCP method name. + """ + params: Optional[Dict[str, Any]] = None + """ + Optional inner MCP params. + + If omitted or set to `null`, the inner MCP message has no params. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionCapabilities(BaseModel): - # Whether the agent supports `session/list`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports listing sessions. - list: Annotated[ - Optional[SessionListCapabilities], - Field( - description="Whether the agent supports `session/list`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports listing sessions." - ), - ] = None - # Whether the agent supports `session/delete`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports deleting sessions from `session/list`. - delete: Annotated[ - Optional[SessionDeleteCapabilities], - Field( - description="Whether the agent supports `session/delete`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports deleting sessions from `session/list`." - ), - ] = None - # Whether the agent supports `additionalDirectories` on supported session lifecycle requests. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports `additionalDirectories` on - # supported session lifecycle requests. - # - # Agents that also support `session/list` may return - # `SessionInfo.additionalDirectories` to report the complete ordered - # additional-root list associated with a listed session. + list: Optional[SessionListCapabilities] = None + """ + Whether the agent supports `session/list`. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports listing sessions. + """ + delete: Optional[SessionDeleteCapabilities] = None + """ + Whether the agent supports `session/delete`. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports deleting sessions from `session/list`. + """ additional_directories: Annotated[ Optional[SessionAdditionalDirectoriesCapabilities], - Field( - alias="additionalDirectories", - description="Whether the agent supports `additionalDirectories` on supported session lifecycle requests.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports `additionalDirectories` on\nsupported session lifecycle requests.\n\nAgents that also support `session/list` may return\n`SessionInfo.additionalDirectories` to report the complete ordered\nadditional-root list associated with a listed session.", - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Whether the agent supports `session/fork`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports forking sessions. - fork: Annotated[ - Optional[SessionForkCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the agent supports `session/fork`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports forking sessions." - ), - ] = None - # Whether the agent supports `session/resume`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports resuming sessions. - resume: Annotated[ - Optional[SessionResumeCapabilities], - Field( - description="Whether the agent supports `session/resume`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports resuming sessions." - ), - ] = None - # Whether the agent supports `session/close`. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports closing sessions. - close: Annotated[ - Optional[SessionCloseCapabilities], - Field( - description="Whether the agent supports `session/close`.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports closing sessions." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + Field(alias="additionalDirectories"), + ] = None + """ + Whether the agent supports `additionalDirectories` on supported session lifecycle requests. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports `additionalDirectories` on + supported session lifecycle requests. + + Agents that also support `session/list` may return + `SessionInfo.additionalDirectories` to report the complete ordered + additional-root list associated with a listed session. + """ + fork: Optional[SessionForkCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Whether the agent supports `session/fork`. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports forking sessions. + """ + resume: Optional[SessionResumeCapabilities] = None + """ + Whether the agent supports `session/resume`. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports resuming sessions. + """ + close: Optional[SessionCloseCapabilities] = None + """ + Whether the agent supports `session/close`. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports closing sessions. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("additional_directories", "close", "delete", "fork", "list", "resume", mode="wrap") @classmethod @@ -3744,28 +3168,21 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class AgentAuthCapabilities(BaseModel): - # Whether the agent supports the logout method. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports the logout method. - logout: Annotated[ - Optional[LogoutCapabilities], - Field( - description="Whether the agent supports the logout method.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports the logout method." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + logout: Optional[LogoutCapabilities] = None + """ + Whether the agent supports the logout method. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports the logout method. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("logout", mode="wrap") @classmethod @@ -3774,83 +3191,53 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesDocumentDidChangeCapabilities(BaseModel): - # The sync kind the agent wants: `"full"` or `"incremental"`. - sync_kind: Annotated[ - str, - Field( - alias="syncKind", - description='The sync kind the agent wants: `"full"` or `"incremental"`.', - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + sync_kind: Annotated[str, Field(alias="syncKind")] + """ + The sync kind the agent wants: `"full"` or `"incremental"`. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesContextCapabilities(BaseModel): - # Whether the agent wants recent files context. - recent_files: Annotated[ - Optional[NesRecentFilesCapabilities], - Field( - alias="recentFiles", - description="Whether the agent wants recent files context.", - ), - ] = None - # Whether the agent wants related snippets context. - related_snippets: Annotated[ - Optional[NesRelatedSnippetsCapabilities], - Field( - alias="relatedSnippets", - description="Whether the agent wants related snippets context.", - ), - ] = None - # Whether the agent wants edit history context. - edit_history: Annotated[ - Optional[NesEditHistoryCapabilities], - Field( - alias="editHistory", - description="Whether the agent wants edit history context.", - ), - ] = None - # Whether the agent wants user actions context. - user_actions: Annotated[ - Optional[NesUserActionsCapabilities], - Field( - alias="userActions", - description="Whether the agent wants user actions context.", - ), - ] = None - # Whether the agent wants open files context. - open_files: Annotated[ - Optional[NesOpenFilesCapabilities], - Field(alias="openFiles", description="Whether the agent wants open files context."), - ] = None - # Whether the agent wants diagnostics context. - diagnostics: Annotated[ - Optional[NesDiagnosticsCapabilities], - Field(description="Whether the agent wants diagnostics context."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + recent_files: Annotated[Optional[NesRecentFilesCapabilities], Field(alias="recentFiles")] = None + """ + Whether the agent wants recent files context. + """ + related_snippets: Annotated[Optional[NesRelatedSnippetsCapabilities], Field(alias="relatedSnippets")] = None + """ + Whether the agent wants related snippets context. + """ + edit_history: Annotated[Optional[NesEditHistoryCapabilities], Field(alias="editHistory")] = None + """ + Whether the agent wants edit history context. + """ + user_actions: Annotated[Optional[NesUserActionsCapabilities], Field(alias="userActions")] = None + """ + Whether the agent wants user actions context. + """ + open_files: Annotated[Optional[NesOpenFilesCapabilities], Field(alias="openFiles")] = None + """ + Whether the agent wants open files context. + """ + diagnostics: Optional[NesDiagnosticsCapabilities] = None + """ + Whether the agent wants diagnostics context. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator( "diagnostics", "edit_history", "open_files", "recent_files", "related_snippets", "user_actions", mode="wrap" @@ -3869,45 +3256,41 @@ class TerminalAuthMethod(AuthMethodTerminal): class ProviderInfo(BaseModel): - # Provider identifier, for example "main" or "openai". - provider_id: Annotated[ - str, - Field( - alias="providerId", - description='Provider identifier, for example "main" or "openai".', - ), - ] - # Supported protocol types for this provider. - supported: Annotated[ - List[Union[str, Dict[str, Any]]], - Field(description="Supported protocol types for this provider."), - ] - # Whether this provider is mandatory and cannot be disabled via `providers/disable`. - # If true, clients must not call `providers/disable` for this provider ID. - required: Annotated[ - bool, - Field( - description="Whether this provider is mandatory and cannot be disabled via `providers/disable`.\nIf true, clients must not call `providers/disable` for this provider ID." - ), - ] - # Current effective non-secret routing config. - # Null or omitted means provider is disabled. - current: Annotated[ - Optional[ProviderCurrentConfig], - Field(description="Current effective non-secret routing config.\nNull or omitted means provider is disabled."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + provider_id: Annotated[str, Field(alias="providerId")] + """ + Provider identifier, for example "main" or "openai". + """ + supported: List[ + Union[ + Literal["anthropic"], + Literal["openai"], + Literal["azure"], + Literal["vertex"], + Literal["bedrock"], + Dict[str, Any], + ] + ] + """ + Supported protocol types for this provider. + """ + required: bool + """ + Whether this provider is mandatory and cannot be disabled via `providers/disable`. + If true, clients must not call `providers/disable` for this provider ID. + """ + current: Optional[ProviderCurrentConfig] = None + """ + Current effective non-secret routing config. + Null or omitted means provider is disabled. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("supported", mode="wrap") @classmethod @@ -3916,31 +3299,22 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class SessionModeState(BaseModel): - # The current mode the Agent is in. - current_mode_id: Annotated[ - str, - Field(alias="currentModeId", description="The current mode the Agent is in."), - ] - # The set of modes that the Agent can operate in - available_modes: Annotated[ - List[SessionMode], - Field( - alias="availableModes", - description="The set of modes that the Agent can operate in", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + current_mode_id: Annotated[str, Field(alias="currentModeId")] + """ + The current mode the Agent is in. + """ + available_modes: Annotated[List[SessionMode], Field(alias="availableModes")] + """ + The set of modes that the Agent can operate in + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("available_modes", mode="wrap") @classmethod @@ -3949,32 +3323,38 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class SessionConfigOptionBoolean(SessionConfigBoolean): - # Unique identifier for the configuration option. - id: Annotated[str, Field(description="Unique identifier for the configuration option.")] - # Human-readable label for the option. - name: Annotated[str, Field(description="Human-readable label for the option.")] - # Optional description for the Client to display to the user. - description: Annotated[ - Optional[str], - Field(description="Optional description for the Client to display to the user."), - ] = None - # Optional semantic category for this option (UX only). - category: Annotated[ - Optional[Union[str, Dict[str, Any]]], - Field(description="Optional semantic category for this option (UX only)."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for the configuration option. + """ + name: str + """ + Human-readable label for the option. + """ + description: Optional[str] = None + """ + Optional description for the Client to display to the user. + """ + category: Optional[ + Union[ + Literal["mode"], + Literal["model"], + Literal["model_config"], + Literal["thought_level"], + Dict[str, Any], + ] + ] = None + """ + Optional semantic category for this option (UX only). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ type: Literal["boolean"] @field_validator("category", "description", mode="wrap") @@ -3984,27 +3364,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class SessionConfigSelectGroup(BaseModel): - # Unique identifier for this group. - group: Annotated[str, Field(description="Unique identifier for this group.")] - # Human-readable label for this group. - name: Annotated[str, Field(description="Human-readable label for this group.")] - # The set of option values in this group. - options: Annotated[ - List[SessionConfigSelectOption], - Field(description="The set of option values in this group."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + group: str + """ + Unique identifier for this group. + """ + name: str + """ + Human-readable label for this group. + """ + options: List[SessionConfigSelectOption] + """ + The set of option values in this group. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("options", mode="wrap") @classmethod @@ -4013,29 +3392,23 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ListSessionsResponse(BaseModel): - # Array of session information objects - sessions: Annotated[List[SessionInfo], Field(description="Array of session information objects")] - # Opaque cursor token. If present, pass this in the next request's cursor parameter - # to fetch the next page. If absent, there are no more results. - next_cursor: Annotated[ - Optional[str], - Field( - alias="nextCursor", - description="Opaque cursor token. If present, pass this in the next request's cursor parameter\nto fetch the next page. If absent, there are no more results.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + sessions: List[SessionInfo] + """ + Array of session information objects + """ + next_cursor: Annotated[Optional[str], Field(alias="nextCursor")] = None + """ + Opaque cursor token. If present, pass this in the next request's cursor parameter + to fetch the next page. If absent, there are no more results. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("next_cursor", mode="wrap") @classmethod @@ -4049,37 +3422,26 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class PromptResponse(BaseModel): - # Indicates why the agent stopped processing the turn. - stop_reason: Annotated[ - StopReason, - Field( - alias="stopReason", - description="Indicates why the agent stopped processing the turn.", - ), - ] - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Token usage for this turn (optional). - usage: Annotated[ - Optional[Usage], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nToken usage for this turn (optional)." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + stop_reason: Annotated[StopReason, Field(alias="stopReason")] + """ + Indicates why the agent stopped processing the turn. + """ + usage: Optional[Usage] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Token usage for this turn (optional). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("usage", mode="wrap") @classmethod @@ -4100,49 +3462,50 @@ class NesSearchAndReplaceSuggestionVariant(NesSearchAndReplaceSuggestion): class Range(BaseModel): - # The start position (inclusive). - start: Annotated[Position, Field(description="The start position (inclusive).")] - # The end position (exclusive). - end: Annotated[Position, Field(description="The end position (exclusive).")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + start: Position + """ + The start position (inclusive). + """ + end: Position + """ + The end position (exclusive). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class Error(BaseModel): - # A number indicating the error type that occurred. - # This must be an integer as defined in the JSON-RPC specification. - code: Annotated[ + code: Union[ + Literal[-32700], + Literal[-32600], + Literal[-32601], + Literal[-32602], + Literal[-32603], + Literal[-32800], + Literal[-32000], + Literal[-32002], int, - Field( - description="A number indicating the error type that occurred.\nThis must be an integer as defined in the JSON-RPC specification." - ), - ] - # A string providing a short description of the error. - # The message should be limited to a concise single sentence. - message: Annotated[ - str, - Field( - description="A string providing a short description of the error.\nThe message should be limited to a concise single sentence." - ), ] - # Optional primitive or structured value that contains additional information about the error. - # This may include debugging information or context-specific details. - data: Annotated[ - Optional[Any], - Field( - description="Optional primitive or structured value that contains additional information about the error.\nThis may include debugging information or context-specific details." - ), - ] = None + """ + A number indicating the error type that occurred. + This must be an integer as defined in the JSON-RPC specification. + """ + message: str + """ + A string providing a short description of the error. + The message should be limited to a concise single sentence. + """ + data: Optional[Any] = None + """ + Optional primitive or structured value that contains additional information about the error. + This may include debugging information or context-specific details. + """ @field_validator("data", mode="wrap") @classmethod @@ -4167,58 +3530,45 @@ class UsageUpdate(_UsageUpdate): class PlanEntry(BaseModel): - # Human-readable description of what this task aims to accomplish. - content: Annotated[ - str, - Field(description="Human-readable description of what this task aims to accomplish."), - ] - # The relative importance of this task. - # Used to indicate which tasks are most critical to the overall goal. - priority: Annotated[ - PlanEntryPriority, - Field( - description="The relative importance of this task.\nUsed to indicate which tasks are most critical to the overall goal." - ), - ] - # Current execution status of this task. - status: Annotated[PlanEntryStatus, Field(description="Current execution status of this task.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + content: str + """ + Human-readable description of what this task aims to accomplish. + """ + priority: PlanEntryPriority + """ + The relative importance of this task. + Used to indicate which tasks are most critical to the overall goal. + """ + status: PlanEntryStatus + """ + Current execution status of this task. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class Plan(BaseModel): - # The list of tasks to be accomplished. - # - # When updating a plan, the agent must send a complete list of all entries - # with their current status. The client replaces the entire plan with each update. - entries: Annotated[ - List[PlanEntry], - Field( - description="The list of tasks to be accomplished.\n\nWhen updating a plan, the agent must send a complete list of all entries\nwith their current status. The client replaces the entire plan with each update." - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + entries: List[PlanEntry] + """ + The list of tasks to be accomplished. + + When updating a plan, the agent must send a complete list of all entries + with their current status. The client replaces the entire plan with each update. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("entries", mode="wrap") @classmethod @@ -4235,30 +3585,25 @@ class PlanUpdateMarkdown(PlanMarkdown): class PlanItems(BaseModel): - # The plan ID to update. - plan_id: Annotated[str, Field(alias="planId", description="The plan ID to update.")] - # The list of tasks to be accomplished. - # - # When updating an item-based plan, the agent must send a complete list of all entries - # with their current status. The client replaces that plan with each update. - entries: Annotated[ - List[PlanEntry], - Field( - description="The list of tasks to be accomplished.\n\nWhen updating an item-based plan, the agent must send a complete list of all entries\nwith their current status. The client replaces that plan with each update." - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + plan_id: Annotated[str, Field(alias="planId")] + """ + The plan ID to update. + """ + entries: List[PlanEntry] + """ + The list of tasks to be accomplished. + + When updating an item-based plan, the agent must send a complete list of all entries + with their current status. The client replaces that plan with each update. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("entries", mode="wrap") @classmethod @@ -4267,38 +3612,32 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class AvailableCommandInput(RootModel[UnstructuredCommandInput]): - # The input specification for a command. - root: Annotated[ - UnstructuredCommandInput, - Field(description="The input specification for a command."), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: UnstructuredCommandInput + """ + The input specification for a command. + """ class SessionConfigOptionsCapabilities(BaseModel): - # Whether the client supports boolean session configuration options. - # - # Optional. Omitted or `null` both mean the client does not advertise support. - # Supplying `{}` means agents may include `type: "boolean"` entries in - # `configOptions`, and the client may send `session/set_config_option` - # requests with `type: "boolean"` and a boolean `value`. - boolean: Annotated[ - Optional[BooleanConfigOptionCapabilities], - Field( - description='Whether the client supports boolean session configuration options.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means agents may include `type: "boolean"` entries in\n`configOptions`, and the client may send `session/set_config_option`\nrequests with `type: "boolean"` and a boolean `value`.' - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + boolean: Optional[BooleanConfigOptionCapabilities] = None + """ + Whether the client supports boolean session configuration options. + + Optional. Omitted or `null` both mean the client does not advertise support. + Supplying `{}` means agents may include `type: "boolean"` entries in + `configOptions`, and the client may send `session/set_config_option` + requests with `type: "boolean"` and a boolean `value`. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("boolean", mode="wrap") @classmethod @@ -4306,40 +3645,30 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: return salvage_on_error(value, handler, lambda: None) -class ElicitationCapabilities(BaseModel): - # Whether the client supports form-based elicitation. - # - # Optional. Omitted or `null` both mean the client does not advertise support. - # Supplying `{}` means the client supports form-based elicitation. - form: Annotated[ - Optional[ElicitationFormCapabilities], - Field( - description="Whether the client supports form-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports form-based elicitation." - ), - ] = None - # Whether the client supports URL-based elicitation. - # - # Optional. Omitted or `null` both mean the client does not advertise support. - # Supplying `{}` means the client supports URL-based elicitation. - url: Annotated[ - Optional[ElicitationUrlCapabilities], - Field( - description="Whether the client supports URL-based elicitation.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client supports URL-based elicitation." - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None - +class ElicitationCapabilities(BaseModel): + form: Optional[ElicitationFormCapabilities] = None + """ + Whether the client supports form-based elicitation. + + Optional. Omitted or `null` both mean the client does not advertise support. + Supplying `{}` means the client supports form-based elicitation. + """ + url: Optional[ElicitationUrlCapabilities] = None + """ + Whether the client supports URL-based elicitation. + + Optional. Omitted or `null` both mean the client does not advertise support. + Supplying `{}` means the client supports URL-based elicitation. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ + @field_validator("form", "url", mode="wrap") @classmethod def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: @@ -4347,36 +3676,26 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ClientNesCapabilities(BaseModel): - # Whether the client supports the `jump` suggestion kind. - jump: Annotated[ - Optional[NesJumpCapabilities], - Field(description="Whether the client supports the `jump` suggestion kind."), - ] = None - # Whether the client supports the `rename` suggestion kind. - rename: Annotated[ - Optional[NesRenameCapabilities], - Field(description="Whether the client supports the `rename` suggestion kind."), - ] = None - # Whether the client supports the `searchAndReplace` suggestion kind. - search_and_replace: Annotated[ - Optional[NesSearchAndReplaceCapabilities], - Field( - alias="searchAndReplace", - description="Whether the client supports the `searchAndReplace` suggestion kind.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + jump: Optional[NesJumpCapabilities] = None + """ + Whether the client supports the `jump` suggestion kind. + """ + rename: Optional[NesRenameCapabilities] = None + """ + Whether the client supports the `rename` suggestion kind. + """ + search_and_replace: Annotated[Optional[NesSearchAndReplaceCapabilities], Field(alias="searchAndReplace")] = None + """ + Whether the client supports the `searchAndReplace` suggestion kind. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("jump", "rename", "search_and_replace", mode="wrap") @classmethod @@ -4397,46 +3716,38 @@ class AcpMcpServer(McpServerAcp): class LoadSessionRequest(BaseModel): - # List of MCP servers to connect to for this session. mcp_servers: Annotated[ List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the loaded - # session. It may differ from any previously used or reported list as long as - # the request `cwd` matches the session's `cwd`. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the loaded\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - ), - ] = None - # The ID of the session to load. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to load.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + Field(alias="mcpServers"), + ] + """ + List of MCP servers to connect to for this session. + """ + cwd: str + """ + The working directory for this session. Must be an absolute path. + """ + additional_directories: Annotated[Optional[List[str]], Field(alias="additionalDirectories")] = None + """ + Additional workspace roots to activate for this session. Each path must be absolute. + + When omitted or empty, no additional roots are activated. When non-empty, + this is the complete resulting additional-root list for the loaded + session. It may differ from any previously used or reported list as long as + the request `cwd` matches the session's `cwd`. + """ + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to load. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("additional_directories", mode="wrap") @classmethod @@ -4450,45 +3761,37 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class ForkSessionRequest(BaseModel): - # The ID of the session to fork. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to fork.")] - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the forked - # session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the forked\nsession.", - ), - ] = None - # List of MCP servers to connect to for this session. + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to fork. + """ + cwd: str + """ + The working directory for this session. Must be an absolute path. + """ + additional_directories: Annotated[Optional[List[str]], Field(alias="additionalDirectories")] = None + """ + Additional workspace roots to activate for this session. Each path must be absolute. + + When omitted or empty, no additional roots are activated. When non-empty, + this is the complete resulting additional-root list for the forked + session. + """ mcp_servers: Annotated[ Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Field(alias="mcpServers"), ] = None + """ + List of MCP servers to connect to for this session. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("additional_directories", mode="wrap") @classmethod @@ -4502,46 +3805,38 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class ResumeSessionRequest(BaseModel): - # The ID of the session to resume. - session_id: Annotated[str, Field(alias="sessionId", description="The ID of the session to resume.")] - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Additional workspace roots to activate for this session. Each path must be absolute. - # - # When omitted or empty, no additional roots are activated. When non-empty, - # this is the complete resulting additional-root list for the resumed - # session. It may differ from any previously used or reported list as long as - # the request `cwd` matches the session's `cwd`. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots to activate for this session. Each path must be absolute.\n\nWhen omitted or empty, no additional roots are activated. When non-empty,\nthis is the complete resulting additional-root list for the resumed\nsession. It may differ from any previously used or reported list as long as\nthe request `cwd` matches the session's `cwd`.", - ), - ] = None - # List of MCP servers to connect to for this session. + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to resume. + """ + cwd: str + """ + The working directory for this session. Must be an absolute path. + """ + additional_directories: Annotated[Optional[List[str]], Field(alias="additionalDirectories")] = None + """ + Additional workspace roots to activate for this session. Each path must be absolute. + + When omitted or empty, no additional roots are activated. When non-empty, + this is the complete resulting additional-root list for the resumed + session. It may differ from any previously used or reported list as long as + the request `cwd` matches the session's `cwd`. + """ mcp_servers: Annotated[ Optional[List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]]], - Field( - alias="mcpServers", - description="List of MCP servers to connect to for this session.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Field(alias="mcpServers"), ] = None + """ + List of MCP servers to connect to for this session. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("additional_directories", mode="wrap") @classmethod @@ -4555,33 +3850,26 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class StartNesRequest(BaseModel): - # The root URI of the workspace. - workspace_uri: Annotated[ - Optional[str], - Field(alias="workspaceUri", description="The root URI of the workspace."), - ] = None - # The workspace folders. - workspace_folders: Annotated[ - Optional[List[WorkspaceFolder]], - Field(alias="workspaceFolders", description="The workspace folders."), - ] = None - # Repository metadata, if the workspace is a git repository. - repository: Annotated[ - Optional[NesRepository], - Field(description="Repository metadata, if the workspace is a git repository."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + workspace_uri: Annotated[Optional[str], Field(alias="workspaceUri")] = None + """ + The root URI of the workspace. + """ + workspace_folders: Annotated[Optional[List[WorkspaceFolder]], Field(alias="workspaceFolders")] = None + """ + The workspace folders. + """ + repository: Optional[NesRepository] = None + """ + Repository metadata, if the workspace is a git repository. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("repository", "workspace_uri", mode="wrap") @classmethod @@ -4590,55 +3878,49 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesRelatedSnippet(BaseModel): - # The URI of the file containing the snippets. - uri: Annotated[str, Field(description="The URI of the file containing the snippets.")] - # The code excerpts. - excerpts: Annotated[List[NesExcerpt], Field(description="The code excerpts.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the file containing the snippets. + """ + excerpts: List[NesExcerpt] + """ + The code excerpts. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesOpenFile(BaseModel): - # The URI of the file. - uri: Annotated[str, Field(description="The URI of the file.")] - # The language identifier. - language_id: Annotated[str, Field(alias="languageId", description="The language identifier.")] - # The visible range in the editor, if any. - visible_range: Annotated[ - Optional[Range], - Field(alias="visibleRange", description="The visible range in the editor, if any."), - ] = None - # Timestamp in milliseconds since epoch of when the file was last focused. - last_focused_ms: Annotated[ - Optional[int], - Field( - alias="lastFocusedMs", - description="Timestamp in milliseconds since epoch of when the file was last focused.", - ge=0, - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the file. + """ + language_id: Annotated[str, Field(alias="languageId")] + """ + The language identifier. + """ + visible_range: Annotated[Optional[Range], Field(alias="visibleRange")] = None + """ + The visible range in the editor, if any. + """ + last_focused_ms: Annotated[Optional[int], Field(alias="lastFocusedMs", ge=0)] = None + """ + Timestamp in milliseconds since epoch of when the file was last focused. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("last_focused_ms", "visible_range", mode="wrap") @classmethod @@ -4647,36 +3929,41 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NesDiagnostic(BaseModel): - # The URI of the file containing the diagnostic. - uri: Annotated[str, Field(description="The URI of the file containing the diagnostic.")] - # The range of the diagnostic. - range: Annotated[Range, Field(description="The range of the diagnostic.")] - # The severity of the diagnostic. - severity: Annotated[str, Field(description="The severity of the diagnostic.")] - # The diagnostic message. - message: Annotated[str, Field(description="The diagnostic message.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + uri: str + """ + The URI of the file containing the diagnostic. + """ + range: Range + """ + The range of the diagnostic. + """ + severity: str + """ + The severity of the diagnostic. + """ + message: str + """ + The diagnostic message. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ClientErrorMessage(BaseModel): - # The id of the request this response answers. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The id of the request this response answers."), - ] = None - # Method-specific error data. - error: Annotated[Error, Field(description="Method-specific error data.")] + id: Optional[Union[int, str]] + """ + The id of the request this response answers. + """ + error: Error + """ + Method-specific error data. + """ class AllowedOutcome(SelectedPermissionOutcome): @@ -4684,27 +3971,26 @@ class AllowedOutcome(SelectedPermissionOutcome): class TerminalOutputResponse(BaseModel): - # The terminal output captured so far. - output: Annotated[str, Field(description="The terminal output captured so far.")] - # Whether the output was truncated due to byte limits. - truncated: Annotated[bool, Field(description="Whether the output was truncated due to byte limits.")] - # Exit status if the command has completed. - exit_status: Annotated[ - Optional[TerminalExitStatus], - Field(alias="exitStatus", description="Exit status if the command has completed."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + output: str + """ + The terminal output captured so far. + """ + truncated: bool + """ + Whether the output was truncated due to byte limits. + """ + exit_status: Annotated[Optional[TerminalExitStatus], Field(alias="exitStatus")] = None + """ + Exit status if the command has completed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("exit_status", mode="wrap") @classmethod @@ -4713,102 +3999,88 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class AcceptElicitationResponse(ElicitationAcceptAction): - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ action: Literal["accept"] class TextDocumentContentChangeEvent(BaseModel): - # The range of the document that changed. If `None`, the entire content is replaced. - range: Annotated[ - Optional[Range], - Field(description="The range of the document that changed. If `None`, the entire content is replaced."), - ] = None - # The new text for the range, or the full document content if `range` is `None`. - text: Annotated[ - str, - Field(description="The new text for the range, or the full document content if `range` is `None`."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + range: Optional[Range] = None + """ + The range of the document that changed. If `None`, the entire content is replaced. + """ + text: str + """ + The new text for the range, or the full document content if `range` is `None`. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DidFocusDocumentNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the focused document. - uri: Annotated[str, Field(description="The URI of the focused document.")] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] - # The current cursor position. - position: Annotated[Position, Field(description="The current cursor position.")] - # The portion of the file currently visible in the editor viewport. - visible_range: Annotated[ - Range, - Field( - alias="visibleRange", - description="The portion of the file currently visible in the editor viewport.", - ), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + uri: str + """ + The URI of the focused document. + """ + version: int + """ + The version number of the document. + """ + position: Position + """ + The current cursor position. + """ + visible_range: Annotated[Range, Field(alias="visibleRange")] + """ + The portion of the file currently visible in the editor viewport. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class RejectNesNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The ID of the rejected suggestion. - id: Annotated[str, Field(description="The ID of the rejected suggestion.")] - # The reason for rejection. - reason: Annotated[Optional[str], Field(description="The reason for rejection.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + id: str + """ + The ID of the rejected suggestion. + """ + reason: Optional[str] = None + """ + The reason for rejection. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("reason", mode="wrap") @classmethod @@ -4837,25 +4109,23 @@ class EmbeddedResourceContentBlock(EmbeddedResource): class Content(BaseModel): - # The actual content block. content: Annotated[ Union[ TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock ], - Field(description="The actual content block.", discriminator="type"), + Field(discriminator="type"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The actual content block. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): @@ -4863,68 +4133,45 @@ class ElicitationMultiSelectPropertySchema(MultiSelectPropertySchema): class AgentErrorMessage(BaseModel): - # The id of the request this response answers. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The id of the request this response answers."), - ] = None - # Method-specific error data. - error: Annotated[Error, Field(description="Method-specific error data.")] + id: Optional[Union[int, str]] + """ + The id of the request this response answers. + """ + error: Error + """ + Method-specific error data. + """ class NesDocumentEventCapabilities(BaseModel): - # Whether the agent wants `document/didOpen` events. - did_open: Annotated[ - Optional[NesDocumentDidOpenCapabilities], - Field( - alias="didOpen", - description="Whether the agent wants `document/didOpen` events.", - ), - ] = None - # Whether the agent wants `document/didChange` events, and the sync kind. - did_change: Annotated[ - Optional[NesDocumentDidChangeCapabilities], - Field( - alias="didChange", - description="Whether the agent wants `document/didChange` events, and the sync kind.", - ), - ] = None - # Whether the agent wants `document/didClose` events. - did_close: Annotated[ - Optional[NesDocumentDidCloseCapabilities], - Field( - alias="didClose", - description="Whether the agent wants `document/didClose` events.", - ), - ] = None - # Whether the agent wants `document/didSave` events. - did_save: Annotated[ - Optional[NesDocumentDidSaveCapabilities], - Field( - alias="didSave", - description="Whether the agent wants `document/didSave` events.", - ), - ] = None - # Whether the agent wants `document/didFocus` events. - did_focus: Annotated[ - Optional[NesDocumentDidFocusCapabilities], - Field( - alias="didFocus", - description="Whether the agent wants `document/didFocus` events.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + did_open: Annotated[Optional[NesDocumentDidOpenCapabilities], Field(alias="didOpen")] = None + """ + Whether the agent wants `document/didOpen` events. + """ + did_change: Annotated[Optional[NesDocumentDidChangeCapabilities], Field(alias="didChange")] = None + """ + Whether the agent wants `document/didChange` events, and the sync kind. + """ + did_close: Annotated[Optional[NesDocumentDidCloseCapabilities], Field(alias="didClose")] = None + """ + Whether the agent wants `document/didClose` events. + """ + did_save: Annotated[Optional[NesDocumentDidSaveCapabilities], Field(alias="didSave")] = None + """ + Whether the agent wants `document/didSave` events. + """ + did_focus: Annotated[Optional[NesDocumentDidFocusCapabilities], Field(alias="didFocus")] = None + """ + Whether the agent wants `document/didFocus` events. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("did_change", "did_close", "did_focus", "did_open", "did_save", mode="wrap") @classmethod @@ -4933,81 +4180,75 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class ListProvidersResponse(BaseModel): - # Configurable providers with current routing info suitable for UI display. - providers: Annotated[ - List[ProviderInfo], - Field(description="Configurable providers with current routing info suitable for UI display."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + providers: List[ProviderInfo] + """ + Configurable providers with current routing info suitable for UI display. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class SessionConfigSelect(BaseModel): - # The currently selected value. - current_value: Annotated[str, Field(alias="currentValue", description="The currently selected value.")] - # The set of selectable options. - options: Annotated[ - Union[List[SessionConfigSelectOption], List[SessionConfigSelectGroup]], - Field(description="The set of selectable options."), - ] + current_value: Annotated[str, Field(alias="currentValue")] + """ + The currently selected value. + """ + options: Union[List[SessionConfigSelectOption], List[SessionConfigSelectGroup]] + """ + The set of selectable options. + """ class NesTextEdit(BaseModel): - # The range to replace. - range: Annotated[Range, Field(description="The range to replace.")] - # The replacement text. - new_text: Annotated[str, Field(alias="newText", description="The replacement text.")] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + range: Range + """ + The range to replace. + """ + new_text: Annotated[str, Field(alias="newText")] + """ + The replacement text. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesEditSuggestion(BaseModel): - # Unique identifier for accept/reject tracking. - id: Annotated[str, Field(description="Unique identifier for accept/reject tracking.")] - # The URI of the file to edit. - uri: Annotated[str, Field(description="The URI of the file to edit.")] - # The text edits to apply. - edits: Annotated[List[NesTextEdit], Field(description="The text edits to apply.")] - # Optional suggested cursor position after applying edits. - cursor_position: Annotated[ - Optional[Position], - Field( - alias="cursorPosition", - description="Optional suggested cursor position after applying edits.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for accept/reject tracking. + """ + uri: str + """ + The URI of the file to edit. + """ + edits: List[NesTextEdit] + """ + The text edits to apply. + """ + cursor_position: Annotated[Optional[Position], Field(alias="cursorPosition")] = None + """ + Optional suggested cursor position after applying edits. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("cursor_position", mode="wrap") @classmethod @@ -5020,36 +4261,30 @@ class AgentPlanUpdate(Plan): class ContentChunk(BaseModel): - # A single item of content content: Annotated[ Union[ TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock ], - Field(description="A single item of content", discriminator="type"), - ] - # A unique identifier for the message this chunk belongs to. - # - # All chunks belonging to the same message share the same `messageId`. - # A change in `messageId` indicates a new message has started. - message_id: Annotated[ - Optional[str], - Field( - alias="messageId", - description="A unique identifier for the message this chunk belongs to.\n\nAll chunks belonging to the same message share the same `messageId`.\nA change in `messageId` indicates a new message has started.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + Field(discriminator="type"), + ] + """ + A single item of content + """ + message_id: Annotated[Optional[str], Field(alias="messageId")] = None + """ + A unique identifier for the message this chunk belongs to. + + All chunks belonging to the same message share the same `messageId`. + A change in `messageId` indicates a new message has started. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("message_id", mode="wrap") @classmethod @@ -5062,50 +4297,44 @@ class PlanUpdateItems(PlanItems): class PlanUpdate(BaseModel): - # The updated plan content. plan: Annotated[ Union[PlanUpdateItems, PlanUpdateFile, PlanUpdateMarkdown], - Field(description="The updated plan content.", discriminator="type"), + Field(discriminator="type"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The updated plan content. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AvailableCommand(BaseModel): - # Command name (e.g., `create_plan`, `research_codebase`). - name: Annotated[ - str, - Field(description="Command name (e.g., `create_plan`, `research_codebase`)."), - ] - # Human-readable description of what the command does. - description: Annotated[str, Field(description="Human-readable description of what the command does.")] - # Input for the command if required - input: Annotated[ - Optional[AvailableCommandInput], - Field(description="Input for the command if required"), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + name: str + """ + Command name (e.g., `create_plan`, `research_codebase`). + """ + description: str + """ + Human-readable description of what the command does. + """ + input: Optional[AvailableCommandInput] = None + """ + Input for the command if required + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("input", mode="wrap") @classmethod @@ -5114,23 +4343,18 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class _AvailableCommandsUpdate(BaseModel): - # Commands the agent can execute - available_commands: Annotated[ - List[AvailableCommand], - Field(alias="availableCommands", description="Commands the agent can execute"), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + available_commands: Annotated[List[AvailableCommand], Field(alias="availableCommands")] + """ + Commands the agent can execute + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("available_commands", mode="wrap") @classmethod @@ -5139,29 +4363,21 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ClientSessionCapabilities(BaseModel): - # Config option capabilities supported by the client. - # - # Omitted or `null` both mean the client does not advertise support for any - # config option extensions. - config_options: Annotated[ - Optional[SessionConfigOptionsCapabilities], - Field( - alias="configOptions", - description="Config option capabilities supported by the client.\n\nOmitted or `null` both mean the client does not advertise support for any\nconfig option extensions.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + config_options: Annotated[Optional[SessionConfigOptionsCapabilities], Field(alias="configOptions")] = None + """ + Config option capabilities supported by the client. + + Omitted or `null` both mean the client does not advertise support for any + config option extensions. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("config_options", mode="wrap") @classmethod @@ -5170,43 +4386,33 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NewSessionRequest(BaseModel): - # The working directory for this session. Must be an absolute path. - cwd: Annotated[ - str, - Field(description="The working directory for this session. Must be an absolute path."), - ] - # Additional workspace roots for this session. Each path must be absolute. - # - # These expand the session's filesystem scope without changing `cwd`, which - # remains the base for relative paths. When omitted or empty, no - # additional roots are activated for the new session. - additional_directories: Annotated[ - Optional[List[str]], - Field( - alias="additionalDirectories", - description="Additional workspace roots for this session. Each path must be absolute.\n\nThese expand the session's filesystem scope without changing `cwd`, which\nremains the base for relative paths. When omitted or empty, no\nadditional roots are activated for the new session.", - ), - ] = None - # List of MCP (Model Context Protocol) servers the agent should connect to. + cwd: str + """ + The working directory for this session. Must be an absolute path. + """ + additional_directories: Annotated[Optional[List[str]], Field(alias="additionalDirectories")] = None + """ + Additional workspace roots for this session. Each path must be absolute. + + These expand the session's filesystem scope without changing `cwd`, which + remains the base for relative paths. When omitted or empty, no + additional roots are activated for the new session. + """ mcp_servers: Annotated[ List[Union[HttpMcpServer, SseMcpServer, AcpMcpServer, McpServerStdio]], - Field( - alias="mcpServers", - description="List of MCP (Model Context Protocol) servers the agent should connect to.", - ), + Field(alias="mcpServers"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + List of MCP (Model Context Protocol) servers the agent should connect to. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("additional_directories", mode="wrap") @classmethod @@ -5220,153 +4426,125 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class PromptRequest(BaseModel): - # The ID of the session to send this user message to - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session to send this user message to", - ), - ] - # The blocks of content that compose the user's message. - # - # As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], - # while other variants are optionally enabled via [`PromptCapabilities`]. - # - # The Client MUST adapt its interface according to [`PromptCapabilities`]. - # - # The client MAY include referenced pieces of context as either - # [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`]. - # - # When available, [`ContentBlock::Resource`] is preferred - # as it avoids extra round-trips and allows the message to include - # pieces of context from sources the agent may not have access to. - prompt: Annotated[ - List[ + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session to send this user message to + """ + prompt: List[ + Annotated[ Union[ TextContentBlock, ImageContentBlock, AudioContentBlock, ResourceContentBlock, EmbeddedResourceContentBlock, - ] - ], - Field( - description="The blocks of content that compose the user's message.\n\nAs a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`],\nwhile other variants are optionally enabled via [`PromptCapabilities`].\n\nThe Client MUST adapt its interface according to [`PromptCapabilities`].\n\nThe client MAY include referenced pieces of context as either\n[`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`].\n\nWhen available, [`ContentBlock::Resource`] is preferred\nas it avoids extra round-trips and allows the message to include\npieces of context from sources the agent may not have access to." - ), + ], + Field(discriminator="type"), + ] ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The blocks of content that compose the user's message. + + As a baseline, the Agent MUST support [`ContentBlock::Text`] and [`ContentBlock::ResourceLink`], + while other variants are optionally enabled via [`PromptCapabilities`]. + + The Client MUST adapt its interface according to [`PromptCapabilities`]. + + The client MAY include referenced pieces of context as either + [`ContentBlock::Resource`] or [`ContentBlock::ResourceLink`]. + + When available, [`ContentBlock::Resource`] is preferred + as it avoids extra round-trips and allows the message to include + pieces of context from sources the agent may not have access to. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class NesSuggestContext(BaseModel): - # Recently accessed files. - recent_files: Annotated[ - Optional[List[NesRecentFile]], - Field(alias="recentFiles", description="Recently accessed files."), - ] = None - # Related code snippets. - related_snippets: Annotated[ - Optional[List[NesRelatedSnippet]], - Field(alias="relatedSnippets", description="Related code snippets."), - ] = None - # Recent edit history. - edit_history: Annotated[ - Optional[List[NesEditHistoryEntry]], - Field(alias="editHistory", description="Recent edit history."), - ] = None - # Recent user actions (typing, navigation, etc.). - user_actions: Annotated[ - Optional[List[NesUserAction]], - Field( - alias="userActions", - description="Recent user actions (typing, navigation, etc.).", - ), - ] = None - # Currently open files in the editor. - open_files: Annotated[ - Optional[List[NesOpenFile]], - Field(alias="openFiles", description="Currently open files in the editor."), - ] = None - # Current diagnostics (errors, warnings). - diagnostics: Annotated[ - Optional[List[NesDiagnostic]], - Field(description="Current diagnostics (errors, warnings)."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + recent_files: Annotated[Optional[List[NesRecentFile]], Field(alias="recentFiles")] = None + """ + Recently accessed files. + """ + related_snippets: Annotated[Optional[List[NesRelatedSnippet]], Field(alias="relatedSnippets")] = None + """ + Related code snippets. + """ + edit_history: Annotated[Optional[List[NesEditHistoryEntry]], Field(alias="editHistory")] = None + """ + Recent edit history. + """ + user_actions: Annotated[Optional[List[NesUserAction]], Field(alias="userActions")] = None + """ + Recent user actions (typing, navigation, etc.). + """ + open_files: Annotated[Optional[List[NesOpenFile]], Field(alias="openFiles")] = None + """ + Currently open files in the editor. + """ + diagnostics: Optional[List[NesDiagnostic]] = None + """ + Current diagnostics (errors, warnings). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class RequestPermissionResponse(BaseModel): - # The user's decision on the permission request. outcome: Annotated[ Union[DeniedOutcome, AllowedOutcome], - Field( - description="The user's decision on the permission request.", - discriminator="outcome", - ), + Field(discriminator="outcome"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The user's decision on the permission request. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class DidChangeDocumentNotification(BaseModel): - # The session ID for this notification. - session_id: Annotated[ - str, - Field(alias="sessionId", description="The session ID for this notification."), - ] - # The URI of the changed document. - uri: Annotated[str, Field(description="The URI of the changed document.")] - # The new version number of the document. - version: Annotated[int, Field(description="The new version number of the document.")] - # The content changes. - content_changes: Annotated[ - List[TextDocumentContentChangeEvent], - Field(alias="contentChanges", description="The content changes."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this notification. + """ + uri: str + """ + The URI of the changed document. + """ + version: int + """ + The new version number of the document. + """ + content_changes: Annotated[List[TextDocumentContentChangeEvent], Field(alias="contentChanges")] + """ + The content changes. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("content_changes", mode="wrap") @classmethod @@ -5379,11 +4557,14 @@ class ContentToolCallContent(Content): class ElicitationSchema(BaseModel): - # Type discriminator. Always `"object"`. - type: Annotated[Optional[str], Field(description='Type discriminator. Always `"object"`.')] = "object" - # Optional title for the schema. - title: Annotated[Optional[str], Field(description="Optional title for the schema.")] = None - # Property definitions (must be primitive types). + type: Optional[str] = "object" + """ + Type discriminator. Always `"object"`. + """ + title: Optional[str] = None + """ + Optional title for the schema. + """ properties: Annotated[ Optional[ Dict[ @@ -5398,27 +4579,27 @@ class ElicitationSchema(BaseModel): ], ] ], - Field(description="Property definitions (must be primitive types)."), + Field(validate_default=True), ] = {} - # List of required property names. - required: Annotated[Optional[List[str]], Field(description="List of required property names.")] = None - # Optional description of what this schema represents. - description: Annotated[ - Optional[str], - Field(description="Optional description of what this schema represents."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + Property definitions (must be primitive types). + """ + required: Optional[List[str]] = None + """ + List of required property names. + """ + description: Optional[str] = None + """ + Optional description of what this schema represents. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("type", mode="wrap") @classmethod @@ -5432,59 +4613,45 @@ def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: class ElicitationFormSessionMode(ElicitationSessionScope): - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] + requested_schema: Annotated[ElicitationSchema, Field(alias="requestedSchema")] + """ + A JSON Schema describing the form fields to present to the user. + """ class ElicitationFormRequestMode(ElicitationRequestScope): - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] + requested_schema: Annotated[ElicitationSchema, Field(alias="requestedSchema")] + """ + A JSON Schema describing the form fields to present to the user. + """ class ElicitationFormMode(RootModel[Union[ElicitationFormSessionMode, ElicitationFormRequestMode]]): - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Form-based elicitation mode where the client renders a form from the provided schema. - root: Annotated[ - Union[ElicitationFormSessionMode, ElicitationFormRequestMode], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nForm-based elicitation mode where the client renders a form from the provided schema." - ), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: Union[ElicitationFormSessionMode, ElicitationFormRequestMode] + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Form-based elicitation mode where the client renders a form from the provided schema. + """ class NesEventCapabilities(BaseModel): - # Document event capabilities. - document: Annotated[ - Optional[NesDocumentEventCapabilities], - Field(description="Document event capabilities."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + document: Optional[NesDocumentEventCapabilities] = None + """ + Document event capabilities. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("document", mode="wrap") @classmethod @@ -5493,32 +4660,38 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class SessionConfigOptionSelect(SessionConfigSelect): - # Unique identifier for the configuration option. - id: Annotated[str, Field(description="Unique identifier for the configuration option.")] - # Human-readable label for the option. - name: Annotated[str, Field(description="Human-readable label for the option.")] - # Optional description for the Client to display to the user. - description: Annotated[ - Optional[str], - Field(description="Optional description for the Client to display to the user."), - ] = None - # Optional semantic category for this option (UX only). - category: Annotated[ - Optional[Union[str, Dict[str, Any]]], - Field(description="Optional semantic category for this option (UX only)."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + id: str + """ + Unique identifier for the configuration option. + """ + name: str + """ + Human-readable label for the option. + """ + description: Optional[str] = None + """ + Optional description for the Client to display to the user. + """ + category: Optional[ + Union[ + Literal["mode"], + Literal["model"], + Literal["model_config"], + Literal["thought_level"], + Dict[str, Any], + ] + ] = None + """ + Optional semantic category for this option (UX only). + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ type: Literal["select"] @field_validator("category", "description", mode="wrap") @@ -5528,35 +4701,34 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class LoadSessionResponse(BaseModel): - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None - # Initial session configuration options if supported by the Agent. + modes: Optional[SessionModeState] = None + """ + Initial mode state if supported by the Agent + + See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + """ config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Optional[ + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ] + ], + Field(alias="configOptions"), ] = None + """ + Initial session configuration options if supported by the Agent. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("modes", mode="wrap") @classmethod @@ -5570,43 +4742,38 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ForkSessionResponse(BaseModel): - # Unique identifier for the newly created forked session. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="Unique identifier for the newly created forked session.", - ), - ] - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None - # Initial session configuration options if supported by the Agent. + session_id: Annotated[str, Field(alias="sessionId")] + """ + Unique identifier for the newly created forked session. + """ + modes: Optional[SessionModeState] = None + """ + Initial mode state if supported by the Agent + + See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + """ config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Optional[ + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ] + ], + Field(alias="configOptions"), ] = None + """ + Initial session configuration options if supported by the Agent. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("modes", mode="wrap") @classmethod @@ -5620,35 +4787,34 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ResumeSessionResponse(BaseModel): - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None - # Initial session configuration options if supported by the Agent. + modes: Optional[SessionModeState] = None + """ + Initial mode state if supported by the Agent + + See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + """ config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Optional[ + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ] + ], + Field(alias="configOptions"), ] = None + """ + Initial session configuration options if supported by the Agent. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("modes", mode="wrap") @classmethod @@ -5662,26 +4828,26 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class SetSessionConfigOptionResponse(BaseModel): - # The full set of configuration options and their current values. config_options: Annotated[ - List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], - Field( - alias="configOptions", - description="The full set of configuration options and their current values.", - ), + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ], + Field(alias="configOptions"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The full set of configuration options and their current values. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("config_options", mode="wrap") @classmethod @@ -5714,62 +4880,55 @@ class AvailableCommandsUpdate(_AvailableCommandsUpdate): class ToolCall(BaseModel): - # Unique identifier for this tool call within the session. - tool_call_id: Annotated[ - str, - Field( - alias="toolCallId", - description="Unique identifier for this tool call within the session.", - ), - ] - # Human-readable title describing what the tool is doing. - title: Annotated[ - str, - Field(description="Human-readable title describing what the tool is doing."), - ] - # The category of tool being invoked. - # Helps clients choose appropriate icons and UI treatment. - kind: Annotated[ - Optional[ToolKind], - Field( - description="The category of tool being invoked.\nHelps clients choose appropriate icons and UI treatment." - ), - ] = None - # Current execution status of the tool call. - status: Annotated[Optional[ToolCallStatus], Field(description="Current execution status of the tool call.")] = None - # Content produced by the tool call. - content: Annotated[ - Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], - Field(description="Content produced by the tool call."), - ] = None - # File locations affected by this tool call. - # Enables "follow-along" features in clients. - locations: Annotated[ - Optional[List[ToolCallLocation]], - Field(description='File locations affected by this tool call.\nEnables "follow-along" features in clients.'), - ] = None - # Raw input parameters sent to the tool. - raw_input: Annotated[ - Optional[Any], - Field(alias="rawInput", description="Raw input parameters sent to the tool."), - ] = None - # Raw output returned by the tool. - raw_output: Annotated[ - Optional[Any], - Field(alias="rawOutput", description="Raw output returned by the tool."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + tool_call_id: Annotated[str, Field(alias="toolCallId")] + """ + Unique identifier for this tool call within the session. + """ + title: str + """ + Human-readable title describing what the tool is doing. + """ + kind: Optional[ToolKind] = None + """ + The category of tool being invoked. + Helps clients choose appropriate icons and UI treatment. + """ + status: Optional[ToolCallStatus] = None + """ + Current execution status of the tool call. + """ + content: Optional[ + List[ + Annotated[ + Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent], + Field(discriminator="type"), + ] + ] + ] = None + """ + Content produced by the tool call. + """ + locations: Optional[List[ToolCallLocation]] = None + """ + File locations affected by this tool call. + Enables "follow-along" features in clients. + """ + raw_input: Annotated[Optional[Any], Field(alias="rawInput")] = None + """ + Raw input parameters sent to the tool. + """ + raw_output: Annotated[Optional[Any], Field(alias="rawOutput")] = None + """ + Raw output returned by the tool. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("kind", "raw_input", "raw_output", "status", mode="wrap") @classmethod @@ -5788,26 +4947,26 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class _ConfigOptionUpdate(BaseModel): - # The full set of configuration options and their current values. config_options: Annotated[ - List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]], - Field( - alias="configOptions", - description="The full set of configuration options and their current values.", - ), + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ], + Field(alias="configOptions"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The full set of configuration options and their current values. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("config_options", mode="wrap") @classmethod @@ -5816,109 +4975,82 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class ClientCapabilities(BaseModel): - # File system capabilities supported by the client. - # Determines which file operations the agent can request. - fs: Annotated[ - Optional[FileSystemCapabilities], - Field( - description="File system capabilities supported by the client.\nDetermines which file operations the agent can request." - ), - ] = FileSystemCapabilities() - # Whether the Client support all `terminal/*` methods. - terminal: Annotated[ - Optional[bool], - Field(description="Whether the Client support all `terminal/*` methods."), - ] = False - # Session-related capabilities supported by the client. - # - # Optional. Omitted or `null` both mean the client does not advertise any - # session-related extensions. - session: Annotated[ - Optional[ClientSessionCapabilities], - Field( - description="Session-related capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nsession-related extensions." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Whether the client supports `plan_update` and `plan_removed` session updates. - # - # Optional. Omitted or `null` both mean the client does not advertise support. - # Supplying `{}` means the client can receive both update types. - plan: Annotated[ - Optional[PlanCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nWhether the client supports `plan_update` and `plan_removed` session updates.\n\nOptional. Omitted or `null` both mean the client does not advertise support.\nSupplying `{}` means the client can receive both update types." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Authentication capabilities supported by the client. - # Determines which authentication method types the agent may include - # in its `InitializeResponse`. - auth: Annotated[ - Optional[AuthCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nAuthentication capabilities supported by the client.\nDetermines which authentication method types the agent may include\nin its `InitializeResponse`." - ), - ] = {"terminal": False} - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Elicitation capabilities supported by the client. - # Determines which elicitation modes the agent may use. - # - # Optional. Omitted or `null` both mean the client does not advertise - # elicitation support. - elicitation: Annotated[ - Optional[ElicitationCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nElicitation capabilities supported by the client.\nDetermines which elicitation modes the agent may use.\n\nOptional. Omitted or `null` both mean the client does not advertise\nelicitation support." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # NES (Next Edit Suggestions) capabilities supported by the client. - # - # Optional. Omitted or `null` both mean the client does not advertise any - # NES suggestion-kind extensions. - nes: Annotated[ - Optional[ClientNesCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the client.\n\nOptional. Omitted or `null` both mean the client does not advertise any\nNES suggestion-kind extensions." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # The position encodings supported by the client, in order of preference. - position_encodings: Annotated[ - Optional[List[str]], - Field( - alias="positionEncodings", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encodings supported by the client, in order of preference.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + fs: Annotated[Optional[FileSystemCapabilities], Field(validate_default=True)] = FileSystemCapabilities() + """ + File system capabilities supported by the client. + Determines which file operations the agent can request. + """ + terminal: Optional[bool] = False + """ + Whether the Client support all `terminal/*` methods. + """ + session: Optional[ClientSessionCapabilities] = None + """ + Session-related capabilities supported by the client. + + Optional. Omitted or `null` both mean the client does not advertise any + session-related extensions. + """ + plan: Optional[PlanCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Whether the client supports `plan_update` and `plan_removed` session updates. + + Optional. Omitted or `null` both mean the client does not advertise support. + Supplying `{}` means the client can receive both update types. + """ + auth: Annotated[Optional[AuthCapabilities], Field(validate_default=True)] = {"terminal": False} + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Authentication capabilities supported by the client. + Determines which authentication method types the agent may include + in its `InitializeResponse`. + """ + elicitation: Optional[ElicitationCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Elicitation capabilities supported by the client. + Determines which elicitation modes the agent may use. + + Optional. Omitted or `null` both mean the client does not advertise + elicitation support. + """ + nes: Optional[ClientNesCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + NES (Next Edit Suggestions) capabilities supported by the client. + + Optional. Omitted or `null` both mean the client does not advertise any + NES suggestion-kind extensions. + """ + position_encodings: Annotated[Optional[List[str]], Field(alias="positionEncodings")] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + The position encodings supported by the client, in order of preference. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("terminal", mode="wrap") @classmethod @@ -5947,140 +5079,154 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class SuggestNesRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # The URI of the document to suggest for. - uri: Annotated[str, Field(description="The URI of the document to suggest for.")] - # The version number of the document. - version: Annotated[int, Field(description="The version number of the document.")] - # The current cursor position. - position: Annotated[Position, Field(description="The current cursor position.")] - # The current text selection range, if any. - selection: Annotated[Optional[Range], Field(description="The current text selection range, if any.")] = None - # What triggered this suggestion request. - trigger_kind: Annotated[ - str, - Field(alias="triggerKind", description="What triggered this suggestion request."), - ] - # Context for the suggestion, included based on agent capabilities. - context: Annotated[ - Optional[NesSuggestContext], - Field(description="Context for the suggestion, included based on agent capabilities."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + uri: str + """ + The URI of the document to suggest for. + """ + version: int + """ + The version number of the document. + """ + position: Position + """ + The current cursor position. + """ + selection: Optional[Range] = None + """ + The current text selection range, if any. + """ + trigger_kind: Annotated[str, Field(alias="triggerKind")] + """ + What triggered this suggestion request. + """ + context: Optional[NesSuggestContext] = None + """ + Context for the suggestion, included based on agent capabilities. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ClientResponseMessage(BaseModel): - # The id of the request this response answers. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The id of the request this response answers."), - ] = None - # Method-specific response data. - result: Annotated[ + id: Optional[Union[int, str]] + """ + The id of the request this response answers. + """ + result: Union[ + WriteTextFileResponse, + ReadTextFileResponse, + RequestPermissionResponse, + CreateTerminalResponse, + TerminalOutputResponse, + ReleaseTerminalResponse, + WaitForTerminalExitResponse, + KillTerminalResponse, + ConnectMcpResponse, + DisconnectMcpResponse, Union[ - WriteTextFileResponse, - ReadTextFileResponse, - RequestPermissionResponse, - CreateTerminalResponse, - TerminalOutputResponse, - ReleaseTerminalResponse, - WaitForTerminalExitResponse, - KillTerminalResponse, - ConnectMcpResponse, - DisconnectMcpResponse, - Union[ - AcceptElicitationResponse, - DeclineElicitationResponse, - CancelElicitationResponse, - OtherElicitationResponse, - ], - Any, + AcceptElicitationResponse, + DeclineElicitationResponse, + CancelElicitationResponse, + OtherElicitationResponse, ], - Field(description="Method-specific response data."), + Any, ] + """ + Method-specific response data. + """ class ClientResponse(RootModel[Union[ClientResponseMessage, ClientErrorMessage]]): - # A JSON-RPC response object. - root: Annotated[ - Union[ClientResponseMessage, ClientErrorMessage], - Field(description="A JSON-RPC response object."), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: Union[ClientResponseMessage, ClientErrorMessage] + """ + A JSON-RPC response object. + """ class ClientNotification(BaseModel): - # The notification method name. - method: Annotated[str, Field(description="The notification method name.")] - # Method-specific notification parameters. - params: Annotated[ - Optional[ - Union[ - CancelNotification, - DidOpenDocumentNotification, - DidChangeDocumentNotification, - DidCloseDocumentNotification, - DidSaveDocumentNotification, - DidFocusDocumentNotification, - AcceptNesNotification, - RejectNesNotification, - MessageMcpNotification, - Any, - ] - ], - Field(description="Method-specific notification parameters."), + method: str + """ + The notification method name. + """ + params: Optional[ + Union[ + CancelNotification, + DidOpenDocumentNotification, + DidChangeDocumentNotification, + DidCloseDocumentNotification, + DidSaveDocumentNotification, + DidFocusDocumentNotification, + AcceptNesNotification, + RejectNesNotification, + MessageMcpNotification, + Any, + ] ] = None + """ + Method-specific notification parameters. + """ class ToolCallUpdate(BaseModel): - # The ID of the tool call being updated. - tool_call_id: Annotated[ - str, - Field(alias="toolCallId", description="The ID of the tool call being updated."), - ] - # Update the tool kind. - kind: Annotated[Optional[ToolKind], Field(description="Update the tool kind.")] = None - # Update the execution status. - status: Annotated[Optional[ToolCallStatus], Field(description="Update the execution status.")] = None - # Update the human-readable title. - title: Annotated[Optional[str], Field(description="Update the human-readable title.")] = None - # Replace the content collection. - content: Annotated[ - Optional[List[Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent]]], - Field(description="Replace the content collection."), - ] = None - # Replace the locations collection. - locations: Annotated[ - Optional[List[ToolCallLocation]], - Field(description="Replace the locations collection."), - ] = None - # Update the raw input. - raw_input: Annotated[Optional[Any], Field(alias="rawInput", description="Update the raw input.")] = None - # Update the raw output. - raw_output: Annotated[Optional[Any], Field(alias="rawOutput", description="Update the raw output.")] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + tool_call_id: Annotated[str, Field(alias="toolCallId")] + """ + The ID of the tool call being updated. + """ + kind: Optional[ToolKind] = None + """ + Update the tool kind. + """ + status: Optional[ToolCallStatus] = None + """ + Update the execution status. + """ + title: Optional[str] = None + """ + Update the human-readable title. + """ + content: Optional[ + List[ + Annotated[ + Union[ContentToolCallContent, FileEditToolCallContent, TerminalToolCallContent], + Field(discriminator="type"), + ] + ] + ] = None + """ + Replace the content collection. + """ + locations: Optional[List[ToolCallLocation]] = None + """ + Replace the locations collection. + """ + raw_input: Annotated[Optional[Any], Field(alias="rawInput")] = None + """ + Update the raw input. + """ + raw_output: Annotated[Optional[Any], Field(alias="rawOutput")] = None + """ + Update the raw output. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("kind", "raw_input", "raw_output", "status", "title", mode="wrap") @classmethod @@ -6099,61 +5245,43 @@ def _skip_invalid_items_1(cls, value: Any, handler: Any) -> Any: class CreateFormSessionElicitationRequest(ElicitationSessionScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + message: str + """ + A human-readable message describing what input is needed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ mode: Literal["form"] - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] + requested_schema: Annotated[ElicitationSchema, Field(alias="requestedSchema")] + """ + A JSON Schema describing the form fields to present to the user. + """ class CreateFormRequestElicitationRequest(ElicitationRequestScope): - # A human-readable message describing what input is needed. - message: Annotated[ - str, - Field(description="A human-readable message describing what input is needed."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + message: str + """ + A human-readable message describing what input is needed. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ mode: Literal["form"] - # A JSON Schema describing the form fields to present to the user. - requested_schema: Annotated[ - ElicitationSchema, - Field( - alias="requestedSchema", - description="A JSON Schema describing the form fields to present to the user.", - ), - ] + requested_schema: Annotated[ElicitationSchema, Field(alias="requestedSchema")] + """ + A JSON Schema describing the form fields to present to the user. + """ ElicitationMode = Union[ @@ -6184,28 +5312,22 @@ class CreateFormRequestElicitationRequest(ElicitationRequestScope): class NesCapabilities(BaseModel): - # Events the agent wants to receive. - events: Annotated[ - Optional[NesEventCapabilities], - Field(description="Events the agent wants to receive."), - ] = None - # Context the agent wants attached to each suggestion request. - context: Annotated[ - Optional[NesContextCapabilities], - Field(description="Context the agent wants attached to each suggestion request."), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + events: Optional[NesEventCapabilities] = None + """ + Events the agent wants to receive. + """ + context: Optional[NesContextCapabilities] = None + """ + Context the agent wants attached to each suggestion request. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("context", "events", mode="wrap") @classmethod @@ -6214,45 +5336,40 @@ def _salvage_on_error_0(cls, value: Any, handler: Any) -> Any: class NewSessionResponse(BaseModel): - # Unique identifier for the created session. - # - # Used in all subsequent requests for this conversation. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation.", - ), - ] - # Initial mode state if supported by the Agent - # - # See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) - modes: Annotated[ - Optional[SessionModeState], - Field( - description="Initial mode state if supported by the Agent\n\nSee protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)" - ), - ] = None - # Initial session configuration options if supported by the Agent. + session_id: Annotated[str, Field(alias="sessionId")] + """ + Unique identifier for the created session. + + Used in all subsequent requests for this conversation. + """ + modes: Optional[SessionModeState] = None + """ + Initial mode state if supported by the Agent + + See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + """ config_options: Annotated[ - Optional[List[Union[SessionConfigOptionSelect, SessionConfigOptionBoolean]]], - Field( - alias="configOptions", - description="Initial session configuration options if supported by the Agent.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), + Optional[ + List[ + Annotated[ + Union[SessionConfigOptionSelect, SessionConfigOptionBoolean], + Field(discriminator="type"), + ] + ] + ], + Field(alias="configOptions"), ] = None + """ + Initial session configuration options if supported by the Agent. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("modes", mode="wrap") @classmethod @@ -6266,30 +5383,28 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class SuggestNesResponse(BaseModel): - # The list of suggestions. - suggestions: Annotated[ - List[ + suggestions: List[ + Annotated[ Union[ NesEditSuggestionVariant, NesJumpSuggestionVariant, NesRenameSuggestionVariant, NesSearchAndReplaceSuggestionVariant, - ] - ], - Field(description="The list of suggestions."), + ], + Field(discriminator="kind"), + ] ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The list of suggestions. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ToolCallStart(ToolCall): @@ -6305,46 +5420,31 @@ class ConfigOptionUpdate(_ConfigOptionUpdate): class InitializeRequest(BaseModel): - # The latest protocol version supported by the client. - protocol_version: Annotated[ - int, - Field( - alias="protocolVersion", - description="The latest protocol version supported by the client.", - ge=0, - le=65535, - ), - ] - # Capabilities supported by the client. + protocol_version: Annotated[int, Field(alias="protocolVersion", ge=0, le=65535)] + """ + The latest protocol version supported by the client. + """ client_capabilities: Annotated[ Optional[ClientCapabilities], - Field( - alias="clientCapabilities", - description="Capabilities supported by the client.", - ), + Field(alias="clientCapabilities", validate_default=True), ] = ClientCapabilities() - # Information about the Client name and version sent to the Agent. - # - # Note: in future versions of the protocol, this will be required. - client_info: Annotated[ - Optional[Implementation], - Field( - alias="clientInfo", - description="Information about the Client name and version sent to the Agent.\n\nNote: in future versions of the protocol, this will be required.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + Capabilities supported by the client. + """ + client_info: Annotated[Optional[Implementation], Field(alias="clientInfo")] = None + """ + Information about the Client name and version sent to the Agent. + + Note: in future versions of the protocol, this will be required. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("protocol_version", mode="before") @classmethod @@ -6380,125 +5480,95 @@ def _salvage_on_error_1(cls, value: Any, handler: Any) -> Any: class RequestPermissionRequest(BaseModel): - # The session ID for this request. - session_id: Annotated[str, Field(alias="sessionId", description="The session ID for this request.")] - # Details about the tool call requiring permission. - tool_call: Annotated[ - ToolCallUpdate, - Field( - alias="toolCall", - description="Details about the tool call requiring permission.", - ), - ] - # Available permission options for the user to choose from. - options: Annotated[ - List[PermissionOption], - Field(description="Available permission options for the user to choose from."), - ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + session_id: Annotated[str, Field(alias="sessionId")] + """ + The session ID for this request. + """ + tool_call: Annotated[ToolCallUpdate, Field(alias="toolCall")] + """ + Details about the tool call requiring permission. + """ + options: List[PermissionOption] + """ + Available permission options for the user to choose from. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class AgentCapabilities(BaseModel): - # Whether the agent supports `session/load`. - load_session: Annotated[ - Optional[bool], - Field( - alias="loadSession", - description="Whether the agent supports `session/load`.", - ), - ] = False - # Prompt capabilities supported by the agent. + load_session: Annotated[Optional[bool], Field(alias="loadSession")] = False + """ + Whether the agent supports `session/load`. + """ prompt_capabilities: Annotated[ Optional[PromptCapabilities], - Field( - alias="promptCapabilities", - description="Prompt capabilities supported by the agent.", - ), + Field(alias="promptCapabilities", validate_default=True), ] = PromptCapabilities() - # MCP capabilities supported by the agent. - mcp_capabilities: Annotated[ - Optional[McpCapabilities], - Field( - alias="mcpCapabilities", - description="MCP capabilities supported by the agent.", - ), - ] = McpCapabilities() - # Session lifecycle and prompt capabilities advertised by the agent. + """ + Prompt capabilities supported by the agent. + """ + mcp_capabilities: Annotated[Optional[McpCapabilities], Field(alias="mcpCapabilities", validate_default=True)] = ( + McpCapabilities() + ) + """ + MCP capabilities supported by the agent. + """ session_capabilities: Annotated[ Optional[SessionCapabilities], - Field( - alias="sessionCapabilities", - description="Session lifecycle and prompt capabilities advertised by the agent.", - ), + Field(alias="sessionCapabilities", validate_default=True), ] = SessionCapabilities() - # Authentication-related capabilities supported by the agent. - auth: Annotated[ - Optional[AgentAuthCapabilities], - Field(description="Authentication-related capabilities supported by the agent."), - ] = {} - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # Provider configuration capabilities supported by the agent. - # - # Optional. Omitted or `null` both mean the agent does not advertise support. - # Supplying `{}` means the agent supports provider configuration methods. - providers: Annotated[ - Optional[ProvidersCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nProvider configuration capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support.\nSupplying `{}` means the agent supports provider configuration methods." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # NES (Next Edit Suggestions) capabilities supported by the agent. - # - # Optional. Omitted or `null` both mean the agent does not advertise support - # for NES methods. - nes: Annotated[ - Optional[NesCapabilities], - Field( - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nNES (Next Edit Suggestions) capabilities supported by the agent.\n\nOptional. Omitted or `null` both mean the agent does not advertise support\nfor NES methods." - ), - ] = None - # **UNSTABLE** - # - # This capability is not part of the spec yet, and may be removed or changed at any point. - # - # The position encoding selected by the agent from the client's supported encodings. - position_encoding: Annotated[ - Optional[str], - Field( - alias="positionEncoding", - description="**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nThe position encoding selected by the agent from the client's supported encodings.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + Session lifecycle and prompt capabilities advertised by the agent. + """ + auth: Annotated[Optional[AgentAuthCapabilities], Field(validate_default=True)] = {} + """ + Authentication-related capabilities supported by the agent. + """ + providers: Optional[ProvidersCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + Provider configuration capabilities supported by the agent. + + Optional. Omitted or `null` both mean the agent does not advertise support. + Supplying `{}` means the agent supports provider configuration methods. + """ + nes: Optional[NesCapabilities] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + NES (Next Edit Suggestions) capabilities supported by the agent. + + Optional. Omitted or `null` both mean the agent does not advertise support + for NES methods. + """ + position_encoding: Annotated[Optional[str], Field(alias="positionEncoding")] = None + """ + **UNSTABLE** + + This capability is not part of the spec yet, and may be removed or changed at any point. + + The position encoding selected by the agent from the client's supported encodings. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("load_session", mode="wrap") @classmethod @@ -6527,15 +5597,10 @@ def _salvage_on_error_4(cls, value: Any, handler: Any) -> Any: class SessionNotification(BaseModel): - # The ID of the session this update pertains to. - session_id: Annotated[ - str, - Field( - alias="sessionId", - description="The ID of the session this update pertains to.", - ), - ] - # The actual update content. + session_id: Annotated[str, Field(alias="sessionId")] + """ + The ID of the session this update pertains to. + """ update: Annotated[ Union[ UserMessageChunk, @@ -6552,150 +5617,133 @@ class SessionNotification(BaseModel): SessionInfoUpdate, UsageUpdate, ], - Field(description="The actual update content.", discriminator="session_update"), + Field(discriminator="session_update"), ] - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + The actual update content. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ class ClientRequest(BaseModel): - # The request id used to correlate the matching response. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The request id used to correlate the matching response."), - ] - # The method name to invoke. - method: Annotated[str, Field(description="The method name to invoke.")] - # Method-specific request parameters. - params: Annotated[ - Optional[ - Union[ - InitializeRequest, - AuthenticateRequest, - ListProvidersRequest, - SetProviderRequest, - DisableProviderRequest, - LogoutRequest, - NewSessionRequest, - LoadSessionRequest, - ListSessionsRequest, - DeleteSessionRequest, - ForkSessionRequest, - ResumeSessionRequest, - CloseSessionRequest, - SetSessionModeRequest, - PromptRequest, - StartNesRequest, - SuggestNesRequest, - CloseNesRequest, - MessageMcpRequest, - Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], - Any, - ] - ], - Field(description="Method-specific request parameters."), + id: Optional[Union[int, str]] + """ + The request id used to correlate the matching response. + """ + method: str + """ + The method name to invoke. + """ + params: Optional[ + Union[ + InitializeRequest, + AuthenticateRequest, + ListProvidersRequest, + SetProviderRequest, + DisableProviderRequest, + LogoutRequest, + NewSessionRequest, + LoadSessionRequest, + ListSessionsRequest, + DeleteSessionRequest, + ForkSessionRequest, + ResumeSessionRequest, + CloseSessionRequest, + SetSessionModeRequest, + PromptRequest, + StartNesRequest, + SuggestNesRequest, + CloseNesRequest, + MessageMcpRequest, + Union[SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionSelectRequest], + Any, + ] ] = None + """ + Method-specific request parameters. + """ class AgentRequest(BaseModel): - # The request id used to correlate the matching response. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The request id used to correlate the matching response."), - ] - # The method name to invoke. - method: Annotated[str, Field(description="The method name to invoke.")] - # Method-specific request parameters. - params: Annotated[ - Optional[ + id: Optional[Union[int, str]] + """ + The request id used to correlate the matching response. + """ + method: str + """ + The method name to invoke. + """ + params: Optional[ + Union[ + WriteTextFileRequest, + ReadTextFileRequest, + RequestPermissionRequest, + CreateTerminalRequest, + TerminalOutputRequest, + ReleaseTerminalRequest, + WaitForTerminalExitRequest, + KillTerminalRequest, + ConnectMcpRequest, + MessageMcpRequest, + DisconnectMcpRequest, Union[ - WriteTextFileRequest, - ReadTextFileRequest, - RequestPermissionRequest, - CreateTerminalRequest, - TerminalOutputRequest, - ReleaseTerminalRequest, - WaitForTerminalExitRequest, - KillTerminalRequest, - ConnectMcpRequest, - MessageMcpRequest, - DisconnectMcpRequest, - Union[ - CreateFormSessionElicitationRequest, - CreateFormRequestElicitationRequest, - CreateUrlSessionElicitationRequest, - CreateUrlRequestElicitationRequest, - CreateOtherElicitationRequest, - ], - Any, - ] - ], - Field(description="Method-specific request parameters."), + CreateFormSessionElicitationRequest, + CreateFormRequestElicitationRequest, + CreateUrlSessionElicitationRequest, + CreateUrlRequestElicitationRequest, + CreateOtherElicitationRequest, + ], + Any, + ] ] = None + """ + Method-specific request parameters. + """ class InitializeResponse(BaseModel): - # The protocol version the client specified if supported by the agent, - # or the latest protocol version supported by the agent. - # - # The client should disconnect, if it doesn't support this version. - protocol_version: Annotated[ - int, - Field( - alias="protocolVersion", - description="The protocol version the client specified if supported by the agent,\nor the latest protocol version supported by the agent.\n\nThe client should disconnect, if it doesn't support this version.", - ge=0, - le=65535, - ), - ] - # Capabilities supported by the agent. + protocol_version: Annotated[int, Field(alias="protocolVersion", ge=0, le=65535)] + """ + The protocol version the client specified if supported by the agent, + or the latest protocol version supported by the agent. + + The client should disconnect, if it doesn't support this version. + """ agent_capabilities: Annotated[ Optional[AgentCapabilities], - Field( - alias="agentCapabilities", - description="Capabilities supported by the agent.", - ), + Field(alias="agentCapabilities", validate_default=True), ] = AgentCapabilities() - # Authentication methods supported by the agent. + """ + Capabilities supported by the agent. + """ auth_methods: Annotated[ Optional[List[Union[EnvVarAuthMethod, TerminalAuthMethod, AuthMethodAgent]]], - Field( - alias="authMethods", - description="Authentication methods supported by the agent.", - ), + Field(alias="authMethods", validate_default=True), ] = [] - # Information about the Agent name and version sent to the Client. - # - # Note: in future versions of the protocol, this will be required. - agent_info: Annotated[ - Optional[Implementation], - Field( - alias="agentInfo", - description="Information about the Agent name and version sent to the Client.\n\nNote: in future versions of the protocol, this will be required.", - ), - ] = None - # The _meta property is reserved by ACP to allow clients and agents to attach additional - # metadata to their interactions. Implementations MUST NOT make assumptions about values at - # these keys. - # - # See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - field_meta: Annotated[ - Optional[Dict[str, Any]], - Field( - alias="_meta", - description="The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)", - ), - ] = None + """ + Authentication methods supported by the agent. + """ + agent_info: Annotated[Optional[Implementation], Field(alias="agentInfo")] = None + """ + Information about the Agent name and version sent to the Client. + + Note: in future versions of the protocol, this will be required. + """ + field_meta: Annotated[Optional[Dict[str, Any]], Field(alias="_meta")] = None + """ + The _meta property is reserved by ACP to allow clients and agents to attach additional + metadata to their interactions. Implementations MUST NOT make assumptions about values at + these keys. + + See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + """ @field_validator("agent_info", mode="wrap") @classmethod @@ -6724,59 +5772,59 @@ def _skip_invalid_items_0(cls, value: Any, handler: Any) -> Any: class AgentNotification(BaseModel): - # The notification method name. - method: Annotated[str, Field(description="The notification method name.")] - # Method-specific notification parameters. - params: Annotated[ - Optional[ - Union[ - SessionNotification, - CompleteElicitationNotification, - MessageMcpNotification, - Any, - ] - ], - Field(description="Method-specific notification parameters."), + method: str + """ + The notification method name. + """ + params: Optional[ + Union[ + SessionNotification, + CompleteElicitationNotification, + MessageMcpNotification, + Any, + ] ] = None + """ + Method-specific notification parameters. + """ class AgentResponseMessage(BaseModel): - # The id of the request this response answers. - id: Annotated[ - Optional[Union[int, str]], - Field(description="The id of the request this response answers."), - ] = None - # Method-specific response data. - result: Annotated[ - Union[ - InitializeResponse, - AuthenticateResponse, - ListProvidersResponse, - SetProviderResponse, - DisableProviderResponse, - LogoutResponse, - NewSessionResponse, - LoadSessionResponse, - ListSessionsResponse, - DeleteSessionResponse, - ForkSessionResponse, - ResumeSessionResponse, - CloseSessionResponse, - SetSessionModeResponse, - SetSessionConfigOptionResponse, - PromptResponse, - StartNesResponse, - SuggestNesResponse, - CloseNesResponse, - Any, - ], - Field(description="Method-specific response data."), - ] + id: Optional[Union[int, str]] + """ + The id of the request this response answers. + """ + result: Union[ + InitializeResponse, + AuthenticateResponse, + ListProvidersResponse, + SetProviderResponse, + DisableProviderResponse, + LogoutResponse, + NewSessionResponse, + LoadSessionResponse, + ListSessionsResponse, + DeleteSessionResponse, + ForkSessionResponse, + ResumeSessionResponse, + CloseSessionResponse, + SetSessionModeResponse, + SetSessionConfigOptionResponse, + PromptResponse, + StartNesResponse, + SuggestNesResponse, + CloseNesResponse, + Any, + ] + """ + Method-specific response data. + """ class AgentResponse(RootModel[Union[AgentResponseMessage, AgentErrorMessage]]): - # A JSON-RPC response object. - root: Annotated[ - Union[AgentResponseMessage, AgentErrorMessage], - Field(description="A JSON-RPC response object."), - ] + model_config = ConfigDict(use_attribute_docstrings=True) + + root: Union[AgentResponseMessage, AgentErrorMessage] + """ + A JSON-RPC response object. + """ diff --git a/tests/test_gen_all.py b/tests/test_gen_all.py index da9f73d..57a4be9 100644 --- a/tests/test_gen_all.py +++ b/tests/test_gen_all.py @@ -1,3 +1,4 @@ +from acp.schema import AvailableCommandInput, ReadTextFileRequest from scripts.gen_all import resolve_ref, schema_source_paths from scripts.gen_schema import ( _deserialize_field_specs, @@ -9,6 +10,16 @@ ) +def test_generated_field_descriptions_are_introspectable() -> None: + path_description = "Absolute path to the file to read." + assert ReadTextFileRequest.model_fields["path"].description == path_description + assert ReadTextFileRequest.model_json_schema()["properties"]["path"]["description"] == path_description + + root_description = "The input specification for a command." + assert AvailableCommandInput.model_fields["root"].description == root_description + assert AvailableCommandInput.model_json_schema()["description"] == root_description + + def test_resolve_ref_accepts_schema_release_tags() -> None: assert resolve_ref("schema-v1.16.0") == "refs/tags/schema-v1.16.0" diff --git a/uv.lock b/uv.lock index fca93fb..ea2d55d 100644 --- a/uv.lock +++ b/uv.lock @@ -55,7 +55,7 @@ provides-extras = ["logfire", "http"] [package.metadata.requires-dev] dev = [ - { name = "datamodel-code-generator", specifier = ">=0.25" }, + { name = "datamodel-code-generator", specifier = ">=0.71.0" }, { name = "deptry", specifier = ">=0.23.0" }, { name = "httpx", extras = ["http2"], specifier = ">=0.27" }, { name = "mkdocs", specifier = ">=1.4.2" }, @@ -319,7 +319,7 @@ wheels = [ [[package]] name = "datamodel-code-generator" -version = "0.64.0" +version = "0.71.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, @@ -332,9 +332,9 @@ dependencies = [ { name = "pyyaml" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/d2/86c94a2836ed42231653a7ddaefa0a5bc23418167a876bba7376c96b3a35/datamodel_code_generator-0.64.0.tar.gz", hash = "sha256:9c592900a00b20e416494273c22435f5a9aef6ea8c7b9190747522a60497a1cb", size = 1316440, upload-time = "2026-06-14T17:24:50.528Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/f5/f4ce23d99503b147c9ec514dc995a96d3b4d2a3284252ad665f875a3145d/datamodel_code_generator-0.71.0.tar.gz", hash = "sha256:d27cd7a0d10f9b2db74a41db7f3e050c226da9cf0afb4916a7ab56275ebacbf2", size = 1684916, upload-time = "2026-07-24T15:32:04.334Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/23/94/71338e2f0146ac10747a5537b3a1e45256e66b7c229869eb0ee787111b41/datamodel_code_generator-0.64.0-py3-none-any.whl", hash = "sha256:b7cd8bd41a312aa997aec6150670bad781847c5b674f17e4d70e78208a0fb990", size = 374698, upload-time = "2026-06-14T17:24:48.809Z" }, + { url = "https://files.pythonhosted.org/packages/c6/4d/556cb290170f41b97ce50fd872e10a266f141d7a38352bb3071e4ae61f41/datamodel_code_generator-0.71.0-py3-none-any.whl", hash = "sha256:680b68338d59e98a0559eeb54d8e5ca33c35b3ec0bef922ec2cc783f2cb28e9a", size = 452379, upload-time = "2026-07-24T15:32:02.467Z" }, ] [[package]] From 082c8f09ccf1c7c235890db2da954aba0b25b4d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Aug 2026 01:51:33 +0800 Subject: [PATCH 48/52] chore(deps): bump h2 in the uv group across 1 directory (#131) Bumps the uv group with 1 update in the / directory: [h2](https://github.com/python-hyper/h2). Updates `h2` from 4.3.0 to 4.4.1 - [Changelog](https://github.com/python-hyper/h2/blob/master/CHANGELOG.rst) - [Commits](https://github.com/python-hyper/h2/compare/v4.3.0...v4.4.1) --- updated-dependencies: - dependency-name: h2 dependency-version: 4.4.1 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/uv.lock b/uv.lock index ea2d55d..54fd84f 100644 --- a/uv.lock +++ b/uv.lock @@ -381,7 +381,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ @@ -462,15 +462,15 @@ wheels = [ [[package]] name = "h2" -version = "4.3.0" +version = "4.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hpack" }, { name = "hyperframe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/85/7c366e69d84c17bb778fe41419e1fbcce3033d5b7ce29bbffff0a98b859f/h2-4.4.1.tar.gz", hash = "sha256:4e866ffb1a869ae14dd9b5e6beb5c24a13da0495ad72b65925ded182521c1516", size = 2157281, upload-time = "2026-08-03T11:45:09.509Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, + { url = "https://files.pythonhosted.org/packages/7e/22/e85faf23bd72a92d1921e37d674ca56eb298a3c8be31fdecef0ff2b3aaac/h2-4.4.1-py3-none-any.whl", hash = "sha256:0e25f1462b23c9cb82d9eb02e28bc706dac2a68cb457c6a0d74d63c8a2a5d0e6", size = 62636, upload-time = "2026-08-03T11:44:59.164Z" }, ] [[package]] From e7e96a777567799d72851081e8f59d5e2573471e Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 13 Aug 2026 11:42:03 +0800 Subject: [PATCH 49/52] refactor(connection): simplify connection handling and remove unused components (#132) refactor(task): clean up task module by removing unused classes and imports test(tests): update tests to reflect changes in connection and task handling Signed-off-by: Frost Ming --- src/acp/connection.py | 160 ++++++++++------------------ src/acp/task/__init__.py | 46 +------- src/acp/task/dispatcher.py | 94 ---------------- src/acp/task/queue.py | 67 ------------ src/acp/task/sender.py | 6 +- src/acp/task/state.py | 84 --------------- tests/test_connection_recovery.py | 4 +- tests/test_core.py | 38 +++---- tests/test_request_error_logging.py | 74 +++++++------ tests/test_rpc.py | 31 ++++++ 10 files changed, 148 insertions(+), 456 deletions(-) delete mode 100644 src/acp/task/dispatcher.py delete mode 100644 src/acp/task/queue.py delete mode 100644 src/acp/task/state.py diff --git a/src/acp/connection.py b/src/acp/connection.py index cfd7b5c..84f8f05 100644 --- a/src/acp/connection.py +++ b/src/acp/connection.py @@ -14,21 +14,7 @@ from ._transport import NdjsonTransport, Transport from .exceptions import RequestError -from .task import ( - DefaultMessageDispatcher, - InMemoryMessageQueue, - InMemoryMessageStateStore, - MessageDispatcher, - MessageQueue, - MessageSender, - MessageStateStore, - NotificationRunner, - RequestRunner, - RpcTask, - RpcTaskKind, - SenderFactory, - TaskSupervisor, -) +from .task import MessageSender, TaskSupervisor from .telemetry import span_context JsonValue = Any @@ -38,12 +24,6 @@ __all__ = ["Connection", "JsonValue", "MethodHandler", "StreamDirection", "StreamEvent"] -DispatcherFactory = Callable[ - [MessageQueue, TaskSupervisor, MessageStateStore, RequestRunner, NotificationRunner], - MessageDispatcher, -] - - class StreamDirection(str, Enum): INCOMING = "incoming" OUTGOING = "outgoing" @@ -67,20 +47,15 @@ def __init__( writer: asyncio.StreamWriter | Transport, reader: asyncio.StreamReader | None = None, *, - queue: MessageQueue | None = None, - state_store: MessageStateStore | None = None, - dispatcher_factory: DispatcherFactory | None = None, - sender_factory: SenderFactory | None = None, observers: list[StreamObserver] | None = None, listening: bool = True, receive_timeout: float | None = None, ) -> None: self._handler = handler self._next_request_id = 0 - self._state = state_store or InMemoryMessageStateStore() + self._pending: dict[int, asyncio.Future[Any]] = {} self._tasks = TaskSupervisor(source="acp.Connection") self._tasks.add_error_handler(self._on_task_error) - self._queue = queue or InMemoryMessageQueue() self._closed = False self._disconnected = False # Two construction forms: @@ -92,7 +67,7 @@ def __init__( if reader is None: self._transport: Transport = cast("Transport", writer) else: - sender = (sender_factory or self._default_sender_factory)(cast("asyncio.StreamWriter", writer), self._tasks) + sender = MessageSender(cast("asyncio.StreamWriter", writer), self._tasks) self._transport = NdjsonTransport(reader, sender, receive_timeout=receive_timeout) self._observers: list[StreamObserver] = list(observers or []) if listening: @@ -103,25 +78,17 @@ def __init__( ) else: self._recv_task = None - dispatcher_factory = dispatcher_factory or self._default_dispatcher_factory - self._dispatcher = dispatcher_factory( - self._queue, - self._tasks, - self._state, - self._run_request, - self._run_notification, - ) - self._dispatcher.start() async def close(self) -> None: """Stop the receive loop and cancel any in-flight handler tasks.""" if self._closed: return self._closed = True - await self._dispatcher.stop() - await self._transport.close() - await self._tasks.shutdown() - self._state.reject_all_outgoing(ConnectionError("Connection closed")) + self._reject_all_outgoing(ConnectionError("Connection closed")) + try: + await self._transport.close() + finally: + await self._tasks.shutdown() async def main_loop(self) -> None: try: @@ -145,18 +112,22 @@ async def send_request(self, method: str, params: JsonValue | None = None) -> An self._raise_if_unavailable() request_id = self._next_request_id self._next_request_id += 1 - future = self._state.register_outgoing(request_id, method) + future: asyncio.Future[Any] = asyncio.get_running_loop().create_future() + self._pending[request_id] = future payload = {"jsonrpc": "2.0", "id": request_id, "method": method, "params": params} try: await self._transport.send(payload) - except Exception as exc: - # A synchronous send failure (e.g. HTTP POST rejected before any - # JSON-RPC response exists) must reject the correlated future so the - # caller gets a real, attributable error. - self._state.reject_outgoing(request_id, exc) + except BaseException: + self._pending.pop(request_id, None) + future.cancel() raise self._notify_observers(StreamDirection.OUTGOING, payload) - return await future + try: + return await future + except asyncio.CancelledError: + self._pending.pop(request_id, None) + future.cancel() + raise async def send_notification(self, method: str, params: JsonValue | None = None) -> None: self._raise_if_unavailable() @@ -171,24 +142,26 @@ async def _receive_loop(self) -> None: if message is None: break self._notify_observers(StreamDirection.INCOMING, message) - await self._process_message(message) + self._process_message(message) except asyncio.CancelledError: return except asyncio.TimeoutError: raise RequestError.internal_error({"details": "Agent timeout"}) from None self._disconnect() - async def _process_message(self, message: dict[str, Any]) -> None: + def _process_message(self, message: dict[str, Any]) -> None: method = message.get("method") has_id = "id" in message - if method is not None and has_id: - await self._queue.publish(RpcTask(RpcTaskKind.REQUEST, message)) - return - if method is not None and not has_id: - await self._queue.publish(RpcTask(RpcTaskKind.NOTIFICATION, message)) + if method is not None: # this is a request or notification + # {"jsonrpc": "2.0", "id": 1, "method": "foo", "params": {...}} # request + # {"jsonrpc": "2.0", "method": "foo", "params: {...}} # notification + self._tasks.create( + self._run_request(message) if has_id else self._run_notification(message), + name="acp.Connection.request" if has_id else "acp.Connection.notification", + ) return - if has_id: - await self._handle_response(message) + if has_id: # this is a response, {"id", "result" | "error"} + self._handle_response(message) def _notify_observers(self, direction: StreamDirection, message: dict[str, Any]) -> None: if not self._observers: @@ -211,7 +184,12 @@ def _notify_observers(self, direction: StreamDirection, message: dict[str, Any]) def _on_observer_error(self, task: asyncio.Task[Any], exc: BaseException) -> None: logging.exception("Stream observer coroutine failed", exc_info=exc) - async def _run_request(self, message: dict[str, Any]) -> Any: + async def _run_request(self, message: dict[str, Any]) -> None: + payload = await self._execute_request(message) + await self._transport.send(payload) + self._notify_observers(StreamDirection.OUTGOING, payload) + + async def _execute_request(self, message: dict[str, Any]) -> dict[str, Any]: payload: dict[str, Any] = {"jsonrpc": "2.0", "id": message["id"]} method = message["method"] with span_context( @@ -228,20 +206,10 @@ async def _run_request(self, message: dict[str, Any]) -> Any: exclude_unset=True, ) payload["result"] = result if result is not None else None - await self._transport.send(payload) - self._notify_observers(StreamDirection.OUTGOING, payload) - return payload.get("result") except RequestError as exc: payload["error"] = exc.to_error_obj() - await self._transport.send(payload) - self._notify_observers(StreamDirection.OUTGOING, payload) - raise except ValidationError as exc: - err = RequestError.invalid_params({"errors": exc.errors()}) - payload["error"] = err.to_error_obj() - await self._transport.send(payload) - self._notify_observers(StreamDirection.OUTGOING, payload) - raise err from None + payload["error"] = RequestError.invalid_params({"errors": exc.errors()}).to_error_obj() except Exception as exc: logging.exception( "Unhandled error while handling request method=%s", @@ -252,11 +220,8 @@ async def _run_request(self, message: dict[str, Any]) -> Any: data = json.loads(str(exc)) except Exception: data = {"details": str(exc)} - err = RequestError.internal_error(data) - payload["error"] = err.to_error_obj() - await self._transport.send(payload) - self._notify_observers(StreamDirection.OUTGOING, payload) - raise err from None + payload["error"] = RequestError.internal_error(data).to_error_obj() + return payload async def _run_notification(self, message: dict[str, Any]) -> None: method = message["method"] @@ -270,24 +235,21 @@ async def _run_notification(self, message: dict[str, Any]) -> None: exc_info=exc, ) - async def _handle_response(self, message: dict[str, Any]) -> None: + def _handle_response(self, message: dict[str, Any]) -> None: request_id = message["id"] - result = message.get("result") + future = self._pending.pop(request_id, None) + if future is None or future.done(): + return if "result" in message: - self._state.resolve_outgoing(request_id, result) + future.set_result(message.get("result")) return if "error" in message: error_obj = message.get("error") or {} - self._state.reject_outgoing( - request_id, - RequestError( - error_obj.get("code", -32603), - error_obj.get("message", "Error"), - error_obj.get("data"), - ), + future.set_exception( + RequestError(error_obj.get("code", -32603), error_obj.get("message", "Error"), error_obj.get("data")) ) return - self._state.resolve_outgoing(request_id, None) + future.set_result(None) def _on_receive_error(self, task: asyncio.Task[Any], exc: BaseException) -> None: logging.exception("Receive loop failed", exc_info=exc) @@ -296,30 +258,18 @@ def _on_receive_error(self, task: asyncio.Task[Any], exc: BaseException) -> None def _on_task_error(self, task: asyncio.Task[Any], exc: BaseException) -> None: logging.exception("Background task failed", exc_info=exc) - def _default_dispatcher_factory( - self, - queue: MessageQueue, - supervisor: TaskSupervisor, - state: MessageStateStore, - request_runner: RequestRunner, - notification_runner: NotificationRunner, - ) -> MessageDispatcher: - return DefaultMessageDispatcher( - queue=queue, - supervisor=supervisor, - store=state, - request_runner=request_runner, - notification_runner=notification_runner, - ) - - def _default_sender_factory(self, writer: asyncio.StreamWriter, supervisor: TaskSupervisor) -> MessageSender: - return MessageSender(writer, supervisor) - def _disconnect(self) -> None: if self._disconnected: return self._disconnected = True - self._state.reject_all_outgoing(ConnectionError("Connection closed")) + self._reject_all_outgoing(ConnectionError("Connection closed")) + + def _reject_all_outgoing(self, error: BaseException) -> None: + pending = list(self._pending.values()) + self._pending.clear() + for future in pending: + if not future.done(): + future.set_exception(error) def _raise_if_unavailable(self) -> None: if self._disconnected or self._closed: diff --git a/src/acp/task/__init__.py b/src/acp/task/__init__.py index 2896fbf..074a67f 100644 --- a/src/acp/task/__init__.py +++ b/src/acp/task/__init__.py @@ -1,44 +1,4 @@ -from __future__ import annotations +from .sender import MessageSender +from .supervisor import TaskSupervisor -from dataclasses import dataclass -from enum import Enum -from typing import Any - -__all__ = ["RpcTask", "RpcTaskKind"] - - -class RpcTaskKind(Enum): - REQUEST = "request" - NOTIFICATION = "notification" - - -@dataclass(slots=True) -class RpcTask: - kind: RpcTaskKind - message: dict[str, Any] - - -from .dispatcher import ( # noqa: E402 - DefaultMessageDispatcher, - MessageDispatcher, - NotificationRunner, - RequestRunner, -) -from .queue import InMemoryMessageQueue, MessageQueue # noqa: E402 -from .sender import MessageSender, SenderFactory # noqa: E402 -from .state import InMemoryMessageStateStore, MessageStateStore # noqa: E402 -from .supervisor import TaskSupervisor # noqa: E402 - -__all__ += [ - "DefaultMessageDispatcher", - "InMemoryMessageQueue", - "InMemoryMessageStateStore", - "MessageDispatcher", - "MessageQueue", - "MessageSender", - "MessageStateStore", - "NotificationRunner", - "RequestRunner", - "SenderFactory", - "TaskSupervisor", -] +__all__ = ["MessageSender", "TaskSupervisor"] diff --git a/src/acp/task/dispatcher.py b/src/acp/task/dispatcher.py deleted file mode 100644 index e8c5e76..0000000 --- a/src/acp/task/dispatcher.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import annotations - -import asyncio -from collections.abc import Awaitable, Callable -from contextlib import suppress -from typing import Any, Protocol - -from . import RpcTaskKind -from .queue import MessageQueue -from .state import MessageStateStore -from .supervisor import TaskSupervisor - -__all__ = [ - "DefaultMessageDispatcher", - "MessageDispatcher", - "NotificationRunner", - "RequestRunner", -] - - -RequestRunner = Callable[[dict[str, Any]], Awaitable[Any]] -NotificationRunner = Callable[[dict[str, Any]], Awaitable[None]] - - -class MessageDispatcher(Protocol): - def start(self) -> None: ... - - async def stop(self) -> None: ... - - -class DefaultMessageDispatcher(MessageDispatcher): - """Background worker that consumes RPC tasks from a broker, coordinating with the store.""" - - def __init__( - self, - *, - queue: MessageQueue, - supervisor: TaskSupervisor, - store: MessageStateStore, - request_runner: RequestRunner, - notification_runner: NotificationRunner, - ) -> None: - self._queue = queue - self._supervisor = supervisor - self._store = store - self._request_runner = request_runner - self._notification_runner = notification_runner - self._task: asyncio.Task[None] | None = None - - def start(self) -> None: - if self._task is not None: - msg = "dispatcher already started" - raise RuntimeError(msg) - self._task = self._supervisor.create(self._run(), name="acp.Dispatcher.loop") - - async def _run(self) -> None: - try: - async for task in self._queue: - try: - if task.kind is RpcTaskKind.REQUEST: - await self._dispatch_request(task.message) - else: - await self._dispatch_notification(task.message) - finally: - self._queue.task_done() - except asyncio.CancelledError: - return - - async def stop(self) -> None: - await self._queue.close() - if self._task is not None: - with suppress(asyncio.CancelledError): - await self._task - self._task = None - - async def _dispatch_request(self, message: dict[str, Any]) -> None: - record = self._store.begin_incoming(message.get("method", ""), message.get("params")) - - async def runner() -> None: - try: - result = await self._request_runner(message) - except Exception as exc: - self._store.fail_incoming(record, exc) - raise - else: - self._store.complete_incoming(record, result) - - self._supervisor.create(runner(), name="acp.Dispatcher.request") - - async def _dispatch_notification(self, message: dict[str, Any]) -> None: - async def runner() -> None: - await self._notification_runner(message) - - self._supervisor.create(runner(), name="acp.Dispatcher.notification") diff --git a/src/acp/task/queue.py b/src/acp/task/queue.py deleted file mode 100644 index 6052635..0000000 --- a/src/acp/task/queue.py +++ /dev/null @@ -1,67 +0,0 @@ -from __future__ import annotations - -import asyncio -from collections.abc import AsyncIterator -from contextlib import suppress -from typing import Protocol - -from . import RpcTask - -__all__ = ["InMemoryMessageQueue", "MessageQueue"] - - -class MessageQueue(Protocol): - async def publish(self, task: RpcTask) -> None: ... - - async def close(self) -> None: ... - - def task_done(self) -> None: ... - - async def join(self) -> None: ... - - def __aiter__(self) -> AsyncIterator[RpcTask]: ... - - -class InMemoryMessageQueue: - """Simple in-memory broker for RPC task dispatch.""" - - def __init__(self, *, maxsize: int = 0) -> None: - self._queue: asyncio.Queue[RpcTask | None] = asyncio.Queue(maxsize=maxsize) - self._closed = False - - async def publish(self, task: RpcTask) -> None: - if self._closed: - msg = "mssage queue already closed" - raise RuntimeError(msg) - await self._queue.put(task) - - async def close(self) -> None: - if self._closed: - return - self._closed = True - await self._queue.put(None) - - async def join(self) -> None: - await self._queue.join() - - def task_done(self) -> None: - with suppress(ValueError): - self._queue.task_done() - - def __aiter__(self) -> AsyncIterator[RpcTask]: - return _QueueIterator(self) - - -class _QueueIterator: - def __init__(self, queue: InMemoryMessageQueue) -> None: - self._queue = queue - - def __aiter__(self) -> _QueueIterator: - return self - - async def __anext__(self) -> RpcTask: - item = await self._queue._queue.get() - if item is None: - self._queue.task_done() - raise StopAsyncIteration - return item diff --git a/src/acp/task/sender.py b/src/acp/task/sender.py index 5662af2..613535b 100644 --- a/src/acp/task/sender.py +++ b/src/acp/task/sender.py @@ -4,16 +4,12 @@ import contextlib import json import logging -from collections.abc import Callable from dataclasses import dataclass from typing import Any from .supervisor import TaskSupervisor -__all__ = ["MessageSender", "SenderFactory"] - - -SenderFactory = Callable[[asyncio.StreamWriter, TaskSupervisor], "MessageSender"] +__all__ = ["MessageSender"] @dataclass(slots=True) diff --git a/src/acp/task/state.py b/src/acp/task/state.py deleted file mode 100644 index 65baf0c..0000000 --- a/src/acp/task/state.py +++ /dev/null @@ -1,84 +0,0 @@ -from __future__ import annotations - -import asyncio -from dataclasses import dataclass -from typing import Any, Protocol - -__all__ = [ - "InMemoryMessageStateStore", - "IncomingMessage", - "MessageStateStore", - "OutgoingMessage", -] - - -@dataclass(slots=True) -class OutgoingMessage: - request_id: int - method: str - future: asyncio.Future[Any] - - -@dataclass(slots=True) -class IncomingMessage: - method: str - params: Any - status: str = "pending" - result: Any = None - error: Any = None - - -class MessageStateStore(Protocol): - def register_outgoing(self, request_id: int, method: str) -> asyncio.Future[Any]: ... - - def resolve_outgoing(self, request_id: int, result: Any) -> None: ... - - def reject_outgoing(self, request_id: int, error: Any) -> None: ... - - def reject_all_outgoing(self, error: Any) -> None: ... - - def begin_incoming(self, method: str, params: Any) -> IncomingMessage: ... - - def complete_incoming(self, record: IncomingMessage, result: Any) -> None: ... - - def fail_incoming(self, record: IncomingMessage, error: Any) -> None: ... - - -class InMemoryMessageStateStore(MessageStateStore): - def __init__(self) -> None: - self._outgoing: dict[int, OutgoingMessage] = {} - self._incoming: list[IncomingMessage] = [] - - def register_outgoing(self, request_id: int, method: str) -> asyncio.Future[Any]: - future: asyncio.Future[Any] = asyncio.get_running_loop().create_future() - self._outgoing[request_id] = OutgoingMessage(request_id, method, future) - return future - - def resolve_outgoing(self, request_id: int, result: Any) -> None: - record = self._outgoing.pop(request_id, None) - if record and not record.future.done(): - record.future.set_result(result) - - def reject_outgoing(self, request_id: int, error: Any) -> None: - record = self._outgoing.pop(request_id, None) - if record and not record.future.done(): - record.future.set_exception(error) - - def reject_all_outgoing(self, error: Any) -> None: - for record in self._outgoing.values(): - if not record.future.done(): - record.future.set_exception(error) - self._outgoing.clear() - - def begin_incoming(self, method: str, params: Any) -> IncomingMessage: - record = IncomingMessage(method=method, params=params) - self._incoming.append(record) - return record - - def complete_incoming(self, record: IncomingMessage, result: Any) -> None: - record.status = "completed" - record.result = result - - def fail_incoming(self, record: IncomingMessage, error: Any) -> None: - record.status = "failed" - record.error = error diff --git a/tests/test_connection_recovery.py b/tests/test_connection_recovery.py index 95769f6..77059d3 100644 --- a/tests/test_connection_recovery.py +++ b/tests/test_connection_recovery.py @@ -34,7 +34,7 @@ async def test_receive_loop_handles_oversized_frame(caplog: pytest.LogCaptureFix conn, reader = _make_connection(limit=128) processed: list[str] = [] - async def tracking_process(message: dict[str, Any]) -> None: + def tracking_process(message: dict[str, Any]) -> None: processed.append(message["method"]) conn._process_message = tracking_process # type: ignore[method-assign] @@ -56,7 +56,7 @@ async def test_receive_loop_handles_consecutive_oversized_frames() -> None: conn, reader = _make_connection(limit=128) processed: list[str] = [] - async def tracking_process(message: dict[str, Any]) -> None: + def tracking_process(message: dict[str, Any]) -> None: processed.append(message["method"]) conn._process_message = tracking_process # type: ignore[method-assign] diff --git a/tests/test_core.py b/tests/test_core.py index 571dd7f..8ae2219 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -10,46 +10,34 @@ @pytest.mark.asyncio -async def test_run_agent_closes_connection_when_cancelled(server, agent) -> None: - sender_created = asyncio.Event() - sender_closed = asyncio.Event() - dispatcher_started = asyncio.Event() - dispatcher_stopped = asyncio.Event() +async def test_run_agent_closes_connection_when_cancelled(agent) -> None: + receive_started = asyncio.Event() + transport_closed = asyncio.Event() - class TrackingSender: - def __init__(self, writer: asyncio.StreamWriter, supervisor: Any) -> None: - sender_created.set() + class TrackingTransport: + async def receive(self) -> dict[str, Any] | None: + receive_started.set() + await asyncio.Event().wait() + return None - async def send(self, payload: dict[str, Any]) -> None: + async def send(self, message: dict[str, Any]) -> None: msg = "test does not send messages" raise AssertionError(msg) async def close(self) -> None: - sender_closed.set() - - class TrackingDispatcher: - def start(self) -> None: - dispatcher_started.set() - - async def stop(self) -> None: - dispatcher_stopped.set() + transport_closed.set() task = asyncio.create_task( run_agent( agent, - server.server_writer, - server.server_reader, - sender_factory=TrackingSender, - dispatcher_factory=lambda *args: TrackingDispatcher(), + TrackingTransport(), ) ) - await asyncio.wait_for(sender_created.wait(), timeout=1) - await asyncio.wait_for(dispatcher_started.wait(), timeout=1) + await asyncio.wait_for(receive_started.wait(), timeout=1) task.cancel() with contextlib.suppress(asyncio.CancelledError): await asyncio.wait_for(task, timeout=1) - await asyncio.wait_for(dispatcher_stopped.wait(), timeout=1) - await asyncio.wait_for(sender_closed.wait(), timeout=1) + await asyncio.wait_for(transport_closed.wait(), timeout=1) diff --git a/tests/test_request_error_logging.py b/tests/test_request_error_logging.py index 3581804..12f3ec4 100644 --- a/tests/test_request_error_logging.py +++ b/tests/test_request_error_logging.py @@ -8,39 +8,35 @@ from __future__ import annotations -import asyncio import logging from typing import Any -from unittest.mock import MagicMock import pytest +from acp._transport import Transport from acp.connection import Connection, MethodHandler -from acp.exceptions import RequestError -class _RecordingSender: - """Duck-typed MessageSender that records outgoing frames instead of writing them.""" +class _RecordingTransport: + """Message transport that records outgoing frames.""" - def __init__(self, writer: asyncio.StreamWriter, supervisor: Any) -> None: + def __init__(self) -> None: self.sent: list[dict[str, Any]] = [] - async def send(self, payload: dict[str, Any]) -> None: - self.sent.append(payload) + async def send(self, message: dict[str, Any]) -> None: + self.sent.append(message) + + async def receive(self) -> dict[str, Any] | None: + return None async def close(self) -> None: pass -def _make_connection(handler: MethodHandler) -> tuple[Connection, _RecordingSender]: - captured: dict[str, _RecordingSender] = {} - - def sender_factory(writer: asyncio.StreamWriter, supervisor: Any) -> _RecordingSender: - captured["sender"] = _RecordingSender(writer, supervisor) - return captured["sender"] - - conn = Connection(handler, MagicMock(), MagicMock(), sender_factory=sender_factory, listening=False) - return conn, captured["sender"] +def _make_connection(handler: MethodHandler) -> tuple[Connection, _RecordingTransport]: + transport = _RecordingTransport() + conn = Connection(handler, transport, listening=False) + return conn, transport async def _raising_handler(method: str, params: Any, is_notification: bool) -> Any: @@ -62,25 +58,19 @@ def _assert_logged_runtime_error(caplog: pytest.LogCaptureFixture, method: str) @pytest.mark.asyncio -async def test_run_request_unhandled_exception_is_logged_and_returned_as_internal_error(caplog): - conn, sender = _make_connection(_raising_handler) +async def test_run_request_unhandled_exception_is_logged_and_sent_as_internal_error(caplog): + conn, transport = _make_connection(_raising_handler) request = {"jsonrpc": "2.0", "id": 7, "method": "explode", "params": None} try: - with caplog.at_level(logging.ERROR), pytest.raises(RequestError) as exc_info: + with caplog.at_level(logging.ERROR): await conn._run_request(request) finally: await conn.close() - # The handler exception is re-raised as a JSON-RPC internal error... - raised = exc_info.value - assert isinstance(raised, RequestError) - assert raised.code == -32603 - assert raised.data == {"details": "kaboom"} - - # ...and exactly one error frame carrying the handler's message is written to the peer. - assert len(sender.sent) == 1 - response = sender.sent[0] + # A handled application exception becomes exactly one JSON-RPC error frame. + assert len(transport.sent) == 1 + response = transport.sent[0] assert response["id"] == 7 assert "result" not in response assert response["error"] == {"code": -32603, "message": "Internal error", "data": {"details": "kaboom"}} @@ -91,7 +81,7 @@ async def test_run_request_unhandled_exception_is_logged_and_returned_as_interna @pytest.mark.asyncio async def test_run_notification_unhandled_exception_is_logged_and_not_answered(caplog): - conn, sender = _make_connection(_raising_handler) + conn, transport = _make_connection(_raising_handler) notification = {"jsonrpc": "2.0", "method": "session/cancel", "params": {"sessionId": "s1"}} try: @@ -102,7 +92,29 @@ async def test_run_notification_unhandled_exception_is_logged_and_not_answered(c # A notification has no response: the error is neither raised nor written to the wire. assert result is None - assert sender.sent == [] + assert transport.sent == [] # It must still be logged — previously contextlib.suppress dropped it silently. _assert_logged_runtime_error(caplog, "session/cancel") + + +@pytest.mark.asyncio +async def test_response_send_failure_is_not_mapped_to_a_handler_error(caplog): + class _FailingTransport(_RecordingTransport): + async def send(self, message: dict[str, Any]) -> None: + raise ConnectionError("send failed") + + async def successful_handler(method: str, params: Any, is_notification: bool) -> Any: + return {"ok": True} + + transport: Transport = _FailingTransport() + conn = Connection(successful_handler, transport, listening=False) + request = {"jsonrpc": "2.0", "id": 8, "method": "succeed", "params": None} + + try: + with caplog.at_level(logging.ERROR), pytest.raises(ConnectionError, match="send failed"): + await conn._run_request(request) + finally: + await conn.close() + + assert "Unhandled error while handling request method=succeed" not in caplog.text diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 5e8a917..1d29465 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -299,6 +299,37 @@ async def test_new_requests_fail_fast_after_remote_eof(server): await conn.close() +@pytest.mark.asyncio +async def test_cancelled_request_is_removed_from_pending_map() -> None: + sent = asyncio.Event() + + class _NeverRespondTransport: + async def send(self, message: dict[str, Any]) -> None: + sent.set() + + async def receive(self) -> dict[str, Any] | None: + await asyncio.Event().wait() + return None + + async def close(self) -> None: + pass + + conn = Connection( + lambda method, params, is_notification: None, + _NeverRespondTransport(), + listening=False, + ) + request = asyncio.create_task(conn.send_request("ping")) + + await sent.wait() + request.cancel() + with pytest.raises(asyncio.CancelledError): + await request + + assert conn._pending == {} + await conn.close() + + @pytest.mark.asyncio async def test_invalid_params_results_in_error_response(connect, server): # Only start agent-side (server) so we can inject raw request from client socket From e8ff5bc36cf71c90eb0bb36df42921e9491262f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:49:42 +0800 Subject: [PATCH 50/52] chore(deps): bump pymdown-extensions in the uv group across 1 directory (#133) Bumps the uv group with 1 update in the / directory: [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions). Updates `pymdown-extensions` from 11.0 to 11.0.1 - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](https://github.com/facelessuser/pymdown-extensions/compare/11.0...11.0.1) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-version: 11.0.1 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 54fd84f..2da1a82 100644 --- a/uv.lock +++ b/uv.lock @@ -1192,15 +1192,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "11.0" +version = "11.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/47/67/f1e79672a5f91985577c7984c9709ca110e4fd37fe7fd167b60422e6ccc2/pymdown_extensions-11.0.tar.gz", hash = "sha256:8269cef0247f9e2d0a62fcea10860aba05c1cbab5470fd4b63230b96434dc589", size = 857049, upload-time = "2026-06-23T02:27:45.146Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/a9/5f0c535ba3b08fe09270c16808e053a968868242ecbd5676d4e3a488bf28/pymdown_extensions-11.0.1.tar.gz", hash = "sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0", size = 857113, upload-time = "2026-07-02T17:59:22.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/b6/1ae53367e28b9cffa3be7574e13fbe4589694272fd47710fbdbafd3d63c6/pymdown_extensions-11.0-py3-none-any.whl", hash = "sha256:fbc4acb641814fa9d17521bbd21a5240ef739a662f11c06330c4b78c93e954d6", size = 269415, upload-time = "2026-06-23T02:27:43.826Z" }, + { url = "https://files.pythonhosted.org/packages/d6/54/da572c98c0b77626a91b5d3b89f0231d8bff5125c225420908632f8b342d/pymdown_extensions-11.0.1-py3-none-any.whl", hash = "sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2", size = 269455, upload-time = "2026-07-02T17:59:21.271Z" }, ] [[package]] From 1647b4a55cdc60065d19457173eb870d75377de7 Mon Sep 17 00:00:00 2001 From: Konstantin Dunas Date: Sun, 16 Aug 2026 07:00:28 -0700 Subject: [PATCH 51/52] fix(client): preserve session update ordering (#129) --- src/acp/client/connection.py | 78 ++++++++++++++++-- tests/test_rpc.py | 149 +++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 8 deletions(-) diff --git a/src/acp/client/connection.py b/src/acp/client/connection.py index 81f6769..000a5da 100644 --- a/src/acp/client/connection.py +++ b/src/acp/client/connection.py @@ -2,12 +2,15 @@ import asyncio from collections.abc import Callable +from contextvars import ContextVar from typing import Any, cast, final from .._transport import Transport from ..connection import Connection +from ..exceptions import RequestError from ..interfaces import Agent, Client -from ..meta import AGENT_METHODS +from ..meta import AGENT_METHODS, CLIENT_METHODS +from ..router import _resolve_handler, _warn_legacy_handler from ..schema import ( AcpMcpServer, AudioContentBlock, @@ -37,6 +40,7 @@ ResourceContentBlock, ResumeSessionRequest, ResumeSessionResponse, + SessionNotification, SetSessionConfigOptionBooleanRequest, SetSessionConfigOptionResponse, SetSessionConfigOptionSelectRequest, @@ -52,6 +56,56 @@ _CLIENT_CONNECTION_ERROR = "ClientSideConnection requires asyncio StreamWriter/StreamReader" +class _SessionUpdateTracker: + """Client proxy that tracks in-flight session updates.""" + + def __init__(self, client: Client) -> None: + self._client = client + self._session_update, self._session_update_attr, self._legacy_session_update = _resolve_handler( + client, "session_update" + ) + self._pending: dict[str, set[asyncio.Future[None]]] = {} + self._current_update: ContextVar[asyncio.Future[None] | None] = ContextVar( + "acp_current_session_update", default=None + ) + + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + completed: asyncio.Future[None] = asyncio.get_running_loop().create_future() + pending = self._pending.setdefault(session_id, set()) + pending.add(completed) + token = self._current_update.set(completed) + + try: + if self._session_update is None: + raise RequestError.method_not_found(CLIENT_METHODS["session_update"]) + if self._legacy_session_update: + _warn_legacy_handler(self._client, self._session_update_attr) + notification = SessionNotification(session_id=session_id, update=update, field_meta=kwargs or None) + await self._session_update(notification) + else: + await self._session_update(session_id=session_id, update=update, **kwargs) + finally: + self._current_update.reset(token) + if not completed.done(): + completed.set_result(None) + pending.discard(completed) + if not pending: + self._pending.pop(session_id, None) + + async def wait(self, session_id: str) -> None: + # Snapshot before yielding so updates received after the response are + # not associated with this prompt. + current = self._current_update.get() + notifications = tuple( + completed for completed in self._pending.get(session_id, set()) if completed is not current + ) + if notifications: + await asyncio.gather(*(asyncio.shield(completed) for completed in notifications)) + + def __getattr__(self, name: str) -> Any: + return getattr(self._client, name) + + @final @compatible_class class ClientSideConnection: @@ -69,7 +123,9 @@ def __init__( **connection_kwargs: Any, ) -> None: client = to_client(self) if callable(to_client) else to_client - handler = build_client_router(cast(Client, client), use_unstable_protocol=use_unstable_protocol) + self._session_updates = _SessionUpdateTracker(cast(Client, client)) + handler = build_client_router(cast(Client, self._session_updates), use_unstable_protocol=use_unstable_protocol) + if isinstance(input_stream, Transport): if output_stream is not None: raise TypeError(_CLIENT_CONNECTION_ERROR) @@ -206,12 +262,18 @@ async def prompt( ], **kwargs: Any, ) -> PromptResponse: - return await request_model( - self._conn, - AGENT_METHODS["session_prompt"], - PromptRequest(prompt=prompt, session_id=session_id, field_meta=kwargs or None), - PromptResponse, - ) + try: + response = await request_model( + self._conn, + AGENT_METHODS["session_prompt"], + PromptRequest(prompt=prompt, session_id=session_id, field_meta=kwargs or None), + PromptResponse, + ) + except Exception: + await self._session_updates.wait(session_id) + raise + await self._session_updates.wait(session_id) + return response @param_model(ForkSessionRequest) async def fork_session( diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 1d29465..ef4623e 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -34,6 +34,7 @@ ) from acp.connection import Connection from acp.core import AgentSideConnection, ClientSideConnection +from acp.exceptions import RequestError from acp.schema import ( AgentMessageChunk, AllowedOutcome, @@ -144,6 +145,154 @@ async def test_session_notifications_flow(connect, client): assert client.notifications[0].session_id == "sess" +@pytest.mark.asyncio +async def test_response_waits_for_preceding_notification(server): + notification_started = asyncio.Event() + release_notification = asyncio.Event() + + class _BlockingClient(TestClient): + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + notification_started.set() + await release_notification.wait() + await super().session_update(session_id, update, **kwargs) + + client = _BlockingClient() + conn = ClientSideConnection(client, server.client_writer, server.client_reader) + request = asyncio.create_task( + conn.prompt(session_id="sess", prompt=[TextContentBlock(type="text", text="question")]) + ) + + request_message = json.loads(await server.server_reader.readline()) + notification = { + "jsonrpc": "2.0", + "method": "session/update", + "params": { + "sessionId": "sess", + "update": { + "sessionUpdate": "agent_message_chunk", + "content": {"type": "text", "text": "answer"}, + }, + }, + } + response = {"jsonrpc": "2.0", "id": request_message["id"], "result": {"stopReason": "end_turn"}} + server.server_writer.write((json.dumps(notification) + "\n" + json.dumps(response) + "\n").encode()) + await server.server_writer.drain() + + await asyncio.wait_for(notification_started.wait(), timeout=1) + await asyncio.sleep(0) + assert not request.done() + + release_notification.set() + prompt_response = await asyncio.wait_for(request, timeout=1) + assert prompt_response.stop_reason == "end_turn" + assert len(client.notifications) == 1 + assert client.notifications[0].session_id == "sess" + await conn.close() + + +@pytest.mark.asyncio +async def test_error_response_waits_for_preceding_notification(server): + notification_started = asyncio.Event() + release_notification = asyncio.Event() + + class _BlockingClient(TestClient): + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + notification_started.set() + await release_notification.wait() + + conn = ClientSideConnection(_BlockingClient(), server.client_writer, server.client_reader) + request = asyncio.create_task( + conn.prompt(session_id="sess", prompt=[TextContentBlock(type="text", text="question")]) + ) + + request_message = json.loads(await server.server_reader.readline()) + notification = { + "jsonrpc": "2.0", + "method": "session/update", + "params": { + "sessionId": "sess", + "update": { + "sessionUpdate": "agent_message_chunk", + "content": {"type": "text", "text": "partial answer"}, + }, + }, + } + response = { + "jsonrpc": "2.0", + "id": request_message["id"], + "error": {"code": -32603, "message": "prompt failed"}, + } + server.server_writer.write((json.dumps(notification) + "\n" + json.dumps(response) + "\n").encode()) + await server.server_writer.drain() + + await asyncio.wait_for(notification_started.wait(), timeout=1) + await asyncio.sleep(0) + assert not request.done() + + release_notification.set() + with pytest.raises(RequestError, match="prompt failed"): + await asyncio.wait_for(request, timeout=1) + await conn.close() + + +@pytest.mark.asyncio +async def test_notification_can_await_nested_request(server): + notification_finished = asyncio.Event() + + class _NestedPromptClient(TestClient): + def __init__(self) -> None: + super().__init__() + self.conn: Agent | None = None + self.nested_result: PromptResponse | None = None + + def on_connect(self, conn: Agent) -> None: + self.conn = conn + + async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None: + assert self.conn is not None + self.nested_result = await self.conn.prompt( + session_id=session_id, + prompt=[TextContentBlock(type="text", text="nested question")], + ) + notification_finished.set() + + client = _NestedPromptClient() + conn = ClientSideConnection(client, server.client_writer, server.client_reader) + outer_request = asyncio.create_task( + conn.prompt(session_id="sess", prompt=[TextContentBlock(type="text", text="outer question")]) + ) + outer_message = json.loads(await server.server_reader.readline()) + + notification = { + "jsonrpc": "2.0", + "method": "session/update", + "params": { + "sessionId": "sess", + "update": { + "sessionUpdate": "agent_message_chunk", + "content": {"type": "text", "text": "answer"}, + }, + }, + } + server.server_writer.write((json.dumps(notification) + "\n").encode()) + await server.server_writer.drain() + + nested_message = json.loads(await asyncio.wait_for(server.server_reader.readline(), timeout=1)) + nested_response = {"jsonrpc": "2.0", "id": nested_message["id"], "result": {"stopReason": "end_turn"}} + server.server_writer.write((json.dumps(nested_response) + "\n").encode()) + await server.server_writer.drain() + + await asyncio.wait_for(notification_finished.wait(), timeout=1) + assert client.nested_result is not None + assert client.nested_result.stop_reason == "end_turn" + + outer_response = {"jsonrpc": "2.0", "id": outer_message["id"], "result": {"stopReason": "end_turn"}} + server.server_writer.write((json.dumps(outer_response) + "\n").encode()) + await server.server_writer.drain() + assert (await asyncio.wait_for(outer_request, timeout=1)).stop_reason == "end_turn" + await conn.close() + + @pytest.mark.asyncio async def test_on_connect_create_terminal_handle(server): class _TerminalAgent(Agent): From e668ed9e0034f5076749a6d74c5cec40ab610010 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Sun, 16 Aug 2026 22:04:54 +0800 Subject: [PATCH 52/52] fix(version): update agent-client-protocol version to 0.12.1 in pyproject.toml and uv.lock Signed-off-by: Frost Ming --- pyproject.toml | 2 +- uv.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d9c8e1c..2602140 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "agent-client-protocol" -version = "0.12.0" +version = "0.12.1" description = "A Python implement of Agent Client Protocol (ACP, by Zed Industries)" authors = [ { name = "Chojan Shang", email = "psiace@apache.org" }, diff --git a/uv.lock b/uv.lock index 2da1a82..c4d74e3 100644 --- a/uv.lock +++ b/uv.lock @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "agent-client-protocol" -version = "0.12.0" +version = "0.12.1" source = { editable = "." } dependencies = [ { name = "pydantic" }, @@ -381,7 +381,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [