Fix empty tool results from resource content (e.g. auto visualiser) (#7866)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::mcp_utils::extract_text_from_resource;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use crate::providers::errors::ProviderError;
|
||||
@@ -142,7 +143,18 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
|
||||
let text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| c.as_text().map(|t| t.text.clone()))
|
||||
.filter_map(|c| {
|
||||
if let Some(t) = c.as_text() {
|
||||
return Some(t.text.clone());
|
||||
}
|
||||
if let Some(r) = c.as_resource() {
|
||||
let text = extract_text_from_resource(&r.resource);
|
||||
if !text.is_empty() {
|
||||
return Some(text);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
@@ -1170,6 +1182,70 @@ mod tests {
|
||||
assert_eq!(assistant_content[0]["type"], "tool_use");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_response_with_resource_content() {
|
||||
use rmcp::model::{CallToolResult, Content};
|
||||
|
||||
let resource_content = Content::embedded_text(
|
||||
"file:///test/file.txt",
|
||||
"This is the file content from a resource",
|
||||
);
|
||||
|
||||
let messages = vec![
|
||||
Message::assistant().with_tool_request(
|
||||
"tool_1",
|
||||
Ok(CallToolRequestParams::new("view_file")
|
||||
.with_arguments(object!({"path": "/test/file.txt"}))),
|
||||
),
|
||||
Message::user().with_tool_response(
|
||||
"tool_1",
|
||||
Ok(CallToolResult::success(vec![resource_content])),
|
||||
),
|
||||
];
|
||||
|
||||
let spec = format_messages(&messages);
|
||||
|
||||
assert_eq!(spec.len(), 2);
|
||||
assert_eq!(spec[1]["role"], "user");
|
||||
assert_eq!(spec[1]["content"][0]["type"], "tool_result");
|
||||
assert_eq!(spec[1]["content"][0]["tool_use_id"], "tool_1");
|
||||
assert_eq!(
|
||||
spec[1]["content"][0]["content"],
|
||||
"This is the file content from a resource"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_response_with_mixed_content() {
|
||||
use rmcp::model::{CallToolResult, Content};
|
||||
|
||||
let text_content = Content::text("Summary: file loaded");
|
||||
let resource_content = Content::embedded_text("file:///test/file.txt", "File content here");
|
||||
|
||||
let messages = vec![
|
||||
Message::assistant().with_tool_request(
|
||||
"tool_1",
|
||||
Ok(CallToolRequestParams::new("view_file")
|
||||
.with_arguments(object!({"path": "/test/file.txt"}))),
|
||||
),
|
||||
Message::user().with_tool_response(
|
||||
"tool_1",
|
||||
Ok(CallToolResult::success(vec![
|
||||
text_content,
|
||||
resource_content,
|
||||
])),
|
||||
),
|
||||
];
|
||||
|
||||
let spec = format_messages(&messages);
|
||||
|
||||
assert_eq!(spec[1]["content"][0]["type"], "tool_result");
|
||||
assert_eq!(
|
||||
spec[1]["content"][0]["content"],
|
||||
"Summary: file loaded\nFile content here"
|
||||
);
|
||||
}
|
||||
|
||||
fn cfg(name: &str) -> ModelConfig {
|
||||
ModelConfig {
|
||||
model_name: name.to_string(),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::conversation::message::{Message, MessageContent};
|
||||
use crate::mcp_utils::extract_text_from_resource;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::base::Usage;
|
||||
use crate::providers::errors::ProviderError;
|
||||
@@ -38,7 +39,18 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
|
||||
let text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| c.as_text().map(|t| t.text.clone()))
|
||||
.filter_map(|c| {
|
||||
if let Some(t) = c.as_text() {
|
||||
return Some(t.text.clone());
|
||||
}
|
||||
if let Some(r) = c.as_resource() {
|
||||
let text = extract_text_from_resource(&r.resource);
|
||||
if !text.is_empty() {
|
||||
return Some(text);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user