From 956e0583f3cd183d6584f786e1e8be44b933d275 Mon Sep 17 00:00:00 2001 From: "Anna.Zhdan" Date: Thu, 19 Mar 2026 18:20:21 +0100 Subject: [PATCH] update elicitation mechanism to allow for elicitations outside of the session scope --- docs/protocol/draft/schema.mdx | 225 +++++++++++++++++---------------- docs/rfds/elicitation.mdx | 38 +++--- schema/meta.unstable.json | 4 +- schema/schema.unstable.json | 28 +++- src/bin/generate.rs | 4 +- src/client.rs | 22 ++-- src/elicitation.rs | 56 +++++--- src/rpc.rs | 4 +- 8 files changed, 207 insertions(+), 174 deletions(-) diff --git a/docs/protocol/draft/schema.mdx b/docs/protocol/draft/schema.mdx index d9a81347..5bfdc52b 100644 --- a/docs/protocol/draft/schema.mdx +++ b/docs/protocol/draft/schema.mdx @@ -1013,87 +1013,22 @@ Clients are typically code editors (IDEs, text editors) that provide the interfa between users and AI agents. They manage the environment, handle user interactions, and control access to resources. - -### fs/read_text_file - -Reads content from a text file in the client's file system. - -Only available if the client advertises the `fs.readTextFile` capability. -Allows the agent to access file contents within the client's environment. - -See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client) - -#### ReadTextFileRequest - -Request to read content from a text file. - -Only available if the client supports the `fs.readTextFile` 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) - - - - Maximum number of lines to read. - - - Minimum: `0` - - - - Line number to start reading from (1-based). - - - Minimum: `0` - - - - Absolute path to the file to read. - -SessionId} required> - The session ID for this request. - - -#### ReadTextFileResponse - -Response containing the contents of a text file. - -**Type:** Object - -**Properties:** + +### elicitation/complete - - The _meta property is reserved by ACP to allow clients and agents to attach additional -metadata to their interactions. Implementations MUST NOT make assumptions about values at -these keys. - -See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - - - - - - -### fs/write_text_file +**UNSTABLE** -Writes content to a text file in the client's file system. +This capability is not part of the spec yet, and may be removed or changed at any point. -Only available if the client advertises the `fs.writeTextFile` capability. -Allows the agent to create or modify files within the client's environment. +Notification that a URL-based elicitation has completed. -See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client) +#### ElicitationCompleteNotification -#### WriteTextFileRequest +**UNSTABLE** -Request to write content to a text file. +This capability is not part of the spec yet, and may be removed or changed at any point. -Only available if the client supports the `fs.writeTextFile` capability. +Notification sent by the agent when a URL-based elicitation is complete. **Type:** Object @@ -1107,35 +1042,12 @@ these keys. See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) - - The text content to write to the file. - - - Absolute path to the file to write. - -SessionId} required> - The session ID for this request. - - -#### WriteTextFileResponse - -Response to `fs/write_text_file` - -**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) - +ElicitationId} required> + The ID of the elicitation that completed. - -### session/elicitation + +### elicitation/create **UNSTABLE** @@ -1153,6 +1065,7 @@ Request from the agent to elicit structured user input. The agent sends this to the client to request information from the user, either via a form or by directing them to a URL. +Elicitations may be tied to a session/request, or sent without either scope. **Type:** Union @@ -1221,22 +1134,56 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/exte The user's action in response to the elicitation. - -### session/elicitation/complete + +### fs/read_text_file -**UNSTABLE** +Reads content from a text file in the client's file system. -This capability is not part of the spec yet, and may be removed or changed at any point. +Only available if the client advertises the `fs.readTextFile` capability. +Allows the agent to access file contents within the client's environment. -Notification that a URL-based elicitation has completed. +See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client) -#### ElicitationCompleteNotification +#### ReadTextFileRequest -**UNSTABLE** +Request to read content from a text file. -This capability is not part of the spec yet, and may be removed or changed at any point. +Only available if the client supports the `fs.readTextFile` capability. -Notification sent by the agent when a URL-based elicitation is complete. +**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) + + + + Maximum number of lines to read. + + - Minimum: `0` + + + + Line number to start reading from (1-based). + + - Minimum: `0` + + + + Absolute path to the file to read. + +SessionId} required> + The session ID for this request. + + +#### ReadTextFileResponse + +Response containing the contents of a text file. **Type:** Object @@ -1250,8 +1197,62 @@ these keys. See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility) -ElicitationId} required> - The ID of the elicitation that completed. + + + + +### fs/write_text_file + +Writes content to a text file in the client's file system. + +Only available if the client advertises the `fs.writeTextFile` capability. +Allows the agent to create or modify files within the client's environment. + +See protocol docs: [Client](https://agentclientprotocol.com/protocol/overview#client) + +#### WriteTextFileRequest + +Request to write content to a text file. + +Only available if the client supports the `fs.writeTextFile` 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 text content to write to the file. + + + Absolute path to the file to write. + +SessionId} required> + The session ID for this request. + + +#### WriteTextFileResponse + +Response to `fs/write_text_file` + +**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) + diff --git a/docs/rfds/elicitation.mdx b/docs/rfds/elicitation.mdx index 0987663e..bfbae9a6 100644 --- a/docs/rfds/elicitation.mdx +++ b/docs/rfds/elicitation.mdx @@ -1,5 +1,5 @@ --- -title: "Elicitation: Structured User Input During Sessions" +title: "Elicitation: Structured User Input" --- - Author(s): [@yordis](https://github.com/yordis) @@ -7,7 +7,7 @@ title: "Elicitation: Structured User Input During Sessions" ## Elevator pitch -Add support for agents to request structured information from users during a session through a standardized elicitation mechanism, aligned with [MCP's elicitation feature](https://modelcontextprotocol.io/specification/draft/client/elicitation). This allows agents to ask follow-up questions, collect authentication credentials, gather preferences, and request required information without side-channel communication or ad-hoc client UI implementations. +Add support for agents to request structured information from users through a standardized elicitation mechanism, aligned with [MCP's elicitation feature](https://modelcontextprotocol.io/specification/draft/client/elicitation). This allows agents to ask follow-up questions, collect authentication credentials, gather preferences, and request required information without side-channel communication or ad-hoc client UI implementations. ## Status quo @@ -41,7 +41,7 @@ The mechanism would: - **Form mode** (in-band): Structured data collection via JSON Schema forms - **URL mode** (out-of-band): Browser-based flows for sensitive operations like OAuth (addressing PR #330 authentication pain points) -3. **Request/response pattern**: Agents send elicitation requests via a `session/elicitation` method and receive responses. The agent controls when to send requests and whether to wait for responses before proceeding. Unlike Session Config Options (which are persistent), elicitation requests are transient. +3. **Request/response pattern**: Agents send elicitation requests via an `elicitation/create` method and receive responses. The agent controls when to send requests and whether to wait for responses before proceeding. Unlike Session Config Options (which are persistent), elicitation requests are transient. 4. **Support client capability negotiation**: Clients declare elicitation support via a structured capability object that distinguishes between `form`-based and `url`-based elicitation (following MCP's capability model). This allows clients to support one or both modalities, enables agents to pass capabilities along to MCP servers, and handles graceful degradation when clients have limited elicitation support. @@ -70,12 +70,12 @@ Clients can: ### Alignment with MCP -This proposal follows MCP's draft elicitation specification. See [MCP Elicitation Specification](https://modelcontextprotocol.io/specification/draft/client/elicitation) for detailed guidance. ACP uses the same JSON Schema constraint approach and capability model, adapted for our session/turn-based architecture. +This proposal follows MCP's draft elicitation specification. See [MCP Elicitation Specification](https://modelcontextprotocol.io/specification/draft/client/elicitation) for detailed guidance. ACP uses the same JSON Schema constraint approach and capability model, adapted for ACP interactions. Key differences from MCP: -- MCP elicitation is tool-call-scoped; ACP elicitation is session-scoped -- ACP uses `session/elicitation` method; MCP uses `elicitation/create` +- MCP elicitation is tool-call-scoped; ACP elicitation may be request-scoped, session-scoped, or standalone +- ACP uses `elicitation/create` method (same as MCP) - ACP must integrate with existing Session Config Options (which also use schema constraints) ### Elicitation Request Structure @@ -346,7 +346,7 @@ Clients use this schema to generate appropriate input forms, validate user input ### Elicitation Request -The agent sends a `session/elicitation` request when it needs information from the user: +The agent sends an `elicitation/create` request when it needs information from the user: **Form mode example:** @@ -354,9 +354,10 @@ The agent sends a `session/elicitation` request when it needs information from t { "jsonrpc": "2.0", "id": 43, - "method": "session/elicitation", + "method": "elicitation/create", "params": { "sessionId": "...", + "requestId": 43, "mode": "form", "message": "How would you like me to approach this refactoring?", "requestedSchema": { @@ -385,9 +386,8 @@ The agent sends a `session/elicitation` request when it needs information from t { "jsonrpc": "2.0", "id": 44, - "method": "session/elicitation", + "method": "elicitation/create", "params": { - "sessionId": "...", "mode": "url", "elicitationId": "github-oauth-001", "url": "https://agent.example.com/connect?elicitationId=github-oauth-001", @@ -396,6 +396,8 @@ The agent sends a `session/elicitation` request when it needs information from t } ``` +`sessionId` and `requestId` are both optional. In general, elicitation is not required to be tied to any specific session or request. + The client presents the elicitation UI to the user. For form mode, the client generates appropriate input UI based on the JSON Schema. For URL mode, the client opens the URL in a secure browser context. ### User Response @@ -460,7 +462,7 @@ sequenceDiagram participant Agent Note over Agent: Agent initiates elicitation - Agent->>Client: session/elicitation (mode: form) + Agent->>Client: elicitation/create (mode: form) Note over User,Client: Present elicitation UI User-->>Client: Provide requested information @@ -481,7 +483,7 @@ sequenceDiagram participant Agent Note over Agent: Agent initiates elicitation - Agent->>Client: session/elicitation (mode: url) + Agent->>Client: elicitation/create (mode: url) Client->>User: Present consent to open URL User-->>Client: Provide consent @@ -491,7 +493,7 @@ sequenceDiagram Note over User,UserAgent: User interaction UserAgent-->>Agent: Interaction complete - Agent-->>Client: notifications/elicitation/complete (optional) + Agent-->>Client: elicitation/complete (optional) Note over Agent: Continue processing with new information ``` @@ -519,19 +521,19 @@ sequenceDiagram Note over User,UserAgent: User interaction UserAgent-->>Agent: Interaction complete - Agent-->>Client: notifications/elicitation/complete (optional) + Agent-->>Client: elicitation/complete (optional) Client->>Agent: Retry original request (optional) ``` ### Completion Notifications for URL Mode -Following MCP, agents MAY send a `notifications/elicitation/complete` notification when an out-of-band interaction started by URL mode elicitation is completed: +Following MCP, agents MAY send an `elicitation/complete` notification when an out-of-band interaction started by URL mode elicitation is completed: ```json { "jsonrpc": "2.0", - "method": "notifications/elicitation/complete", + "method": "elicitation/complete", "params": { "elicitationId": "github-oauth-001" } @@ -584,7 +586,7 @@ Agents MUST return standard JSON-RPC errors for common failure cases: Clients MUST return standard JSON-RPC errors for common failure cases: -- When the agent sends a `session/elicitation` request with a mode not declared in client capabilities: `-32602` (Invalid params) +- When the agent sends an `elicitation/create` request with a mode not declared in client capabilities: `-32602` (Invalid params) ### Client Capabilities @@ -725,7 +727,7 @@ From PR #330: URL-mode elicitation allows agents to request authentication witho 7. User authenticates and grants permission 8. OAuth provider redirects back to the agent's redirect_uri 9. Agent exchanges the authorization code for tokens and stores them bound to the user's identity -10. Agent sends a `notifications/elicitation/complete` notification to inform the client +10. Agent sends an `elicitation/complete` notification to inform the client **Key guarantees**: diff --git a/schema/meta.unstable.json b/schema/meta.unstable.json index 6198214a..77b13da2 100644 --- a/schema/meta.unstable.json +++ b/schema/meta.unstable.json @@ -16,10 +16,10 @@ "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_elicitation": "session/elicitation", - "session_elicitation_complete": "session/elicitation/complete", "session_request_permission": "session/request_permission", "session_update": "session/update", "terminal_create": "terminal/create", diff --git a/schema/schema.unstable.json b/schema/schema.unstable.json index 081e1a1f..345c62e2 100644 --- a/schema/schema.unstable.json +++ b/schema/schema.unstable.json @@ -1587,7 +1587,7 @@ }, "required": ["elicitationId"], "type": "object", - "x-method": "session/elicitation/complete", + "x-method": "elicitation/complete", "x-side": "client" }, "ElicitationContentValue": { @@ -1738,7 +1738,7 @@ ] }, "ElicitationRequest": { - "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.", + "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 may be tied to a session/request, or sent without either scope.", "discriminator": { "propertyName": "mode" }, @@ -1786,18 +1786,32 @@ "description": "A human-readable message describing what input is needed.", "type": "string" }, + "requestId": { + "anyOf": [ + { + "$ref": "#/$defs/RequestId" + }, + { + "type": "null" + } + ], + "description": "Optional request ID if this elicitation is tied to a specific request." + }, "sessionId": { - "allOf": [ + "anyOf": [ { "$ref": "#/$defs/SessionId" + }, + { + "type": "null" } ], - "description": "The session ID for this request." + "description": "Optional session ID if this elicitation is tied to a specific session." } }, - "required": ["sessionId", "message"], + "required": ["message"], "type": "object", - "x-method": "session/elicitation", + "x-method": "elicitation/create", "x-side": "client" }, "ElicitationResponse": { @@ -1819,7 +1833,7 @@ }, "required": ["action"], "type": "object", - "x-method": "session/elicitation", + "x-method": "elicitation/create", "x-side": "client" }, "ElicitationSchema": { diff --git a/src/bin/generate.rs b/src/bin/generate.rs index 3051d30f..5c8bdcbb 100644 --- a/src/bin/generate.rs +++ b/src/bin/generate.rs @@ -1050,9 +1050,9 @@ starting with '$/' it is free to ignore the notification." "terminal/wait_for_exit" => self.client.get("WaitForTerminalExitRequest").unwrap(), "terminal/kill" => self.client.get("KillTerminalRequest").unwrap(), #[cfg(feature = "unstable_elicitation")] - "session/elicitation" => self.client.get("ElicitationRequest").unwrap(), + "elicitation/create" => self.client.get("ElicitationRequest").unwrap(), #[cfg(feature = "unstable_elicitation")] - "session/elicitation/complete" => { + "elicitation/complete" => { self.client.get("ElicitationCompleteNotification").unwrap() } _ => panic!("Introduced a method? Add it here :)"), diff --git a/src/client.rs b/src/client.rs index ef81f671..b4731b52 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1706,12 +1706,12 @@ pub struct ClientMethodNames { pub terminal_wait_for_exit: &'static str, /// Method for killing a terminal. pub terminal_kill: &'static str, - /// Method for session elicitation. + /// Method for elicitation. #[cfg(feature = "unstable_elicitation")] - pub session_elicitation: &'static str, + pub elicitation_create: &'static str, /// Notification for elicitation completion. #[cfg(feature = "unstable_elicitation")] - pub session_elicitation_complete: &'static str, + pub elicitation_complete: &'static str, } /// Constant containing all client method names. @@ -1726,9 +1726,9 @@ pub const CLIENT_METHOD_NAMES: ClientMethodNames = ClientMethodNames { terminal_wait_for_exit: TERMINAL_WAIT_FOR_EXIT_METHOD_NAME, terminal_kill: TERMINAL_KILL_METHOD_NAME, #[cfg(feature = "unstable_elicitation")] - session_elicitation: SESSION_ELICITATION_METHOD_NAME, + elicitation_create: ELICITATION_CREATE_METHOD_NAME, #[cfg(feature = "unstable_elicitation")] - session_elicitation_complete: SESSION_ELICITATION_COMPLETE, + elicitation_complete: ELICITATION_COMPLETE, }; /// Notification name for session updates. @@ -1749,12 +1749,12 @@ pub(crate) const TERMINAL_RELEASE_METHOD_NAME: &str = "terminal/release"; pub(crate) const TERMINAL_WAIT_FOR_EXIT_METHOD_NAME: &str = "terminal/wait_for_exit"; /// Method for killing a terminal. pub(crate) const TERMINAL_KILL_METHOD_NAME: &str = "terminal/kill"; -/// Method name for session elicitation. +/// Method name for elicitation. #[cfg(feature = "unstable_elicitation")] -pub(crate) const SESSION_ELICITATION_METHOD_NAME: &str = "session/elicitation"; +pub(crate) const ELICITATION_CREATE_METHOD_NAME: &str = "elicitation/create"; /// Notification name for elicitation completion. #[cfg(feature = "unstable_elicitation")] -pub(crate) const SESSION_ELICITATION_COMPLETE: &str = "session/elicitation/complete"; +pub(crate) const ELICITATION_COMPLETE: &str = "elicitation/complete"; /// All possible requests that an agent can send to a client. /// @@ -1875,7 +1875,7 @@ impl AgentRequest { Self::WaitForTerminalExitRequest(_) => CLIENT_METHOD_NAMES.terminal_wait_for_exit, Self::KillTerminalRequest(_) => CLIENT_METHOD_NAMES.terminal_kill, #[cfg(feature = "unstable_elicitation")] - Self::ElicitationRequest(_) => CLIENT_METHOD_NAMES.session_elicitation, + Self::ElicitationRequest(_) => CLIENT_METHOD_NAMES.elicitation_create, Self::ExtMethodRequest(ext_request) => &ext_request.method, } } @@ -1953,9 +1953,7 @@ impl AgentNotification { match self { Self::SessionNotification(_) => CLIENT_METHOD_NAMES.session_update, #[cfg(feature = "unstable_elicitation")] - Self::ElicitationCompleteNotification(_) => { - CLIENT_METHOD_NAMES.session_elicitation_complete - } + Self::ElicitationCompleteNotification(_) => CLIENT_METHOD_NAMES.elicitation_complete, Self::ExtNotification(ext_notification) => &ext_notification.method, } } diff --git a/src/elicitation.rs b/src/elicitation.rs index 55b1d316..0beccedc 100644 --- a/src/elicitation.rs +++ b/src/elicitation.rs @@ -11,8 +11,8 @@ use derive_more::{Display, From}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::client::{SESSION_ELICITATION_COMPLETE, SESSION_ELICITATION_METHOD_NAME}; -use crate::{IntoOption, Meta, SessionId}; +use crate::client::{ELICITATION_COMPLETE, ELICITATION_CREATE_METHOD_NAME}; +use crate::{IntoOption, Meta, RequestId, SessionId}; /// **UNSTABLE** /// @@ -870,13 +870,18 @@ impl ElicitationUrlCapabilities { /// /// The agent sends this to the client to request information from the user, /// either via a form or by directing them to a URL. +/// Elicitations may be tied to a session/request, or sent without either scope. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] -#[schemars(extend("x-side" = "client", "x-method" = SESSION_ELICITATION_METHOD_NAME))] +#[schemars(extend("x-side" = "client", "x-method" = ELICITATION_CREATE_METHOD_NAME))] #[serde(rename_all = "camelCase")] #[non_exhaustive] pub struct ElicitationRequest { - /// The session ID for this request. - pub session_id: SessionId, + /// Optional session ID if this elicitation is tied to a specific session. + #[serde(skip_serializing_if = "Option::is_none")] + pub session_id: Option, + /// Optional request ID if this elicitation is tied to a specific request. + #[serde(skip_serializing_if = "Option::is_none")] + pub request_id: Option, /// The elicitation mode and its mode-specific fields. #[serde(flatten)] pub mode: ElicitationMode, @@ -893,19 +898,28 @@ pub struct ElicitationRequest { impl ElicitationRequest { #[must_use] - pub fn new( - session_id: impl Into, - mode: ElicitationMode, - message: impl Into, - ) -> Self { + pub fn new(mode: ElicitationMode, message: impl Into) -> Self { Self { - session_id: session_id.into(), + session_id: None, + request_id: None, mode, message: message.into(), meta: None, } } + #[must_use] + pub fn session_id(mut self, session_id: impl Into) -> Self { + self.session_id = Some(session_id.into()); + self + } + + #[must_use] + pub fn request_id(mut self, request_id: impl Into) -> Self { + self.request_id = Some(request_id.into()); + 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. @@ -986,7 +1000,7 @@ impl ElicitationUrlMode { /// /// Response from the client to an elicitation request. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] -#[schemars(extend("x-side" = "client", "x-method" = SESSION_ELICITATION_METHOD_NAME))] +#[schemars(extend("x-side" = "client", "x-method" = ELICITATION_CREATE_METHOD_NAME))] #[serde(rename_all = "camelCase")] #[non_exhaustive] pub struct ElicitationResponse { @@ -1139,7 +1153,7 @@ impl Default for ElicitationAcceptAction { /// /// Notification sent by the agent when a URL-based elicitation is complete. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[schemars(extend("x-side" = "client", "x-method" = SESSION_ELICITATION_COMPLETE))] +#[schemars(extend("x-side" = "client", "x-method" = ELICITATION_COMPLETE))] #[serde(rename_all = "camelCase")] #[non_exhaustive] pub struct ElicitationCompleteNotification { @@ -1251,13 +1265,13 @@ mod tests { fn form_mode_request_serialization() { let schema = ElicitationSchema::new().string("name", true); let req = ElicitationRequest::new( - "sess_1", ElicitationMode::Form(ElicitationFormMode::new(schema)), "Please enter your name", ); let json = serde_json::to_value(&req).unwrap(); - assert_eq!(json["sessionId"], "sess_1"); + assert!(json.get("sessionId").is_none()); + assert!(json.get("requestId").is_none()); assert_eq!(json["mode"], "form"); assert_eq!(json["message"], "Please enter your name"); assert!(json["requestedSchema"].is_object()); @@ -1268,7 +1282,8 @@ mod tests { ); let roundtripped: ElicitationRequest = serde_json::from_value(json).unwrap(); - assert_eq!(roundtripped.session_id, SessionId::new("sess_1")); + assert_eq!(roundtripped.session_id, None); + assert_eq!(roundtripped.request_id, None); assert_eq!(roundtripped.message, "Please enter your name"); assert!(matches!(roundtripped.mode, ElicitationMode::Form(_))); } @@ -1276,23 +1291,26 @@ mod tests { #[test] fn url_mode_request_serialization() { let req = ElicitationRequest::new( - "sess_2", ElicitationMode::Url(ElicitationUrlMode::new( "elic_1", "https://example.com/auth", )), "Please authenticate", - ); + ) + .session_id("sess_2") + .request_id(42i64); let json = serde_json::to_value(&req).unwrap(); assert_eq!(json["sessionId"], "sess_2"); + assert_eq!(json["requestId"], 42); assert_eq!(json["mode"], "url"); assert_eq!(json["elicitationId"], "elic_1"); assert_eq!(json["url"], "https://example.com/auth"); assert_eq!(json["message"], "Please authenticate"); let roundtripped: ElicitationRequest = serde_json::from_value(json).unwrap(); - assert_eq!(roundtripped.session_id, SessionId::new("sess_2")); + assert_eq!(roundtripped.session_id, Some(SessionId::new("sess_2"))); + assert_eq!(roundtripped.request_id, Some(RequestId::Number(42))); assert!(matches!(roundtripped.mode, ElicitationMode::Url(_))); } diff --git a/src/rpc.rs b/src/rpc.rs index 868087ee..105da671 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -216,7 +216,7 @@ impl Side for ClientSide { .map_err(Into::into) } #[cfg(feature = "unstable_elicitation")] - m if m == CLIENT_METHOD_NAMES.session_elicitation => serde_json::from_str(params.get()) + m if m == CLIENT_METHOD_NAMES.elicitation_create => serde_json::from_str(params.get()) .map(AgentRequest::ElicitationRequest) .map_err(Into::into), _ => { @@ -240,7 +240,7 @@ impl Side for ClientSide { .map(AgentNotification::SessionNotification) .map_err(Into::into), #[cfg(feature = "unstable_elicitation")] - m if m == CLIENT_METHOD_NAMES.session_elicitation_complete => { + m if m == CLIENT_METHOD_NAMES.elicitation_complete => { serde_json::from_str(params.get()) .map(AgentNotification::ElicitationCompleteNotification) .map_err(Into::into)