diff --git a/Cargo.toml b/Cargo.toml index 72174a8..d986671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,12 @@ categories = ["development-tools", "api-bindings"] include = ["/src/**/*.rs", "/README.md", "/LICENSE", "/Cargo.toml"] [features] -unstable = ["unstable_session_model", "unstable_session_list", "unstable_session_fork", "unstable_cancel_request"] +unstable = ["unstable_session_model", "unstable_session_list", "unstable_session_fork", "unstable_session_resume", "unstable_cancel_request"] unstable_cancel_request = [] unstable_session_model = [] unstable_session_list = [] unstable_session_fork = [] +unstable_session_resume = [] [[bin]] name = "generate" diff --git a/docs/protocol/draft/schema.mdx b/docs/protocol/draft/schema.mdx index 308ff78..5c1bc91 100644 --- a/docs/protocol/draft/schema.mdx +++ b/docs/protocol/draft/schema.mdx @@ -583,6 +583,90 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/exte Indicates why the agent stopped processing the turn. + +### session/resume + +**UNSTABLE** + +This capability is not part of the spec yet, and may be removed or changed at any point. + +Resumes an existing session without returning previous messages. + +This method is only available if the agent advertises the `session.resume` capability. + +The agent should resume the session context, allowing the conversation to continue +without replaying the message history (unlike `session/load`). + +#### ResumeSessionRequest + +**UNSTABLE** + +This capability is not part of the spec yet, and may be removed or changed at any point. + +Request parameters for resuming an existing session. + +Resumes an existing session without returning previous messages (unlike `session/load`). +This is useful for agents that can resume sessions but don't implement full session loading. + +Only available if the Agent supports the `session.resume` capability. + +**Type:** Object + +**Properties:** + + + The _meta property is reserved by ACP to allow clients and agents to attach additional +metadata to their interactions. Implementations MUST NOT make assumptions about values at +these keys. + +See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + + + + The working directory for this session. + +McpServer[]} > + List of MCP servers to connect to for this session. + +SessionId} required> + The ID of the session to resume. + + +#### ResumeSessionResponse + +**UNSTABLE** + +This capability is not part of the spec yet, and may be removed or changed at any point. + +Response from resuming an existing session. + +**Type:** Object + +**Properties:** + + + The _meta property is reserved by ACP to allow clients and agents to attach additional +metadata to their interactions. Implementations MUST NOT make assumptions about values at +these keys. + +See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + + +SessionModelState | null} > + **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 + + +SessionModeState | null} > + Initial mode state if supported by the Agent + +See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + + + ### session/set_mode @@ -2759,6 +2843,14 @@ This capability is not part of the spec yet, and may be removed or changed at an Whether the agent supports `session/list`. + +SessionResumeCapabilities | null} > + **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`. + ## SessionForkCapabilities @@ -2930,6 +3022,29 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/exte The current model the Agent is in. +## SessionResumeCapabilities + +**UNSTABLE** + +This capability is not part of the spec yet, and may be removed or changed at any point. + +Capabilities for the `session/resume` method. + +By supplying `\{\}` it means that the agent supports resuming of sessions. + +**Type:** Object + +**Properties:** + + + The _meta property is reserved by ACP to allow clients and agents to attach additional +metadata to their interactions. Implementations MUST NOT make assumptions about values at +these keys. + +See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + + + ## SessionUpdate Different types of updates that can be sent during session processing. diff --git a/schema/meta.unstable.json b/schema/meta.unstable.json index b67f1f3..e58853e 100644 --- a/schema/meta.unstable.json +++ b/schema/meta.unstable.json @@ -8,6 +8,7 @@ "session_load": "session/load", "session_new": "session/new", "session_prompt": "session/prompt", + "session_resume": "session/resume", "session_set_mode": "session/set_mode", "session_set_model": "session/set_model" }, diff --git a/schema/schema.unstable.json b/schema/schema.unstable.json index 86675b0..2c67708 100644 --- a/schema/schema.unstable.json +++ b/schema/schema.unstable.json @@ -211,6 +211,9 @@ { "$ref": "#/$defs/ForkSessionResponse" }, + { + "$ref": "#/$defs/ResumeSessionResponse" + }, { "$ref": "#/$defs/SetSessionModeResponse" }, @@ -606,6 +609,14 @@ ], "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/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`)." + }, { "allOf": [ { @@ -2254,6 +2265,74 @@ "required": ["name", "uri"], "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.", + "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"] + }, + "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": "**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.", + "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"] + }, + "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"], @@ -2308,6 +2387,17 @@ } ], "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`." + }, + "resume": { + "anyOf": [ + { + "$ref": "#/$defs/SessionResumeCapabilities" + }, + { + "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" @@ -2479,6 +2569,17 @@ "x-method": "session/update", "x-side": "client" }, + "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.", + "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": { diff --git a/src/agent.rs b/src/agent.rs index 2c50119..6c0631a 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -732,6 +732,143 @@ impl ForkSessionResponse { } } +// Resume session + +/// **UNSTABLE** +/// +/// This capability is not part of the spec yet, and may be removed or changed at any point. +/// +/// Request parameters for resuming an existing session. +/// +/// Resumes an existing session without returning previous messages (unlike `session/load`). +/// This is useful for agents that can resume sessions but don't implement full session loading. +/// +/// Only available if the Agent supports the `session.resume` capability. +#[cfg(feature = "unstable_session_resume")] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))] +#[serde(rename_all = "camelCase")] +#[non_exhaustive] +pub struct ResumeSessionRequest { + /// The ID of the session to resume. + pub session_id: SessionId, + /// The working directory for this session. + pub cwd: PathBuf, + /// List of MCP servers to connect to for this session. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub mcp_servers: Vec, + /// The _meta property is reserved by ACP to allow clients and agents to attach additional + /// metadata to their interactions. Implementations MUST NOT make assumptions about values at + /// these keys. + /// + /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")] + pub meta: Option, +} + +#[cfg(feature = "unstable_session_resume")] +impl ResumeSessionRequest { + pub fn new(session_id: impl Into, cwd: impl Into) -> Self { + Self { + session_id: session_id.into(), + cwd: cwd.into(), + mcp_servers: vec![], + meta: None, + } + } + + /// List of MCP servers to connect to for this session. + #[must_use] + pub fn mcp_servers(mut self, mcp_servers: Vec) -> Self { + self.mcp_servers = mcp_servers; + self + } + + /// The _meta property is reserved by ACP to allow clients and agents to attach additional + /// metadata to their interactions. Implementations MUST NOT make assumptions about values at + /// these keys. + /// + /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + #[must_use] + pub fn meta(mut self, meta: impl IntoOption) -> Self { + self.meta = meta.into_option(); + self + } +} + +/// **UNSTABLE** +/// +/// This capability is not part of the spec yet, and may be removed or changed at any point. +/// +/// Response from resuming an existing session. +#[cfg(feature = "unstable_session_resume")] +#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[schemars(extend("x-side" = "agent", "x-method" = SESSION_RESUME_METHOD_NAME))] +#[serde(rename_all = "camelCase")] +#[non_exhaustive] +pub struct ResumeSessionResponse { + /// Initial mode state if supported by the Agent + /// + /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub modes: Option, + /// **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 + #[cfg(feature = "unstable_session_model")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub models: 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) + #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")] + pub meta: Option, +} + +#[cfg(feature = "unstable_session_resume")] +impl ResumeSessionResponse { + #[must_use] + pub fn new() -> Self { + Self::default() + } + + /// Initial mode state if supported by the Agent + /// + /// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes) + #[must_use] + pub fn modes(mut self, modes: impl IntoOption) -> Self { + self.modes = modes.into_option(); + self + } + + /// **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 + #[cfg(feature = "unstable_session_model")] + #[must_use] + pub fn models(mut self, models: impl IntoOption) -> Self { + self.models = models.into_option(); + self + } + + /// The _meta property is reserved by ACP to allow clients and agents to attach additional + /// metadata to their interactions. Implementations MUST NOT make assumptions about values at + /// these keys. + /// + /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + #[must_use] + pub fn meta(mut self, meta: impl IntoOption) -> Self { + self.meta = meta.into_option(); + self + } +} + // List sessions /// **UNSTABLE** @@ -1778,6 +1915,14 @@ pub struct SessionCapabilities { #[cfg(feature = "unstable_session_fork")] #[serde(skip_serializing_if = "Option::is_none")] pub fork: Option, + /// **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`. + #[cfg(feature = "unstable_session_resume")] + #[serde(skip_serializing_if = "Option::is_none")] + pub resume: 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. @@ -1809,6 +1954,14 @@ impl SessionCapabilities { self } + #[cfg(feature = "unstable_session_resume")] + /// Whether the agent supports `session/resume`. + #[must_use] + pub fn resume(mut self, resume: impl IntoOption) -> Self { + self.resume = resume.into_option(); + self + } + /// The _meta property is reserved by ACP to allow clients and agents to attach additional /// metadata to their interactions. Implementations MUST NOT make assumptions about values at /// these keys. @@ -1896,6 +2049,45 @@ impl SessionForkCapabilities { } } +/// **UNSTABLE** +/// +/// This capability is not part of the spec yet, and may be removed or changed at any point. +/// +/// Capabilities for the `session/resume` method. +/// +/// By supplying `{}` it means that the agent supports resuming of sessions. +#[cfg(feature = "unstable_session_resume")] +#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[non_exhaustive] +pub struct SessionResumeCapabilities { + /// The _meta property is reserved by ACP to allow clients and agents to attach additional + /// metadata to their interactions. Implementations MUST NOT make assumptions about values at + /// these keys. + /// + /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + #[serde(skip_serializing_if = "Option::is_none", rename = "_meta")] + pub meta: Option, +} + +#[cfg(feature = "unstable_session_resume")] +impl SessionResumeCapabilities { + #[must_use] + pub fn new() -> Self { + Self::default() + } + + /// The _meta property is reserved by ACP to allow clients and agents to attach additional + /// metadata to their interactions. Implementations MUST NOT make assumptions about values at + /// these keys. + /// + /// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) + #[must_use] + pub fn meta(mut self, meta: impl IntoOption) -> Self { + self.meta = meta.into_option(); + self + } +} + /// Prompt capabilities supported by the agent in `session/prompt` requests. /// /// Baseline agent functionality requires support for [`ContentBlock::Text`] @@ -2058,6 +2250,9 @@ pub struct AgentMethodNames { /// Method for forking an existing session. #[cfg(feature = "unstable_session_fork")] pub session_fork: &'static str, + /// Method for resuming an existing session. + #[cfg(feature = "unstable_session_resume")] + pub session_resume: &'static str, } /// Constant containing all agent method names. @@ -2075,6 +2270,8 @@ pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames { session_list: SESSION_LIST_METHOD_NAME, #[cfg(feature = "unstable_session_fork")] session_fork: SESSION_FORK_METHOD_NAME, + #[cfg(feature = "unstable_session_resume")] + session_resume: SESSION_RESUME_METHOD_NAME, }; /// Method name for the initialize request. @@ -2100,6 +2297,9 @@ pub(crate) const SESSION_LIST_METHOD_NAME: &str = "session/list"; /// Method name for forking an existing session. #[cfg(feature = "unstable_session_fork")] pub(crate) const SESSION_FORK_METHOD_NAME: &str = "session/fork"; +/// Method name for resuming an existing session. +#[cfg(feature = "unstable_session_resume")] +pub(crate) const SESSION_RESUME_METHOD_NAME: &str = "session/resume"; /// All possible requests that a client can send to an agent. /// @@ -2181,6 +2381,18 @@ pub enum ClientRequest { /// original, allowing operations like generating summaries without affecting the /// original session's history. ForkSessionRequest(ForkSessionRequest), + #[cfg(feature = "unstable_session_resume")] + /// **UNSTABLE** + /// + /// This capability is not part of the spec yet, and may be removed or changed at any point. + /// + /// Resumes an existing session without returning previous messages. + /// + /// This method is only available if the agent advertises the `session.resume` capability. + /// + /// The agent should resume the session context, allowing the conversation to continue + /// without replaying the message history (unlike `session/load`). + ResumeSessionRequest(ResumeSessionRequest), /// Sets the current mode for a session. /// /// Allows switching between different agent modes (e.g., "ask", "architect", "code") @@ -2236,6 +2448,8 @@ impl ClientRequest { Self::ListSessionsRequest(_) => AGENT_METHOD_NAMES.session_list, #[cfg(feature = "unstable_session_fork")] Self::ForkSessionRequest(_) => AGENT_METHOD_NAMES.session_fork, + #[cfg(feature = "unstable_session_resume")] + Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume, Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode, Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt, #[cfg(feature = "unstable_session_model")] @@ -2255,6 +2469,7 @@ impl ClientRequest { #[serde(untagged)] #[schemars(inline)] #[non_exhaustive] +#[expect(clippy::large_enum_variant)] pub enum AgentResponse { InitializeResponse(InitializeResponse), AuthenticateResponse(#[serde(default)] AuthenticateResponse), @@ -2264,6 +2479,8 @@ pub enum AgentResponse { ListSessionsResponse(ListSessionsResponse), #[cfg(feature = "unstable_session_fork")] ForkSessionResponse(ForkSessionResponse), + #[cfg(feature = "unstable_session_resume")] + ResumeSessionResponse(#[serde(default)] ResumeSessionResponse), SetSessionModeResponse(#[serde(default)] SetSessionModeResponse), PromptResponse(PromptResponse), #[cfg(feature = "unstable_session_model")] diff --git a/src/bin/generate.rs b/src/bin/generate.rs index 39ae870..87945de 100644 --- a/src/bin/generate.rs +++ b/src/bin/generate.rs @@ -850,6 +850,7 @@ starting with '$/' it is free to ignore the notification." "session/load" => self.agent.get("LoadSessionRequest").unwrap(), "session/list" => self.agent.get("ListSessionsRequest").unwrap(), "session/fork" => self.agent.get("ForkSessionRequest").unwrap(), + "session/resume" => self.agent.get("ResumeSessionRequest").unwrap(), "session/set_mode" => self.agent.get("SetSessionModeRequest").unwrap(), "session/prompt" => self.agent.get("PromptRequest").unwrap(), "session/cancel" => self.agent.get("CancelNotification").unwrap(), diff --git a/src/rpc.rs b/src/rpc.rs index 07ec773..c8c5e0b 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -287,6 +287,10 @@ impl Side for AgentSide { m if m == AGENT_METHOD_NAMES.session_fork => serde_json::from_str(params.get()) .map(ClientRequest::ForkSessionRequest) .map_err(Into::into), + #[cfg(feature = "unstable_session_resume")] + m if m == AGENT_METHOD_NAMES.session_resume => serde_json::from_str(params.get()) + .map(ClientRequest::ResumeSessionRequest) + .map_err(Into::into), m if m == AGENT_METHOD_NAMES.session_set_mode => serde_json::from_str(params.get()) .map(ClientRequest::SetSessionModeRequest) .map_err(Into::into),