@@ -1566,9 +1566,12 @@ impl SessionConfigSelect {
15661566/// This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
15671567/// session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
15681568/// placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
1569- /// categories gracefully (treat as `Other`).
1569+ /// categories gracefully.
1570+ ///
1571+ /// Category names beginning with `_` are free for custom use, like other ACP extension methods.
1572+ /// Category names that do not begin with `_` are reserved for the ACP spec.
15701573#[ cfg( feature = "unstable_session_config_options" ) ]
1571- #[ derive( Debug , Clone , Copy , Serialize , Deserialize , JsonSchema , PartialEq , Eq ) ]
1574+ #[ derive( Debug , Clone , Serialize , Deserialize , JsonSchema , PartialEq , Eq ) ]
15721575#[ serde( rename_all = "snake_case" ) ]
15731576#[ non_exhaustive]
15741577pub enum SessionConfigOptionCategory {
@@ -1579,8 +1582,8 @@ pub enum SessionConfigOptionCategory {
15791582 /// Thought/reasoning level selector.
15801583 ThoughtLevel ,
15811584 /// Unknown / uncategorized selector.
1582- #[ serde( other ) ]
1583- Other ,
1585+ #[ serde( untagged ) ]
1586+ Other ( String ) ,
15841587}
15851588
15861589/// **UNSTABLE**
@@ -2108,7 +2111,7 @@ impl PromptRequest {
21082111/// Response from processing a user prompt.
21092112///
21102113/// See protocol docs: [Check for Completion](https://agentclientprotocol.com/protocol/prompt-turn#4-check-for-completion)
2111- #[ derive( Debug , Clone , Serialize , Deserialize , JsonSchema , PartialEq ) ]
2114+ #[ derive( Debug , Clone , Serialize , Deserialize , JsonSchema , PartialEq , Eq ) ]
21122115#[ schemars( extend( "x-side" = "agent" , "x-method" = SESSION_PROMPT_METHOD_NAME ) ) ]
21132116#[ serde( rename_all = "camelCase" ) ]
21142117#[ non_exhaustive]
@@ -2170,15 +2173,6 @@ pub enum StopReason {
21702173 /// Agents should catch these exceptions and return this semantically meaningful
21712174 /// response to confirm successful cancellation.
21722175 Cancelled ,
2173- /// **UNSTABLE**
2174- ///
2175- /// The turn ended because the agent is waiting for user input via elicitation.
2176- /// The agent will send a separate `session/elicitation` request.
2177- ///
2178- /// This feature is unstable and may change.
2179- #[ serde( rename = "elicitation_requested" ) ]
2180- #[ cfg( feature = "unstable_elicitation" ) ]
2181- ElicitationRequested ,
21822176}
21832177
21842178// Model
@@ -2449,6 +2443,13 @@ impl AgentCapabilities {
24492443 self
24502444 }
24512445
2446+ /// Session capabilities supported by the agent.
2447+ #[ must_use]
2448+ pub fn session_capabilities ( mut self , session_capabilities : SessionCapabilities ) -> Self {
2449+ self . session_capabilities = session_capabilities;
2450+ self
2451+ }
2452+
24522453 /// The _meta property is reserved by ACP to allow clients and agents to attach additional
24532454 /// metadata to their interactions. Implementations MUST NOT make assumptions about values at
24542455 /// these keys.
@@ -2816,9 +2817,6 @@ pub struct AgentMethodNames {
28162817 pub session_set_config_option : & ' static str ,
28172818 /// Method for sending a prompt to the agent.
28182819 pub session_prompt : & ' static str ,
2819- /// Method for requesting elicitation (structured user input).
2820- #[ cfg( feature = "unstable_elicitation" ) ]
2821- pub session_elicitation : & ' static str ,
28222820 /// Notification for cancelling operations.
28232821 pub session_cancel : & ' static str ,
28242822 /// Method for selecting a model for a given session.
@@ -2845,8 +2843,6 @@ pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
28452843 #[ cfg( feature = "unstable_session_config_options" ) ]
28462844 session_set_config_option : SESSION_SET_CONFIG_OPTION_METHOD_NAME ,
28472845 session_prompt : SESSION_PROMPT_METHOD_NAME ,
2848- #[ cfg( feature = "unstable_elicitation" ) ]
2849- session_elicitation : SESSION_ELICITATION_METHOD_NAME ,
28502846 session_cancel : SESSION_CANCEL_METHOD_NAME ,
28512847 #[ cfg( feature = "unstable_session_model" ) ]
28522848 session_set_model : SESSION_SET_MODEL_METHOD_NAME ,
@@ -2873,9 +2869,6 @@ pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
28732869pub ( crate ) const SESSION_SET_CONFIG_OPTION_METHOD_NAME : & str = "session/set_config_option" ;
28742870/// Method name for sending a prompt.
28752871pub ( crate ) const SESSION_PROMPT_METHOD_NAME : & str = "session/prompt" ;
2876- /// Method name for requesting elicitation (structured user input).
2877- #[ cfg( feature = "unstable_elicitation" ) ]
2878- pub ( crate ) const SESSION_ELICITATION_METHOD_NAME : & str = "session/elicitation" ;
28792872/// Method name for the cancel notification.
28802873pub ( crate ) const SESSION_CANCEL_METHOD_NAME : & str = "session/cancel" ;
28812874/// Method name for selecting a model for a given session.
@@ -3309,4 +3302,75 @@ mod test_serialization {
33093302 _ => panic ! ( "Expected Sse variant" ) ,
33103303 }
33113304 }
3305+
3306+ #[ test]
3307+ #[ cfg( feature = "unstable_session_config_options" ) ]
3308+ fn test_session_config_option_category_known_variants ( ) {
3309+ // Test serialization of known variants
3310+ assert_eq ! (
3311+ serde_json:: to_value( & SessionConfigOptionCategory :: Mode ) . unwrap( ) ,
3312+ json!( "mode" )
3313+ ) ;
3314+ assert_eq ! (
3315+ serde_json:: to_value( & SessionConfigOptionCategory :: Model ) . unwrap( ) ,
3316+ json!( "model" )
3317+ ) ;
3318+ assert_eq ! (
3319+ serde_json:: to_value( & SessionConfigOptionCategory :: ThoughtLevel ) . unwrap( ) ,
3320+ json!( "thought_level" )
3321+ ) ;
3322+
3323+ // Test deserialization of known variants
3324+ assert_eq ! (
3325+ serde_json:: from_str:: <SessionConfigOptionCategory >( "\" mode\" " ) . unwrap( ) ,
3326+ SessionConfigOptionCategory :: Mode
3327+ ) ;
3328+ assert_eq ! (
3329+ serde_json:: from_str:: <SessionConfigOptionCategory >( "\" model\" " ) . unwrap( ) ,
3330+ SessionConfigOptionCategory :: Model
3331+ ) ;
3332+ assert_eq ! (
3333+ serde_json:: from_str:: <SessionConfigOptionCategory >( "\" thought_level\" " ) . unwrap( ) ,
3334+ SessionConfigOptionCategory :: ThoughtLevel
3335+ ) ;
3336+ }
3337+
3338+ #[ test]
3339+ #[ cfg( feature = "unstable_session_config_options" ) ]
3340+ fn test_session_config_option_category_unknown_variants ( ) {
3341+ // Test that unknown strings are captured in Other variant
3342+ let unknown: SessionConfigOptionCategory =
3343+ serde_json:: from_str ( "\" some_future_category\" " ) . unwrap ( ) ;
3344+ assert_eq ! (
3345+ unknown,
3346+ SessionConfigOptionCategory :: Other ( "some_future_category" . to_string( ) )
3347+ ) ;
3348+
3349+ // Test round-trip of unknown category
3350+ let json = serde_json:: to_value ( & unknown) . unwrap ( ) ;
3351+ assert_eq ! ( json, json!( "some_future_category" ) ) ;
3352+ }
3353+
3354+ #[ test]
3355+ #[ cfg( feature = "unstable_session_config_options" ) ]
3356+ fn test_session_config_option_category_custom_categories ( ) {
3357+ // Category names beginning with `_` are free for custom use
3358+ let custom: SessionConfigOptionCategory =
3359+ serde_json:: from_str ( "\" _my_custom_category\" " ) . unwrap ( ) ;
3360+ assert_eq ! (
3361+ custom,
3362+ SessionConfigOptionCategory :: Other ( "_my_custom_category" . to_string( ) )
3363+ ) ;
3364+
3365+ // Test round-trip preserves the custom category name
3366+ let json = serde_json:: to_value ( & custom) . unwrap ( ) ;
3367+ assert_eq ! ( json, json!( "_my_custom_category" ) ) ;
3368+
3369+ // Deserialize back and verify
3370+ let deserialized: SessionConfigOptionCategory = serde_json:: from_value ( json) . unwrap ( ) ;
3371+ assert_eq ! (
3372+ deserialized,
3373+ SessionConfigOptionCategory :: Other ( "_my_custom_category" . to_string( ) )
3374+ ) ;
3375+ }
33123376}
0 commit comments