fix: match shape of the calltoolresult schema (#377)
BREAKING CHANGE: makes the `content` field non-optional
This commit is contained in:
parent
81ff3159f9
commit
a47cbaac4b
1 changed files with 26 additions and 29 deletions
|
|
@ -183,7 +183,7 @@ impl<'de> Deserialize<'de> for ProtocolVersion {
|
|||
pub enum NumberOrString {
|
||||
/// A numeric identifier
|
||||
Number(u32),
|
||||
/// A string identifier
|
||||
/// A string identifier
|
||||
String(Arc<str>),
|
||||
}
|
||||
|
||||
|
|
@ -1257,8 +1257,7 @@ pub type CreateElicitationRequest =
|
|||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct CallToolResult {
|
||||
/// The content returned by the tool (text, images, etc.)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub content: Option<Vec<Content>>,
|
||||
pub content: Vec<Content>,
|
||||
/// An optional JSON object that represents the structured result of the tool call
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub structured_content: Option<Value>,
|
||||
|
|
@ -1271,7 +1270,7 @@ impl CallToolResult {
|
|||
/// Create a successful tool result with unstructured content
|
||||
pub fn success(content: Vec<Content>) -> Self {
|
||||
CallToolResult {
|
||||
content: Some(content),
|
||||
content,
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
}
|
||||
|
|
@ -1279,7 +1278,7 @@ impl CallToolResult {
|
|||
/// Create an error tool result with unstructured content
|
||||
pub fn error(content: Vec<Content>) -> Self {
|
||||
CallToolResult {
|
||||
content: Some(content),
|
||||
content,
|
||||
structured_content: None,
|
||||
is_error: Some(true),
|
||||
}
|
||||
|
|
@ -1300,7 +1299,7 @@ impl CallToolResult {
|
|||
/// ```
|
||||
pub fn structured(value: Value) -> Self {
|
||||
CallToolResult {
|
||||
content: Some(vec![Content::text(value.to_string())]),
|
||||
content: vec![Content::text(value.to_string())],
|
||||
structured_content: Some(value),
|
||||
is_error: Some(false),
|
||||
}
|
||||
|
|
@ -1325,7 +1324,7 @@ impl CallToolResult {
|
|||
/// ```
|
||||
pub fn structured_error(value: Value) -> Self {
|
||||
CallToolResult {
|
||||
content: Some(vec![Content::text(value.to_string())]),
|
||||
content: vec![Content::text(value.to_string())],
|
||||
structured_content: Some(value),
|
||||
is_error: Some(true),
|
||||
}
|
||||
|
|
@ -1341,10 +1340,10 @@ impl CallToolResult {
|
|||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let raw_text = match (self.structured_content, &self.content) {
|
||||
let raw_text = match (self.structured_content, &self.content.first()) {
|
||||
(Some(value), _) => return serde_json::from_value(value),
|
||||
(None, Some(contents)) => {
|
||||
if let Some(text) = contents.first().and_then(|c| c.as_text()) {
|
||||
if let Some(text) = contents.as_text() {
|
||||
let text = &text.text;
|
||||
Some(text)
|
||||
} else {
|
||||
|
|
@ -1379,13 +1378,13 @@ impl<'de> Deserialize<'de> for CallToolResult {
|
|||
|
||||
let helper = CallToolResultHelper::deserialize(deserializer)?;
|
||||
let result = CallToolResult {
|
||||
content: helper.content,
|
||||
content: helper.content.unwrap_or_default(),
|
||||
structured_content: helper.structured_content,
|
||||
is_error: helper.is_error,
|
||||
};
|
||||
|
||||
// Validate mutual exclusivity
|
||||
if result.content.is_none() && result.structured_content.is_none() {
|
||||
if result.content.is_empty() && result.structured_content.is_none() {
|
||||
return Err(serde::de::Error::custom(
|
||||
"CallToolResult must have either content or structured_content",
|
||||
));
|
||||
|
|
|
|||
Loading…
Reference in a new issue