diff --git a/agent-client-protocol-schema/src/v1/elicitation.rs b/agent-client-protocol-schema/src/v1/elicitation.rs index 234c348b..d9bb3eb9 100644 --- a/agent-client-protocol-schema/src/v1/elicitation.rs +++ b/agent-client-protocol-schema/src/v1/elicitation.rs @@ -63,7 +63,7 @@ pub enum ElicitationSchemaType { Object, } -/// A titled enum option with a const value and human-readable title. +/// A titled enum option with a const value, human-readable title, and optional description. #[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[non_exhaustive] @@ -73,6 +73,8 @@ pub struct EnumOption { pub value: String, /// Human-readable title for this option. pub title: String, + /// Optional description for this option value. + pub description: 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. @@ -89,10 +91,18 @@ impl EnumOption { Self { value: value.into(), title: title.into(), + description: None, meta: None, } } + /// Optional description for this option value. + #[must_use] + pub fn description(mut self, description: impl IntoOption) -> Self { + self.description = description.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. @@ -1970,7 +1980,7 @@ mod tests { let schema = ElicitationSchema::new().property( "country", StringPropertySchema::new().one_of(vec![ - EnumOption::new("us", "United States"), + EnumOption::new("us", "United States").description("Use US English spelling."), EnumOption::new("uk", "United Kingdom"), ]), true, @@ -1982,12 +1992,20 @@ mod tests { assert_eq!(one_of.len(), 2); assert_eq!(one_of[0]["const"], "us"); assert_eq!(one_of[0]["title"], "United States"); + assert_eq!(one_of[0]["description"], "Use US English spelling."); + assert!(one_of[1].get("description").is_none()); let roundtripped: ElicitationSchema = serde_json::from_value(json).unwrap(); if let ElicitationPropertySchema::String(s) = roundtripped.properties.get("country").unwrap() { - assert_eq!(s.one_of.as_ref().unwrap().len(), 2); + let one_of = s.one_of.as_ref().unwrap(); + assert_eq!(one_of.len(), 2); + assert_eq!( + one_of[0].description.as_deref(), + Some("Use US English spelling.") + ); + assert!(one_of[1].description.is_none()); } else { panic!("expected String variant"); } diff --git a/agent-client-protocol-schema/src/v2/conversion.rs b/agent-client-protocol-schema/src/v2/conversion.rs index 23bcb015..ef28b577 100644 --- a/agent-client-protocol-schema/src/v2/conversion.rs +++ b/agent-client-protocol-schema/src/v2/conversion.rs @@ -7520,10 +7520,16 @@ impl IntoV1 for super::EnumOption { type Output = crate::v1::EnumOption; fn into_v1(self) -> Result { - let Self { value, title, meta } = self; + let Self { + value, + title, + description, + meta, + } = self; Ok(crate::v1::EnumOption { value: value.into_v1()?, title: title.into_v1()?, + description: description.into_v1()?, meta: meta.into_v1()?, }) } @@ -7534,10 +7540,16 @@ impl IntoV2 for crate::v1::EnumOption { type Output = super::EnumOption; fn into_v2(self) -> Result { - let Self { value, title, meta } = self; + let Self { + value, + title, + description, + meta, + } = self; Ok(super::EnumOption { value: value.into_v2()?, title: title.into_v2()?, + description: description.into_v2()?, meta: meta.into_v2()?, }) } diff --git a/agent-client-protocol-schema/src/v2/elicitation.rs b/agent-client-protocol-schema/src/v2/elicitation.rs index 295424f1..96ddc6eb 100644 --- a/agent-client-protocol-schema/src/v2/elicitation.rs +++ b/agent-client-protocol-schema/src/v2/elicitation.rs @@ -68,7 +68,7 @@ pub enum ElicitationSchemaType { Object, } -/// A titled enum option with a const value and human-readable title. +/// A titled enum option with a const value, human-readable title, and optional description. #[skip_serializing_none] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[non_exhaustive] @@ -78,6 +78,8 @@ pub struct EnumOption { pub value: String, /// Human-readable title for this option. pub title: String, + /// Optional description for this option value. + pub description: 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. @@ -94,10 +96,18 @@ impl EnumOption { Self { value: value.into(), title: title.into(), + description: None, meta: None, } } + /// Optional description for this option value. + #[must_use] + pub fn description(mut self, description: impl IntoOption) -> Self { + self.description = description.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. @@ -1966,7 +1976,7 @@ mod tests { let schema = ElicitationSchema::new().property( "country", StringPropertySchema::new().one_of(vec![ - EnumOption::new("us", "United States"), + EnumOption::new("us", "United States").description("Use US English spelling."), EnumOption::new("uk", "United Kingdom"), ]), true, @@ -1978,12 +1988,20 @@ mod tests { assert_eq!(one_of.len(), 2); assert_eq!(one_of[0]["const"], "us"); assert_eq!(one_of[0]["title"], "United States"); + assert_eq!(one_of[0]["description"], "Use US English spelling."); + assert!(one_of[1].get("description").is_none()); let roundtripped: ElicitationSchema = serde_json::from_value(json).unwrap(); if let ElicitationPropertySchema::String(s) = roundtripped.properties.get("country").unwrap() { - assert_eq!(s.one_of.as_ref().unwrap().len(), 2); + let one_of = s.one_of.as_ref().unwrap(); + assert_eq!(one_of.len(), 2); + assert_eq!( + one_of[0].description.as_deref(), + Some("Use US English spelling.") + ); + assert!(one_of[1].description.is_none()); } else { panic!("expected String variant"); } diff --git a/docs/protocol/v1/draft/schema.mdx b/docs/protocol/v1/draft/schema.mdx index bfac724a..008e1297 100644 --- a/docs/protocol/v1/draft/schema.mdx +++ b/docs/protocol/v1/draft/schema.mdx @@ -4294,7 +4294,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d ## EnumOption -A titled enum option with a const value and human-readable title. +A titled enum option with a const value, human-readable title, and optional description. **Type:** Object @@ -4311,6 +4311,9 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d The constant value for this option. + + Optional description for this option value. + Human-readable title for this option. diff --git a/docs/protocol/v2/draft/schema.mdx b/docs/protocol/v2/draft/schema.mdx index 83ee14b4..a2d800c8 100644 --- a/docs/protocol/v2/draft/schema.mdx +++ b/docs/protocol/v2/draft/schema.mdx @@ -3885,7 +3885,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/d ## EnumOption -A titled enum option with a const value and human-readable title. +A titled enum option with a const value, human-readable title, and optional description. **Type:** Object @@ -3902,6 +3902,9 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/d The constant value for this option. + + Optional description for this option value. + Human-readable title for this option. diff --git a/docs/rfds/elicitation.mdx b/docs/rfds/elicitation.mdx index ab69c108..72f3d692 100644 --- a/docs/rfds/elicitation.mdx +++ b/docs/rfds/elicitation.mdx @@ -99,12 +99,18 @@ Agents send elicitation requests when they need information from the user. This "oneOf": [ { "const": "conservative", - "title": "Conservative - Minimal changes" + "title": "Conservative - Minimal changes", + "description": "Make minimal changes and avoid broad cleanup." + }, + { + "const": "balanced", + "title": "Balanced (Recommended)", + "description": "Fix the issue and clean nearby code when it lowers risk." }, - { "const": "balanced", "title": "Balanced (Recommended)" }, { "const": "aggressive", - "title": "Aggressive - Maximum optimization" + "title": "Aggressive - Maximum optimization", + "description": "Refactor more broadly to optimize the affected area." } ], "default": "balanced" @@ -269,9 +275,21 @@ Single-select enum (with titles): "title": "Color Selection", "description": "Choose your favorite color", "oneOf": [ - { "const": "#FF0000", "title": "Red" }, - { "const": "#00FF00", "title": "Green" }, - { "const": "#0000FF", "title": "Blue" } + { + "const": "#FF0000", + "title": "Red", + "description": "High emphasis and warning-oriented." + }, + { + "const": "#00FF00", + "title": "Green", + "description": "Positive status and success-oriented." + }, + { + "const": "#0000FF", + "title": "Blue", + "description": "Neutral and informational." + } ], "default": "#FF0000" } @@ -305,9 +323,21 @@ Multi-select enum (with titles): "maxItems": 2, "items": { "anyOf": [ - { "const": "#FF0000", "title": "Red" }, - { "const": "#00FF00", "title": "Green" }, - { "const": "#0000FF", "title": "Blue" } + { + "const": "#FF0000", + "title": "Red", + "description": "High emphasis and warning-oriented." + }, + { + "const": "#00FF00", + "title": "Green", + "description": "Positive status and success-oriented." + }, + { + "const": "#0000FF", + "title": "Blue", + "description": "Neutral and informational." + } ] }, "default": ["#FF0000", "#00FF00"] @@ -368,9 +398,21 @@ The agent sends an `elicitation/create` request when it needs information from t "type": "string", "title": "Refactoring Strategy", "oneOf": [ - { "const": "conservative", "title": "Conservative" }, - { "const": "balanced", "title": "Balanced (Recommended)" }, - { "const": "aggressive", "title": "Aggressive" } + { + "const": "conservative", + "title": "Conservative", + "description": "Make minimal changes and avoid broad cleanup." + }, + { + "const": "balanced", + "title": "Balanced (Recommended)", + "description": "Fix the issue and clean nearby code when it lowers risk." + }, + { + "const": "aggressive", + "title": "Aggressive", + "description": "Refactor more broadly to optimize the affected area." + } ], "default": "balanced" } diff --git a/schema/v1/schema.unstable.json b/schema/v1/schema.unstable.json index d4cc569f..af41d91f 100644 --- a/schema/v1/schema.unstable.json +++ b/schema/v1/schema.unstable.json @@ -1595,7 +1595,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": { @@ -1606,6 +1606,10 @@ "description": "Human-readable title for this option.", "type": "string" }, + "description": { + "description": "Optional description for this option value.", + "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"], diff --git a/schema/v2/schema.unstable.json b/schema/v2/schema.unstable.json index 0badad84..648dbe27 100644 --- a/schema/v2/schema.unstable.json +++ b/schema/v2/schema.unstable.json @@ -1811,7 +1811,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": { @@ -1822,6 +1822,10 @@ "description": "Human-readable title for this option.", "type": "string" }, + "description": { + "description": "Optional description for this option value.", + "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"],