diff --git a/Cargo.lock b/Cargo.lock index 9ebd3d4..e986e5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,9 +138,8 @@ dependencies = [ [[package]] name = "agent-client-protocol-schema" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac542aba230234b1591ace7286a47c0514fe3efc3037d43296bde31ba7ee5728" +version = "1.2.0" +source = "git+https://github.com/daniel-agentee/agent-client-protocol?rev=064ee1ffe194cdb14e1d45d66875ce74a14933c3#064ee1ffe194cdb14e1d45d66875ce74a14933c3" dependencies = [ "anyhow", "derive_more", diff --git a/Cargo.toml b/Cargo.toml index 8db2927..d429488 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ agent-client-protocol-trace-viewer = { path = "src/agent-client-protocol-trace-v yopo = { package = "agent-client-protocol-yopo", path = "src/yopo" } # Protocol -agent-client-protocol-schema = { version = "=1.1.0", features = ["tracing"] } +agent-client-protocol-schema = { version = "=1.2.0", features = ["tracing"] } # Core async runtime tokio = { version = "1.52", default-features = false } @@ -113,3 +113,7 @@ struct_field_names = "allow" too_many_lines = "allow" type_complexity = "allow" wildcard_imports = "allow" + +[patch.crates-io] +# Temporary: consume session/setTitle schema types before they are released. +agent-client-protocol-schema = { git = "https://github.com/daniel-agentee/agent-client-protocol", rev = "064ee1ffe194cdb14e1d45d66875ce74a14933c3" } diff --git a/src/agent-client-protocol-test/src/testy.rs b/src/agent-client-protocol-test/src/testy.rs index 55d97d1..570047e 100644 --- a/src/agent-client-protocol-test/src/testy.rs +++ b/src/agent-client-protocol-test/src/testy.rs @@ -31,7 +31,7 @@ use agent_client_protocol::schema::v1::{ CompleteElicitationNotification, CreateElicitationRequest, ElicitationAction, ElicitationCapabilities, ElicitationFormMode, ElicitationRequestScope, ElicitationSchema, ElicitationSessionScope, ElicitationUrlMode, ErrorCode, MultiSelectPropertySchema, RequestId, - StringPropertySchema, UrlElicitationRequiredData, UrlElicitationRequiredItem, + StringPropertySchema, }; use agent_client_protocol::{ Agent, Client, ConnectTo, ConnectionTo, JsonRpcRequest, Responder, SentRequest, @@ -637,7 +637,7 @@ impl Testy { Err(error) => { self.finish_prompt(&session_id, StopReason::EndTurn); #[cfg(feature = "unstable")] - if error.code == ErrorCode::UrlElicitationRequired { + if is_url_elicitation_required_error(&error) { return responder.respond_with_error(error); } return Err(error); @@ -1765,15 +1765,28 @@ fn elicitation_cancelled(agent: &Testy, session_id: &SessionId, report: &mut Vec #[cfg(feature = "unstable")] fn url_elicitation_required_error() -> agent_client_protocol::Error { - let data = UrlElicitationRequiredData::new(vec![UrlElicitationRequiredItem::new( - "testy-url-required", - "https://example.com/testy/required", - "Complete the Testy URL elicitation before continuing", - )]); - match serde_json::to_value(data) { - Ok(data) => agent_client_protocol::Error::url_elicitation_required().data(data), - Err(error) => agent_client_protocol::Error::into_internal_error(error), - } + agent_client_protocol::Error::invalid_params().data(url_elicitation_required_data()) +} + +#[cfg(feature = "unstable")] +fn is_url_elicitation_required_error(error: &agent_client_protocol::Error) -> bool { + error.code == ErrorCode::InvalidParams + && error + .data + .as_ref() + .is_some_and(|data| data.get("elicitations").is_some()) +} + +#[cfg(feature = "unstable")] +fn url_elicitation_required_data() -> serde_json::Value { + serde_json::json!({ + "elicitations": [{ + "mode": "url", + "elicitationId": "testy-url-required", + "url": "https://example.com/testy/required", + "message": "Complete the Testy URL elicitation before continuing" + }] + }) } fn send_session_update( diff --git a/src/agent-client-protocol-test/tests/testy.rs b/src/agent-client-protocol-test/tests/testy.rs index cdfc0bf..0c2c7fc 100644 --- a/src/agent-client-protocol-test/tests/testy.rs +++ b/src/agent-client-protocol-test/tests/testy.rs @@ -12,7 +12,7 @@ use agent_client_protocol::schema::v1::{ CompleteElicitationNotification, CreateElicitationRequest, CreateElicitationResponse, ElicitationAcceptAction, ElicitationAction, ElicitationCapabilities, ElicitationContentValue, ElicitationFormCapabilities, ElicitationMode, ElicitationScope, ElicitationUrlCapabilities, - ErrorCode, UrlElicitationRequiredData, + ErrorCode, }; use agent_client_protocol::{ Client, Responder, @@ -1958,18 +1958,18 @@ async fn testy_callbacks_with_unstable_feature_returns_url_required_when_url_eli .block_task() .await .expect_err("url-required elicitation scenario should fail the prompt request"); - assert_eq!(error.code, ErrorCode::UrlElicitationRequired); - - let data: UrlElicitationRequiredData = - serde_json::from_value(error.data.expect("url-required error should include data")) - .expect("url-required error data should deserialize"); - assert_eq!(data.elicitations.len(), 1); - let elicitation = &data.elicitations[0]; - assert_eq!(elicitation.elicitation_id.to_string(), "testy-url-required"); - assert_eq!(elicitation.url, "https://example.com/testy/required"); + assert_eq!(error.code, ErrorCode::InvalidParams); + assert_eq!( - elicitation.message, - "Complete the Testy URL elicitation before continuing" + error.data.expect("url-required error should include data"), + serde_json::json!({ + "elicitations": [{ + "mode": "url", + "elicitationId": "testy-url-required", + "url": "https://example.com/testy/required", + "message": "Complete the Testy URL elicitation before continuing" + }] + }) ); Ok(()) }) diff --git a/src/agent-client-protocol/src/capabilities.rs b/src/agent-client-protocol/src/capabilities.rs index 21517fa..1718f08 100644 --- a/src/agent-client-protocol/src/capabilities.rs +++ b/src/agent-client-protocol/src/capabilities.rs @@ -142,7 +142,7 @@ mod tests { #[test] fn test_add_capability_to_request() { - let request = InitializeRequest::new(ProtocolVersion::LATEST); + let request = InitializeRequest::new(ProtocolVersion::V1); let request = request.add_meta_capability(TestCapability); @@ -165,8 +165,8 @@ mod tests { ); let client_capabilities = ClientCapabilities::new().meta(meta); - let request = InitializeRequest::new(ProtocolVersion::LATEST) - .client_capabilities(client_capabilities); + let request = + InitializeRequest::new(ProtocolVersion::V1).client_capabilities(client_capabilities); let request = request.remove_meta_capability(TestCapability); @@ -175,7 +175,7 @@ mod tests { #[test] fn test_add_capability_to_response() { - let response = InitializeResponse::new(ProtocolVersion::LATEST); + let response = InitializeResponse::new(ProtocolVersion::V1); let response = response.add_meta_capability(TestCapability); @@ -198,8 +198,8 @@ mod tests { ); let client_capabilities = ClientCapabilities::new().meta(meta); - let request = InitializeRequest::new(ProtocolVersion::LATEST) - .client_capabilities(client_capabilities); + let request = + InitializeRequest::new(ProtocolVersion::V1).client_capabilities(client_capabilities); assert!(!request.has_meta_capability(TestCapability)); } @@ -216,8 +216,8 @@ mod tests { ); let client_capabilities = ClientCapabilities::new().meta(meta); - let request = InitializeRequest::new(ProtocolVersion::LATEST) - .client_capabilities(client_capabilities); + let request = + InitializeRequest::new(ProtocolVersion::V1).client_capabilities(client_capabilities); assert!(!request.has_meta_capability(TestCapability)); } diff --git a/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs b/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs index cbca8fe..8626457 100644 --- a/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs +++ b/src/agent-client-protocol/src/jsonrpc/protocol_compat.rs @@ -536,7 +536,11 @@ mod imp { } fn public_to_v2_message(message: UntypedMessage) -> Result { - let UntypedMessage { method, params } = message; + let UntypedMessage { method, mut params } = message; + + if method == "initialize" { + ensure_legacy_initialize_info(&mut params, "clientInfo"); + } if let Some(message) = try_convert_message_to_v2::(&method, ¶ms)? { return Ok(message); @@ -573,8 +577,12 @@ mod imp { fn public_to_v2_response( method: &str, - value: serde_json::Value, + mut value: serde_json::Value, ) -> Result { + if method == "initialize" { + ensure_legacy_initialize_info(&mut value, "agentInfo"); + } + if let Some(value) = try_convert_response_to_v2::(method, &value)? { return Ok(value); } @@ -585,6 +593,27 @@ mod imp { Ok(value) } + fn ensure_legacy_initialize_info(value: &mut serde_json::Value, field: &str) { + let serde_json::Value::Object(object) = value else { + return; + }; + + let needs_default = match object.get(field) { + Some(value) => value.is_null(), + None => true, + }; + + if needs_default { + object.insert( + field.into(), + serde_json::json!({ + "name": "legacy-acp-peer", + "version": "unknown", + }), + ); + } + } + fn v2_to_public_response( method: &str, value: serde_json::Value, @@ -728,6 +757,10 @@ mod imp { .negotiated } + fn v2_implementation() -> v2::Implementation { + v2::Implementation::new("rust-sdk-test", "0.0.0") + } + #[test] fn initialize_request_sets_active_wire_version_before_response() -> Result<(), crate::Error> { @@ -736,7 +769,7 @@ mod imp { compat.incoming_message(UntypedMessage::new( "initialize", - v2::InitializeRequest::new(ProtocolVersion::V2), + v2::InitializeRequest::new(ProtocolVersion::V2, v2_implementation()), )?)?; assert_eq!(negotiated(&compat), ProtocolVersionKind::V1); @@ -746,6 +779,7 @@ mod imp { "initialize", Ok(serde_json::to_value(v2::InitializeResponse::new( ProtocolVersion::V2, + v2_implementation(), ))?), )?; @@ -762,7 +796,7 @@ mod imp { compat.outgoing_message(UntypedMessage::new( "initialize", - v2::InitializeRequest::new(ProtocolVersion::V1), + v2::InitializeRequest::new(ProtocolVersion::V1, v2_implementation()), )?)?; assert_eq!(negotiated(&compat), ProtocolVersionKind::V1); @@ -772,6 +806,7 @@ mod imp { "initialize", Ok(serde_json::to_value(v2::InitializeResponse::new( ProtocolVersion::V2, + v2_implementation(), ))?), )?; @@ -788,7 +823,7 @@ mod imp { compat.outgoing_message(UntypedMessage::new( "initialize", - v2::InitializeRequest::new(ProtocolVersion::V1), + v2::InitializeRequest::new(ProtocolVersion::V1, v2_implementation()), )?)?; assert_eq!(negotiated(&compat), ProtocolVersionKind::V1); @@ -814,7 +849,7 @@ mod imp { let compat = ProtocolCompat::new(ProtocolMode::v2_client()); compat.outgoing_message(UntypedMessage::new( "initialize", - v2::InitializeRequest::new(ProtocolVersion::V1), + v2::InitializeRequest::new(ProtocolVersion::V1, v2_implementation()), )?)?; let error = compat @@ -838,7 +873,7 @@ mod imp { let compat = ProtocolCompat::new(ProtocolMode::v2_agent()); let messages = compat.outgoing_notification(UntypedMessage::new( "session/update", - v2::SessionNotification::new( + v2::UpdateSessionNotification::new( "sess", v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent").content( vec![ diff --git a/src/agent-client-protocol/src/schema/client_to_agent/requests.rs b/src/agent-client-protocol/src/schema/client_to_agent/requests.rs index 7a4f233..d7bb5eb 100644 --- a/src/agent-client-protocol/src/schema/client_to_agent/requests.rs +++ b/src/agent-client-protocol/src/schema/client_to_agent/requests.rs @@ -5,6 +5,7 @@ use crate::schema::v1::{ LogoutRequest, LogoutResponse, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, SetSessionModeRequest, SetSessionModeResponse, + SetSessionTitleRequest, SetSessionTitleResponse, }; #[cfg(feature = "unstable_session_fork")] use crate::schema::v1::{ForkSessionRequest, ForkSessionResponse}; @@ -31,6 +32,11 @@ impl_jsonrpc_request!( SetSessionConfigOptionResponse, "session/set_config_option" ); +impl_jsonrpc_request!( + SetSessionTitleRequest, + SetSessionTitleResponse, + "session/setTitle" +); #[cfg(feature = "unstable_session_fork")] impl_jsonrpc_request!(ForkSessionRequest, ForkSessionResponse, "session/fork"); diff --git a/src/agent-client-protocol/src/schema/enum_impls.rs b/src/agent-client-protocol/src/schema/enum_impls.rs index 680158b..b730ddc 100644 --- a/src/agent-client-protocol/src/schema/enum_impls.rs +++ b/src/agent-client-protocol/src/schema/enum_impls.rs @@ -24,6 +24,7 @@ impl_jsonrpc_request_enum!(ClientRequest { CloseSessionRequest => "session/close", SetSessionModeRequest => "session/set_mode", SetSessionConfigOptionRequest => "session/set_config_option", + SetSessionTitleRequest => "session/setTitle", PromptRequest => "session/prompt", #[cfg(feature = "unstable_mcp_over_acp")] MessageMcpRequest => "mcp/message", diff --git a/src/agent-client-protocol/src/schema/v2_impls.rs b/src/agent-client-protocol/src/schema/v2_impls.rs index d87ad71..73883bd 100644 --- a/src/agent-client-protocol/src/schema/v2_impls.rs +++ b/src/agent-client-protocol/src/schema/v2_impls.rs @@ -107,10 +107,10 @@ macro_rules! impl_v2_jsonrpc_request_enum { if method.starts_with('_') { crate::util::json_cast_params(params).map( |ext_req: v2::ExtRequest| { - Self::$ext_variant(v2::ExtRequest::new( + Self::$ext_variant(Box::new(v2::ExtRequest::new( method.to_string(), ext_req.params, - )) + ))) }, ) } else { @@ -159,10 +159,10 @@ macro_rules! impl_v2_jsonrpc_notification_enum { if method.starts_with('_') { crate::util::json_cast_params(params).map( |ext_notif: v2::ExtNotification| { - Self::$ext_variant(v2::ExtNotification::new( + Self::$ext_variant(Box::new(v2::ExtNotification::new( method.to_string(), ext_notif.params, - )) + ))) }, ) } else { @@ -210,12 +210,8 @@ macro_rules! impl_v2_jsonrpc_response_enum { } impl_v2_jsonrpc_request!(v2::InitializeRequest, v2::InitializeResponse, "initialize"); -impl_v2_jsonrpc_request!( - v2::AuthenticateRequest, - v2::AuthenticateResponse, - "authenticate" -); -impl_v2_jsonrpc_request!(v2::LogoutRequest, v2::LogoutResponse, "logout"); +impl_v2_jsonrpc_request!(v2::LoginAuthRequest, v2::LoginAuthResponse, "auth/login"); +impl_v2_jsonrpc_request!(v2::LogoutAuthRequest, v2::LogoutAuthResponse, "auth/logout"); impl_v2_jsonrpc_request!(v2::NewSessionRequest, v2::NewSessionResponse, "session/new"); impl_v2_jsonrpc_request!( v2::LoadSessionRequest, @@ -248,6 +244,11 @@ impl_v2_jsonrpc_request!( v2::CloseSessionResponse, "session/close" ); +impl_v2_jsonrpc_request!( + v2::SetSessionTitleRequest, + v2::SetSessionTitleResponse, + "session/setTitle" +); impl_v2_jsonrpc_request!( v2::SetSessionConfigOptionRequest, v2::SetSessionConfigOptionResponse, @@ -259,7 +260,7 @@ impl_v2_jsonrpc_request!(v2::MessageMcpRequest, v2::MessageMcpResponse, "mcp/mes #[cfg(feature = "unstable_cancel_request")] impl_v2_jsonrpc_notification!(v2::CancelRequestNotification, "$/cancel_request"); -impl_v2_jsonrpc_notification!(v2::CancelNotification, "session/cancel"); +impl_v2_jsonrpc_notification!(v2::CancelSessionNotification, "session/cancel"); #[cfg(feature = "unstable_mcp_over_acp")] impl_v2_jsonrpc_notification!(v2::MessageMcpNotification, "mcp/message"); @@ -283,7 +284,7 @@ impl_v2_jsonrpc_request!( "mcp/disconnect" ); -impl_v2_jsonrpc_notification!(v2::SessionNotification, "session/update"); +impl_v2_jsonrpc_notification!(v2::UpdateSessionNotification, "session/update"); #[cfg(feature = "unstable_elicitation")] impl_v2_jsonrpc_notification!(v2::CompleteElicitationNotification, "elicitation/complete"); @@ -294,8 +295,8 @@ impl_jsonrpc_protocol_level_notification_enum!(v2::ProtocolLevelNotification { impl_v2_jsonrpc_request_enum!(v2::ClientRequest { InitializeRequest => "initialize", - AuthenticateRequest => "authenticate", - LogoutRequest => "logout", + LoginAuthRequest => "auth/login", + LogoutAuthRequest => "auth/logout", NewSessionRequest => "session/new", LoadSessionRequest => "session/load", ListSessionsRequest => "session/list", @@ -304,6 +305,7 @@ impl_v2_jsonrpc_request_enum!(v2::ClientRequest { ForkSessionRequest => "session/fork", ResumeSessionRequest => "session/resume", CloseSessionRequest => "session/close", + SetSessionTitleRequest => "session/setTitle", SetSessionConfigOptionRequest => "session/set_config_option", PromptRequest => "session/prompt", #[cfg(feature = "unstable_mcp_over_acp")] @@ -313,8 +315,8 @@ impl_v2_jsonrpc_request_enum!(v2::ClientRequest { impl_v2_jsonrpc_response_enum!(v2::AgentResponse { InitializeResponse => "initialize", - AuthenticateResponse => "authenticate", - LogoutResponse => "logout", + LoginAuthResponse => "auth/login", + LogoutAuthResponse => "auth/logout", NewSessionResponse => "session/new", LoadSessionResponse => "session/load", ListSessionsResponse => "session/list", @@ -323,6 +325,7 @@ impl_v2_jsonrpc_response_enum!(v2::AgentResponse { ForkSessionResponse => "session/fork", ResumeSessionResponse => "session/resume", CloseSessionResponse => "session/close", + SetSessionTitleResponse => "session/setTitle", SetSessionConfigOptionResponse => "session/set_config_option", PromptResponse => "session/prompt", #[cfg(feature = "unstable_mcp_over_acp")] @@ -331,7 +334,7 @@ impl_v2_jsonrpc_response_enum!(v2::AgentResponse { }); impl_v2_jsonrpc_notification_enum!(v2::ClientNotification { - CancelNotification => "session/cancel", + CancelSessionNotification => "session/cancel", #[cfg(feature = "unstable_mcp_over_acp")] MessageMcpNotification => "mcp/message", [ext] ExtNotification, @@ -364,7 +367,7 @@ impl_v2_jsonrpc_response_enum!(v2::ClientResponse { }); impl_v2_jsonrpc_notification_enum!(v2::AgentNotification { - SessionNotification => "session/update", + UpdateSessionNotification => "session/update", #[cfg(feature = "unstable_elicitation")] CompleteElicitationNotification => "elicitation/complete", #[cfg(feature = "unstable_mcp_over_acp")] diff --git a/src/agent-client-protocol/tests/protocol_v2.rs b/src/agent-client-protocol/tests/protocol_v2.rs index f05f032..994d02e 100644 --- a/src/agent-client-protocol/tests/protocol_v2.rs +++ b/src/agent-client-protocol/tests/protocol_v2.rs @@ -49,10 +49,14 @@ fn cwd() -> Result { std::env::current_dir().map_err(Error::into_internal_error) } +fn v2_implementation() -> v2::Implementation { + v2::Implementation::new("rust-sdk-test", "0.0.0") +} + fn v2_initialize_response_with_session( protocol_version: ProtocolVersion, ) -> v2::InitializeResponse { - v2::InitializeResponse::new(protocol_version) + v2::InitializeResponse::new(protocol_version, v2_implementation()) .capabilities(v2::AgentCapabilities::new().session(v2::SessionCapabilities::new())) } @@ -110,7 +114,10 @@ async fn assert_v2_client_rejected_by_v1_agent(agent: impl ConnectTo) -> .v2() .connect_with(agent, async |cx| { let error = cx - .send_request(v2::InitializeRequest::new(ProtocolVersion::V2)) + .send_request(v2::InitializeRequest::new( + ProtocolVersion::V2, + v2_implementation(), + )) .block_task() .await .expect_err("v1 agent protocol mode should reject v2 clients"); @@ -173,7 +180,10 @@ async fn role_builder_v1_agent_rejects_v2_client_negotiation() -> Result<(), Err .v2() .connect_with(agent, async |cx| { let error = cx - .send_request(v2::InitializeRequest::new(ProtocolVersion::V2)) + .send_request(v2::InitializeRequest::new( + ProtocolVersion::V2, + v2_implementation(), + )) .block_task() .await .expect_err("Role::builder should preserve v1 agent protocol mode"); @@ -499,7 +509,10 @@ async fn v2_client_rejects_v1_agent() -> Result<(), Error> { .v2() .connect_with(Testy::new(), async |cx| { let error = cx - .send_request(v2::InitializeRequest::new(ProtocolVersion::V1)) + .send_request(v2::InitializeRequest::new( + ProtocolVersion::V1, + v2_implementation(), + )) .block_task() .await .expect_err("v2 clients require a v2 agent"); @@ -524,7 +537,9 @@ async fn v2_client_and_agent_negotiate_v2() -> Result<(), Error> { .on_receive_request( async |initialize: v2::InitializeRequest, responder, _cx| { assert_eq!(initialize.protocol_version, ProtocolVersion::V2); - responder.respond(v2::InitializeResponse::new(initialize.protocol_version)) + responder.respond(v2_initialize_response_with_session( + initialize.protocol_version, + )) }, agent_client_protocol::on_receive_request!(), ) @@ -542,7 +557,10 @@ async fn v2_client_and_agent_negotiate_v2() -> Result<(), Error> { .v2() .connect_with(agent, async |cx| { let initialize = cx - .send_request(v2::InitializeRequest::new(ProtocolVersion::V1)) + .send_request(v2::InitializeRequest::new( + ProtocolVersion::V1, + v2_implementation(), + )) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V2); @@ -596,7 +614,10 @@ async fn v2_client_can_cancel_request_to_v2_agent() -> Result<(), Error> { .v2() .connect_with(v2_agent_with_cancellable_new_session(), async |cx| { let initialize = cx - .send_request(v2::InitializeRequest::new(ProtocolVersion::V2)) + .send_request(v2::InitializeRequest::new( + ProtocolVersion::V2, + v2_implementation(), + )) .block_task() .await?; assert_eq!(initialize.protocol_version, ProtocolVersion::V2); diff --git a/src/agent-client-protocol/tests/schema_elicitation.rs b/src/agent-client-protocol/tests/schema_elicitation.rs index 8ea8dc9..c6ec56d 100644 --- a/src/agent-client-protocol/tests/schema_elicitation.rs +++ b/src/agent-client-protocol/tests/schema_elicitation.rs @@ -4,8 +4,7 @@ use agent_client_protocol::schema::v1::{ AgentNotification, AgentRequest, ClientCapabilities, ClientResponse, CompleteElicitationNotification, CreateElicitationRequest, CreateElicitationResponse, ElicitationAction, ElicitationCapabilities, ElicitationFormCapabilities, ElicitationFormMode, - ElicitationSchema, ElicitationSessionScope, ElicitationUrlCapabilities, Error, ErrorCode, - UrlElicitationRequiredData, UrlElicitationRequiredItem, + ElicitationSchema, ElicitationSessionScope, ElicitationUrlCapabilities, Error, }; use agent_client_protocol::{JsonRpcMessage, JsonRpcNotification, JsonRpcRequest, JsonRpcResponse}; use serde::Serialize; @@ -123,29 +122,6 @@ fn client_capabilities_can_declare_elicitation_modes() { assert!(parsed.elicitation.is_some()); } -#[test] -fn url_elicitation_required_error_helper_is_available() { - let data = UrlElicitationRequiredData::new(vec![UrlElicitationRequiredItem::new( - "elicit_1", - "https://example.com/connect", - "Connect your account", - )]); - let error = Error::url_elicitation_required().data(json_value(data).unwrap()); - - assert_eq!(error.code, ErrorCode::UrlElicitationRequired); - assert_eq!( - error.data.unwrap(), - json!({ - "elicitations": [{ - "mode": "url", - "elicitationId": "elicit_1", - "url": "https://example.com/connect", - "message": "Connect your account" - }] - }) - ); -} - #[cfg(feature = "unstable_protocol_v2")] #[test] fn protocol_v2_elicitation_variants_are_jsonrpc_mapped() -> Result<(), Error> { @@ -191,10 +167,14 @@ async fn v2_agent_can_elicit_from_v1_client_before_prompt_completion() -> Result use agent_client_protocol::{Agent, Client}; use std::collections::BTreeMap; + fn v2_implementation() -> v2::Implementation { + v2::Implementation::new("rust-sdk-test", "0.0.0") + } + fn v2_initialize_response_with_session( protocol_version: ProtocolVersion, ) -> v2::InitializeResponse { - v2::InitializeResponse::new(protocol_version) + v2::InitializeResponse::new(protocol_version, v2_implementation()) .capabilities(v2::AgentCapabilities::new().session(v2::SessionCapabilities::new())) }