Revert "Internal MCP Crate Cleanup (#4800)" (#4883)

This commit is contained in:
Alex Hancock
2025-09-29 14:21:30 -04:00
committed by GitHub
parent 2cfef016e2
commit b9ba8dca29
78 changed files with 1090 additions and 844 deletions
+22 -31
View File
@@ -1,11 +1,11 @@
use crate::mcp_utils::ToolResult;
use chrono::Utc;
use mcp_core::{ToolCall, ToolResult};
use rmcp::model::{
AnnotateAble, CallToolRequestParam, Content, ImageContent, JsonObject, PromptMessage,
PromptMessageContent, PromptMessageRole, RawContent, RawImageContent, RawTextContent,
ResourceContents, Role, TextContent,
AnnotateAble, Content, ImageContent, PromptMessage, PromptMessageContent, PromptMessageRole,
RawContent, RawImageContent, RawTextContent, ResourceContents, Role, TextContent,
};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::collections::HashSet;
use std::fmt;
use utoipa::ToSchema;
@@ -46,7 +46,7 @@ pub struct ToolRequest {
pub id: String,
#[serde(with = "tool_result_serde")]
#[schema(value_type = Object)]
pub tool_call: ToolResult<CallToolRequestParam>,
pub tool_call: ToolResult<ToolCall>,
}
impl ToolRequest {
@@ -81,7 +81,7 @@ pub struct ToolResponse {
pub struct ToolConfirmationRequest {
pub id: String,
pub tool_name: String,
pub arguments: JsonObject,
pub arguments: Value,
pub prompt: Option<String>,
}
@@ -102,7 +102,7 @@ pub struct FrontendToolRequest {
pub id: String,
#[serde(with = "tool_result_serde")]
#[schema(value_type = Object)]
pub tool_call: ToolResult<CallToolRequestParam>,
pub tool_call: ToolResult<ToolCall>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)]
@@ -188,10 +188,7 @@ impl MessageContent {
)
}
pub fn tool_request<S: Into<String>>(
id: S,
tool_call: ToolResult<CallToolRequestParam>,
) -> Self {
pub fn tool_request<S: Into<String>>(id: S, tool_call: ToolResult<ToolCall>) -> Self {
MessageContent::ToolRequest(ToolRequest {
id: id.into(),
tool_call,
@@ -208,7 +205,7 @@ impl MessageContent {
pub fn tool_confirmation_request<S: Into<String>>(
id: S,
tool_name: String,
arguments: JsonObject,
arguments: Value,
prompt: Option<String>,
) -> Self {
MessageContent::ToolConfirmationRequest(ToolConfirmationRequest {
@@ -230,10 +227,7 @@ impl MessageContent {
MessageContent::RedactedThinking(RedactedThinkingContent { data: data.into() })
}
pub fn frontend_tool_request<S: Into<String>>(
id: S,
tool_call: ToolResult<CallToolRequestParam>,
) -> Self {
pub fn frontend_tool_request<S: Into<String>>(id: S, tool_call: ToolResult<ToolCall>) -> Self {
MessageContent::FrontendToolRequest(FrontendToolRequest {
id: id.into(),
tool_call,
@@ -563,7 +557,7 @@ impl Message {
pub fn with_tool_request<S: Into<String>>(
self,
id: S,
tool_call: ToolResult<CallToolRequestParam>,
tool_call: ToolResult<ToolCall>,
) -> Self {
self.with_content(MessageContent::tool_request(id, tool_call))
}
@@ -582,7 +576,7 @@ impl Message {
self,
id: S,
tool_name: String,
arguments: JsonObject,
arguments: Value,
prompt: Option<String>,
) -> Self {
self.with_content(MessageContent::tool_confirmation_request(
@@ -593,7 +587,7 @@ impl Message {
pub fn with_frontend_tool_request<S: Into<String>>(
self,
id: S,
tool_call: ToolResult<CallToolRequestParam>,
tool_call: ToolResult<ToolCall>,
) -> Self {
self.with_content(MessageContent::frontend_tool_request(id, tool_call))
}
@@ -734,13 +728,13 @@ impl Message {
mod tests {
use crate::conversation::message::{Message, MessageContent, MessageMetadata};
use crate::conversation::*;
use mcp_core::ToolCall;
use rmcp::model::{
AnnotateAble, CallToolRequestParam, PromptMessage, PromptMessageContent, PromptMessageRole,
RawEmbeddedResource, RawImageContent, ResourceContents,
AnnotateAble, PromptMessage, PromptMessageContent, PromptMessageRole, RawEmbeddedResource,
RawImageContent, ResourceContents,
};
use rmcp::model::{ErrorCode, ErrorData};
use rmcp::object;
use serde_json::Value;
use serde_json::{json, Value};
#[test]
fn test_sanitize_with_text() {
@@ -762,10 +756,7 @@ mod tests {
.with_text("Hello, I'll help you with that.")
.with_tool_request(
"tool123",
Ok(CallToolRequestParam {
name: "test_tool".into(),
arguments: Some(object!({"param": "value"})),
}),
Ok(ToolCall::new("test_tool", json!({"param": "value"}))),
);
let json_str = serde_json::to_string_pretty(&message).unwrap();
@@ -865,7 +856,7 @@ mod tests {
assert_eq!(req.id, "tool123");
if let Ok(tool_call) = &req.tool_call {
assert_eq!(tool_call.name, "test_tool");
assert_eq!(tool_call.arguments, Some(object!({"param": "value"})))
assert_eq!(tool_call.arguments, json!({"param": "value"}));
} else {
panic!("Expected successful tool call");
}
@@ -1019,9 +1010,9 @@ mod tests {
#[test]
fn test_message_with_tool_request() {
let tool_call = Ok(CallToolRequestParam {
name: "test_tool".into(),
arguments: Some(object!({})),
let tool_call = Ok(ToolCall {
name: "test_tool".to_string(),
arguments: serde_json::json!({}),
});
let message = Message::assistant().with_tool_request("req1", tool_call);
+14 -40
View File
@@ -380,8 +380,9 @@ pub fn debug_conversation_fix(
mod tests {
use crate::conversation::message::Message;
use crate::conversation::{debug_conversation_fix, fix_conversation, Conversation};
use rmcp::model::{CallToolRequestParam, Role};
use rmcp::object;
use mcp_core::tool::ToolCall;
use rmcp::model::Role;
use serde_json::json;
fn run_verify(messages: Vec<Message>) -> (Vec<Message>, Vec<String>) {
let (fixed, issues) = fix_conversation(Conversation::new_unvalidated(messages.clone()));
@@ -409,10 +410,10 @@ mod tests {
.with_text("I'll help you search.")
.with_tool_request(
"search_1",
Ok(CallToolRequestParam {
name: "web_search".into(),
arguments: Some(object!({"query": "rust programming"})),
}),
Ok(ToolCall::new(
"web_search",
json!({"query": "rust programming"}),
)),
),
Message::user().with_tool_response("search_1", Ok(vec![])),
Message::assistant().with_text("Based on the search results, here's what I found..."),
@@ -454,13 +455,7 @@ mod tests {
.with_tool_response("orphan_1", Ok(vec![])), // Wrong role
Message::assistant().with_thinking("Let me think", "sig"),
Message::user()
.with_tool_request(
"bad_req",
Ok(CallToolRequestParam {
name: "search".into(),
arguments: Some(object!({})),
}),
)
.with_tool_request("bad_req", Ok(ToolCall::new("search", json!({}))))
.with_text("User with bad tool request"),
];
@@ -495,22 +490,11 @@ mod tests {
let messages = vec![
Message::assistant()
.with_text("I'll search for you")
.with_tool_request(
"search_1",
Ok(CallToolRequestParam {
name: "search".into(),
arguments: Some(object!({})),
}),
),
.with_tool_request("search_1", Ok(ToolCall::new("search", json!({})))),
Message::user(),
Message::user().with_tool_response("wrong_id", Ok(vec![])),
Message::assistant().with_tool_request(
"search_2",
Ok(CallToolRequestParam {
name: "search".into(),
arguments: Some(object!({})),
}),
),
Message::assistant()
.with_tool_request("search_2", Ok(ToolCall::new("search", json!({})))),
];
let (fixed, issues) = run_verify(messages);
@@ -530,18 +514,14 @@ mod tests {
fn test_real_world_consecutive_assistant_messages() {
let conversation = Conversation::new_unvalidated(vec![
Message::user().with_text("run ls in the current directory and then run a word count on the smallest file"),
Message::assistant()
.with_text("I'll help you run `ls` in the current directory and then perform a word count on the smallest file. Let me start by listing the directory contents.")
.with_tool_request("toolu_bdrk_018adWbP4X26CfoJU5hkhu3i", Ok(CallToolRequestParam { name: "developer__shell".into(), arguments: Some(object!({"command": "ls -la"})) })),
.with_tool_request("toolu_bdrk_018adWbP4X26CfoJU5hkhu3i", Ok(ToolCall::new("developer__shell", json!({"command": "ls -la"})))),
Message::assistant()
.with_text("Now I'll identify the smallest file by size. Looking at the output, I can see that both `slack.yaml` and `subrecipes.yaml` have a size of 0 bytes, making them the smallest files. I'll run a word count on one of them:")
.with_tool_request("toolu_bdrk_01KgDYHs4fAodi22NqxRzmwx", Ok(CallToolRequestParam { name: "developer__shell".into(), arguments: Some(object!({"command": "wc slack.yaml"})) })),
.with_tool_request("toolu_bdrk_01KgDYHs4fAodi22NqxRzmwx", Ok(ToolCall::new("developer__shell", json!({"command": "wc slack.yaml"})))),
Message::user()
.with_tool_response("toolu_bdrk_01KgDYHs4fAodi22NqxRzmwx", Ok(vec![])),
Message::assistant()
.with_text("I ran `ls -la` in the current directory and found several files. Looking at the file sizes, I can see that both `slack.yaml` and `subrecipes.yaml` are 0 bytes (the smallest files). I ran a word count on `slack.yaml` which shows: **0 lines**, **0 words**, **0 characters**"),
Message::user().with_text("thanks!"),
@@ -561,13 +541,7 @@ mod tests {
Message::user().with_text("Search for something"),
Message::assistant()
.with_text("I'll search for you")
.with_tool_request(
"search_1",
Ok(CallToolRequestParam {
name: "search".into(),
arguments: Some(object!({})),
}),
),
.with_tool_request("search_1", Ok(ToolCall::new("search", json!({})))),
Message::user().with_tool_response("search_1", Ok(vec![])),
Message::user().with_text("Thanks!"),
];
@@ -1,4 +1,4 @@
use crate::mcp_utils::ToolResult;
use mcp_core::ToolResult;
use rmcp::model::{ErrorCode, ErrorData};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};