Replace mcp_core::content types with rmcp::model types (#3500)
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
use goose::message::{Message, MessageContent, ToolRequest, ToolResponse};
|
||||
use goose::utils::safe_truncate;
|
||||
use mcp_core::content::Content as McpContent;
|
||||
use mcp_core::resource::ResourceContents;
|
||||
use rmcp::model::Role;
|
||||
use rmcp::model::{RawContent, ResourceContents, Role};
|
||||
use serde_json::Value;
|
||||
|
||||
const MAX_STRING_LENGTH_MD_EXPORT: usize = 4096; // Generous limit for export
|
||||
@@ -219,8 +217,8 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
||||
}
|
||||
}
|
||||
|
||||
match content {
|
||||
McpContent::Text(text_content) => {
|
||||
match &content.raw {
|
||||
RawContent::Text(text_content) => {
|
||||
let trimmed_text = text_content.text.trim();
|
||||
if (trimmed_text.starts_with('{') && trimmed_text.ends_with('}'))
|
||||
|| (trimmed_text.starts_with('[') && trimmed_text.ends_with(']'))
|
||||
@@ -236,7 +234,7 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
||||
md.push_str("\n\n");
|
||||
}
|
||||
}
|
||||
McpContent::Image(image_content) => {
|
||||
RawContent::Image(image_content) => {
|
||||
if image_content.mime_type.starts_with("image/") {
|
||||
// For actual images, provide a placeholder that indicates it's an image
|
||||
md.push_str(&format!(
|
||||
@@ -252,7 +250,7 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
||||
));
|
||||
}
|
||||
}
|
||||
McpContent::Resource(resource) => {
|
||||
RawContent::Resource(resource) => {
|
||||
match &resource.resource {
|
||||
ResourceContents::TextResourceContents {
|
||||
uri,
|
||||
@@ -299,6 +297,9 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
RawContent::Audio(_) => {
|
||||
md.push_str("[audio content not displayed in Markdown export]\n\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,8 +361,8 @@ pub fn message_to_markdown(message: &Message, export_all_content: bool) -> Strin
|
||||
mod tests {
|
||||
use super::*;
|
||||
use goose::message::{Message, ToolRequest, ToolResponse};
|
||||
use mcp_core::content::{Content as McpContent, TextContent};
|
||||
use mcp_core::tool::ToolCall;
|
||||
use rmcp::model::{Content, RawTextContent, TextContent};
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
@@ -521,12 +522,14 @@ mod tests {
|
||||
#[test]
|
||||
fn test_tool_response_to_markdown_text() {
|
||||
let text_content = TextContent {
|
||||
text: "Command executed successfully".to_string(),
|
||||
raw: RawTextContent {
|
||||
text: "Command executed successfully".to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "test-id".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -538,12 +541,14 @@ mod tests {
|
||||
fn test_tool_response_to_markdown_json() {
|
||||
let json_text = r#"{"status": "success", "data": "test"}"#;
|
||||
let text_content = TextContent {
|
||||
text: json_text.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: json_text.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "test-id".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -640,12 +645,14 @@ if __name__ == "__main__":
|
||||
hello_world()"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: python_code.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: python_code.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "shell-cat".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
@@ -677,12 +684,14 @@ if __name__ == "__main__":
|
||||
|
||||
let git_output = " M src/main.rs\n?? temp.txt\n A new_feature.rs";
|
||||
let text_content = TextContent {
|
||||
text: git_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: git_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "git-status".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
@@ -722,12 +731,14 @@ warning: unused variable `x`
|
||||
Finished dev [unoptimized + debuginfo] target(s) in 2.45s"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: build_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: build_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "cargo-build".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let response_result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -765,12 +776,14 @@ warning: unused variable `x`
|
||||
}"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: api_response.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: api_response.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "curl-api".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let response_result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -797,12 +810,14 @@ warning: unused variable `x`
|
||||
};
|
||||
|
||||
let text_content = TextContent {
|
||||
text: "File created successfully".to_string(),
|
||||
raw: RawTextContent {
|
||||
text: "File created successfully".to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "editor-write".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
@@ -850,12 +865,14 @@ def process_data(data: List[Dict]) -> List[Dict]:
|
||||
return [item for item in data if item.get('active', False)]"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: python_code.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: python_code.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "editor-view".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let response_result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -883,12 +900,14 @@ def process_data(data: List[Dict]) -> List[Dict]:
|
||||
Command failed with exit code 2"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: error_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: error_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "shell-error".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let response_result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -919,12 +938,14 @@ Command failed with exit code 2"#;
|
||||
5^2 = 25"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: script_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: script_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "script-exec".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
@@ -962,12 +983,14 @@ drwx------ 3 user staff 96 Dec 6 16:20 com.apple.launchd.abc
|
||||
/tmp"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: multi_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: multi_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "multi-cmd".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&_tool_request, true);
|
||||
@@ -1001,12 +1024,14 @@ src/database.rs:23:async fn query_users(pool: &Pool) -> Result<Vec<User>> {
|
||||
src/middleware.rs:12:async fn auth_middleware(req: Request, next: Next) -> Result<Response> {"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: grep_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: grep_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "grep-search".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
@@ -1037,12 +1062,14 @@ src/middleware.rs:12:async fn auth_middleware(req: Request, next: Next) -> Resul
|
||||
|
||||
let json_output = r#"{"status": "success", "data": {"count": 42}}"#;
|
||||
let text_content = TextContent {
|
||||
text: json_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: json_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "json-test".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let response_result = tool_response_to_markdown(&tool_response, true);
|
||||
@@ -1074,12 +1101,14 @@ src/middleware.rs:12:async fn auth_middleware(req: Request, next: Next) -> Resul
|
||||
found 0 vulnerabilities"#;
|
||||
|
||||
let text_content = TextContent {
|
||||
text: npm_output.to_string(),
|
||||
raw: RawTextContent {
|
||||
text: npm_output.to_string(),
|
||||
},
|
||||
annotations: None,
|
||||
};
|
||||
let tool_response = ToolResponse {
|
||||
id: "npm-install".to_string(),
|
||||
tool_result: Ok(vec![McpContent::Text(text_content)]),
|
||||
tool_result: Ok(vec![Content::text(text_content.raw.text)]),
|
||||
};
|
||||
|
||||
let request_result = tool_request_to_markdown(&tool_request, true);
|
||||
|
||||
@@ -35,9 +35,9 @@ use goose::providers::pricing::initialize_pricing_cache;
|
||||
use goose::session;
|
||||
use input::InputResult;
|
||||
use mcp_core::handler::ToolError;
|
||||
use mcp_core::prompt::PromptMessage;
|
||||
use mcp_core::protocol::JsonRpcMessage;
|
||||
use mcp_core::protocol::JsonRpcNotification;
|
||||
use rmcp::model::PromptMessage;
|
||||
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use rustyline::EditMode;
|
||||
@@ -359,7 +359,33 @@ impl Session {
|
||||
|
||||
pub async fn get_prompt(&mut self, name: &str, arguments: Value) -> Result<Vec<PromptMessage>> {
|
||||
let result = self.agent.get_prompt(name, arguments).await?;
|
||||
Ok(result.messages)
|
||||
// Convert mcp_core::prompt::PromptMessage to rmcp::model::PromptMessage
|
||||
let converted_messages = result
|
||||
.messages
|
||||
.into_iter()
|
||||
.map(|msg| rmcp::model::PromptMessage {
|
||||
role: match msg.role {
|
||||
mcp_core::prompt::PromptMessageRole::User => {
|
||||
rmcp::model::PromptMessageRole::User
|
||||
}
|
||||
mcp_core::prompt::PromptMessageRole::Assistant => {
|
||||
rmcp::model::PromptMessageRole::Assistant
|
||||
}
|
||||
},
|
||||
content: match msg.content {
|
||||
mcp_core::prompt::PromptMessageContent::Text { text } => {
|
||||
rmcp::model::PromptMessageContent::Text { text }
|
||||
}
|
||||
mcp_core::prompt::PromptMessageContent::Image { image } => {
|
||||
rmcp::model::PromptMessageContent::Image { image }
|
||||
}
|
||||
mcp_core::prompt::PromptMessageContent::Resource { resource } => {
|
||||
rmcp::model::PromptMessageContent::Resource { resource }
|
||||
}
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
Ok(converted_messages)
|
||||
}
|
||||
|
||||
/// Process a single message and get the response
|
||||
|
||||
@@ -252,7 +252,7 @@ fn render_tool_response(resp: &ToolResponse, theme: Theme, debug: bool) {
|
||||
|
||||
if debug {
|
||||
println!("{:#?}", content);
|
||||
} else if let mcp_core::content::Content::Text(text) = content {
|
||||
} else if let Some(text) = content.as_text() {
|
||||
print_markdown(&text.text, theme);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user