Tool reply meta (#6074)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -74,9 +74,10 @@ impl ClaudeCodeProvider {
|
||||
}
|
||||
}
|
||||
MessageContent::ToolResponse(tool_response) => {
|
||||
if let Ok(tool_contents) = &tool_response.tool_result {
|
||||
if let Ok(result) = &tool_response.tool_result {
|
||||
// Convert tool result contents to text
|
||||
let content_text = tool_contents
|
||||
let content_text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|content| match &content.raw {
|
||||
rmcp::model::RawContent::Text(text_content) => {
|
||||
|
||||
@@ -86,8 +86,9 @@ impl CursorAgentProvider {
|
||||
}
|
||||
}
|
||||
MessageContent::ToolResponse(tool_response) => {
|
||||
if let Ok(tool_contents) = &tool_response.tool_result {
|
||||
let content_text = tool_contents
|
||||
if let Ok(result) = &tool_response.tool_result {
|
||||
let content_text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|content| match &content.raw {
|
||||
rmcp::model::RawContent::Text(text_content) => {
|
||||
|
||||
@@ -68,6 +68,7 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
|
||||
MessageContent::ToolResponse(tool_response) => match &tool_response.tool_result {
|
||||
Ok(result) => {
|
||||
let text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| c.as_text().map(|t| t.text.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
@@ -86,8 +86,9 @@ pub fn to_bedrock_message_content(content: &MessageContent) -> Result<bedrock::C
|
||||
}
|
||||
MessageContent::ToolResponse(tool_res) => {
|
||||
let content = match &tool_res.tool_result {
|
||||
Ok(content) => Some(
|
||||
content
|
||||
Ok(result) => Some(
|
||||
result
|
||||
.content
|
||||
.iter()
|
||||
// Filter out content items that have User in their audience
|
||||
.filter(|c| {
|
||||
@@ -318,6 +319,12 @@ pub fn from_bedrock_content_block(block: &bedrock::ContentBlock) -> Result<Messa
|
||||
.iter()
|
||||
.map(from_bedrock_tool_result_content_block)
|
||||
.collect::<ToolResult<Vec<_>>>()
|
||||
.map(|content| rmcp::model::CallToolResult {
|
||||
content,
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
})
|
||||
},
|
||||
),
|
||||
_ => bail!("Unsupported content block type from Bedrock"),
|
||||
|
||||
@@ -133,9 +133,10 @@ fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<Data
|
||||
}
|
||||
MessageContent::ToolResponse(response) => {
|
||||
match &response.tool_result {
|
||||
Ok(contents) => {
|
||||
Ok(call_result) => {
|
||||
// Send only contents with no audience or with Assistant in the audience
|
||||
let abridged: Vec<_> = contents
|
||||
let abridged: Vec<_> = call_result
|
||||
.content
|
||||
.iter()
|
||||
.filter(|content| {
|
||||
content
|
||||
@@ -638,6 +639,7 @@ pub fn create_request(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::model::CallToolResult;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
|
||||
@@ -727,8 +729,15 @@ mod tests {
|
||||
panic!("should be tool request");
|
||||
};
|
||||
|
||||
messages
|
||||
.push(Message::user().with_tool_response(tool_id, Ok(vec![Content::text("Result")])));
|
||||
messages.push(Message::user().with_tool_response(
|
||||
tool_id,
|
||||
Ok(CallToolResult {
|
||||
content: vec![Content::text("Result")],
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
}),
|
||||
));
|
||||
|
||||
let as_value =
|
||||
serde_json::to_value(format_messages(&messages, &ImageFormat::OpenAi)).unwrap();
|
||||
@@ -764,8 +773,15 @@ mod tests {
|
||||
panic!("should be tool request");
|
||||
};
|
||||
|
||||
messages
|
||||
.push(Message::user().with_tool_response(tool_id, Ok(vec![Content::text("Result")])));
|
||||
messages.push(Message::user().with_tool_response(
|
||||
tool_id,
|
||||
Ok(CallToolResult {
|
||||
content: vec![Content::text("Result")],
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
}),
|
||||
));
|
||||
|
||||
let as_value =
|
||||
serde_json::to_value(format_messages(&messages, &ImageFormat::OpenAi)).unwrap();
|
||||
|
||||
@@ -70,9 +70,10 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
|
||||
},
|
||||
MessageContent::ToolResponse(response) => {
|
||||
match &response.tool_result {
|
||||
Ok(contents) => {
|
||||
Ok(result) => {
|
||||
// Send only contents with no audience or with Assistant in the audience
|
||||
let abridged: Vec<_> = contents
|
||||
let abridged: Vec<_> = result
|
||||
.content
|
||||
.iter()
|
||||
.filter(|content| {
|
||||
content.audience().is_none_or(|audience| {
|
||||
@@ -394,7 +395,7 @@ pub fn create_request(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::model::CallToolRequestParam;
|
||||
use rmcp::model::{CallToolRequestParam, CallToolResult};
|
||||
use rmcp::{model::Content, object};
|
||||
use serde_json::json;
|
||||
|
||||
@@ -429,7 +430,12 @@ mod tests {
|
||||
0,
|
||||
vec![MessageContent::tool_response(
|
||||
id.to_string(),
|
||||
Ok(tool_response),
|
||||
Ok(CallToolResult {
|
||||
content: tool_response,
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
}),
|
||||
)],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -128,9 +128,10 @@ pub fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<
|
||||
},
|
||||
MessageContent::ToolResponse(response) => {
|
||||
match &response.tool_result {
|
||||
Ok(contents) => {
|
||||
Ok(result) => {
|
||||
// Send only contents with no audience or with Assistant in the audience
|
||||
let abridged: Vec<_> = contents
|
||||
let abridged: Vec<_> = result
|
||||
.content
|
||||
.iter()
|
||||
.filter(|content| {
|
||||
content
|
||||
@@ -710,6 +711,7 @@ pub fn create_request(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::message::Message;
|
||||
use rmcp::model::CallToolResult;
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
use tokio::pin;
|
||||
@@ -868,8 +870,15 @@ mod tests {
|
||||
panic!("should be tool request");
|
||||
};
|
||||
|
||||
messages
|
||||
.push(Message::user().with_tool_response(tool_id, Ok(vec![Content::text("Result")])));
|
||||
messages.push(Message::user().with_tool_response(
|
||||
tool_id,
|
||||
Ok(CallToolResult {
|
||||
content: vec![Content::text("Result")],
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
}),
|
||||
));
|
||||
|
||||
let spec = format_messages(&messages, &ImageFormat::OpenAi);
|
||||
|
||||
@@ -904,8 +913,15 @@ mod tests {
|
||||
panic!("should be tool request");
|
||||
};
|
||||
|
||||
messages
|
||||
.push(Message::user().with_tool_response(tool_id, Ok(vec![Content::text("Result")])));
|
||||
messages.push(Message::user().with_tool_response(
|
||||
tool_id,
|
||||
Ok(CallToolResult {
|
||||
content: vec![Content::text("Result")],
|
||||
structured_content: None,
|
||||
is_error: Some(false),
|
||||
meta: None,
|
||||
}),
|
||||
));
|
||||
|
||||
let spec = format_messages(&messages, &ImageFormat::OpenAi);
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
|
||||
MessageContent::ToolResponse(tool_response) => {
|
||||
if let Ok(result) = &tool_response.tool_result {
|
||||
let text = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| c.as_text().map(|t| t.text.clone()))
|
||||
.collect::<Vec<_>>()
|
||||
|
||||
@@ -215,9 +215,9 @@ impl LeadWorkerProvider {
|
||||
if let Err(tool_error) = &tool_response.tool_result {
|
||||
failure_indicators += 1;
|
||||
tracing::debug!("Tool execution failure detected: {:?}", tool_error);
|
||||
} else if let Ok(contents) = &tool_response.tool_result {
|
||||
} else if let Ok(result) = &tool_response.tool_result {
|
||||
// Check tool output for error indicators
|
||||
if self.contains_error_indicators(contents) {
|
||||
if self.contains_error_indicators(&result.content) {
|
||||
failure_indicators += 1;
|
||||
tracing::debug!("Tool output contains error indicators");
|
||||
}
|
||||
|
||||
@@ -343,8 +343,9 @@ pub fn convert_tool_messages_to_text(messages: &[Message]) -> Conversation {
|
||||
has_tool_content = true;
|
||||
// Convert tool response to text format
|
||||
let text = match &res.tool_result {
|
||||
Ok(contents) => {
|
||||
let text_contents: Vec<String> = contents
|
||||
Ok(result) => {
|
||||
let text_contents: Vec<String> = result
|
||||
.content
|
||||
.iter()
|
||||
.filter_map(|c| match c.deref() {
|
||||
RawContent::Text(t) => Some(t.text.clone()),
|
||||
|
||||
Reference in New Issue
Block a user