Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/protocol/v1/draft/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4185,7 +4185,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d

## <span class="font-mono">EnumOption</span>

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

Expand All @@ -4194,6 +4194,9 @@ A titled enum option with a const value and human-readable title.
<ResponseField name="const" type={"string"} required>
The constant value for this option.
</ResponseField>
<ResponseField name="description" type={"string | null"}>
Optional description for this option value.
</ResponseField>
<ResponseField name="title" type={"string"} required>
Human-readable title for this option.
</ResponseField>
Expand Down
5 changes: 4 additions & 1 deletion docs/protocol/v2/draft/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3784,7 +3784,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v2/d

## <span class="font-mono">EnumOption</span>

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

Expand All @@ -3793,6 +3793,9 @@ A titled enum option with a const value and human-readable title.
<ResponseField name="const" type={"string"} required>
The constant value for this option.
</ResponseField>
<ResponseField name="description" type={"string | null"}>
Optional description for this option value.
</ResponseField>
<ResponseField name="title" type={"string"} required>
Human-readable title for this option.
</ResponseField>
Expand Down
66 changes: 54 additions & 12 deletions docs/rfds/elicitation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
}
Expand Down Expand Up @@ -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"]
Expand Down Expand Up @@ -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"
}
Expand Down
6 changes: 5 additions & 1 deletion schema/v1/schema.unstable.json
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,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": {
Expand All @@ -1519,6 +1519,10 @@
"title": {
"description": "Human-readable title for this option.",
"type": "string"
},
"description": {
"description": "Optional description for this option value.",
"type": ["string", "null"]
}
},
"required": ["const", "title"]
Expand Down
6 changes: 5 additions & 1 deletion schema/v2/schema.unstable.json
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,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": {
Expand All @@ -1704,6 +1704,10 @@
"title": {
"description": "Human-readable title for this option.",
"type": "string"
},
"description": {
"description": "Optional description for this option value.",
"type": ["string", "null"]
}
},
"required": ["const", "title"]
Expand Down
25 changes: 22 additions & 3 deletions src/v1/elicitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ 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]
pub struct EnumOption {
Expand All @@ -69,6 +70,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<String>,
}

impl EnumOption {
Expand All @@ -78,8 +81,16 @@ impl EnumOption {
Self {
value: value.into(),
title: title.into(),
description: None,
}
}

/// Optional description for this option value.
#[must_use]
pub fn description(mut self, description: impl IntoOption<String>) -> Self {
self.description = description.into_option();
self
}
}

/// Schema for string properties in an elicitation form.
Expand Down Expand Up @@ -1763,7 +1774,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,
Expand All @@ -1775,12 +1786,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");
}
Expand Down
14 changes: 12 additions & 2 deletions src/v2/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7347,10 +7347,15 @@ impl IntoV1 for super::EnumOption {
type Output = crate::v1::EnumOption;

fn into_v1(self) -> Result<Self::Output> {
let Self { value, title } = self;
let Self {
value,
title,
description,
} = self;
Ok(crate::v1::EnumOption {
value: value.into_v1()?,
title: title.into_v1()?,
description: description.into_v1()?,
})
}
}
Expand All @@ -7360,10 +7365,15 @@ impl IntoV2 for crate::v1::EnumOption {
type Output = super::EnumOption;

fn into_v2(self) -> Result<Self::Output> {
let Self { value, title } = self;
let Self {
value,
title,
description,
} = self;
Ok(super::EnumOption {
value: value.into_v2()?,
title: title.into_v2()?,
description: description.into_v2()?,
})
}
}
Expand Down
25 changes: 22 additions & 3 deletions src/v2/elicitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ 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]
pub struct EnumOption {
Expand All @@ -76,6 +77,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<String>,
}

impl EnumOption {
Expand All @@ -85,8 +88,16 @@ impl EnumOption {
Self {
value: value.into(),
title: title.into(),
description: None,
}
}

/// Optional description for this option value.
#[must_use]
pub fn description(mut self, description: impl IntoOption<String>) -> Self {
self.description = description.into_option();
self
}
}

/// Schema for string properties in an elicitation form.
Expand Down Expand Up @@ -1767,7 +1778,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,
Expand All @@ -1779,12 +1790,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");
}
Expand Down