alexhancock/mcp-crate-cleanup (#4885)
This commit is contained in:
@@ -554,6 +554,8 @@ mod final_output_tool_tests {
|
||||
use goose::conversation::Conversation;
|
||||
use goose::providers::base::MessageStream;
|
||||
use goose::recipe::Response;
|
||||
use rmcp::model::CallToolRequestParam;
|
||||
use rmcp::object;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_final_output_assistant_message_in_reply() -> Result<()> {
|
||||
@@ -620,12 +622,13 @@ mod final_output_tool_tests {
|
||||
agent.add_final_output_tool(response).await;
|
||||
|
||||
// Simulate a final output tool call occurring.
|
||||
let tool_call = mcp_core::tool::ToolCall::new(
|
||||
FINAL_OUTPUT_TOOL_NAME,
|
||||
serde_json::json!({
|
||||
let tool_call = CallToolRequestParam {
|
||||
name: FINAL_OUTPUT_TOOL_NAME.into(),
|
||||
arguments: Some(object!({
|
||||
"result": "Test output"
|
||||
}),
|
||||
);
|
||||
})),
|
||||
};
|
||||
|
||||
let (_, result) = agent
|
||||
.dispatch_tool_call(tool_call, "request_id".to_string(), None, &None)
|
||||
.await;
|
||||
@@ -1039,8 +1042,8 @@ mod max_turns_tests {
|
||||
use goose::model::ModelConfig;
|
||||
use goose::providers::base::{Provider, ProviderMetadata, ProviderUsage, Usage};
|
||||
use goose::providers::errors::ProviderError;
|
||||
use mcp_core::tool::ToolCall;
|
||||
use rmcp::model::Tool;
|
||||
use rmcp::model::{CallToolRequestParam, Tool};
|
||||
use rmcp::object;
|
||||
|
||||
struct MockToolProvider {}
|
||||
|
||||
@@ -1058,7 +1061,10 @@ mod max_turns_tests {
|
||||
_messages: &[Message],
|
||||
_tools: &[Tool],
|
||||
) -> Result<(Message, ProviderUsage), ProviderError> {
|
||||
let tool_call = ToolCall::new("test_tool", serde_json::json!({"param": "value"}));
|
||||
let tool_call = CallToolRequestParam {
|
||||
name: "test_tool".into(),
|
||||
arguments: Some(object!({"param": "value"})),
|
||||
};
|
||||
let message = Message::assistant().with_tool_request("call_123", Ok(tool_call));
|
||||
|
||||
let usage = ProviderUsage::new(
|
||||
|
||||
@@ -3,13 +3,12 @@ use std::fs::File;
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
|
||||
use rmcp::model::Content;
|
||||
use serde_json::json;
|
||||
use rmcp::model::{CallToolRequestParam, Content};
|
||||
use rmcp::object;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use goose::agents::extension::{Envs, ExtensionConfig};
|
||||
use goose::agents::extension_manager::ExtensionManager;
|
||||
use mcp_core::ToolCall;
|
||||
|
||||
use test_case::test_case;
|
||||
|
||||
@@ -21,66 +20,66 @@ enum TestMode {
|
||||
#[test_case(
|
||||
vec!["npx", "-y", "@modelcontextprotocol/server-everything"],
|
||||
vec![
|
||||
ToolCall::new("echo", json!({"message": "Hello, world!"})),
|
||||
ToolCall::new("add", json!({"a": 1, "b": 2})),
|
||||
ToolCall::new("longRunningOperation", json!({"duration": 1, "steps": 5})),
|
||||
ToolCall::new("structuredContent", json!({"location": "11238"})),
|
||||
CallToolRequestParam { name: "echo".into(), arguments: Some(object!({"message": "Hello, world!" })) },
|
||||
CallToolRequestParam { name: "add".into(), arguments: Some(object!({"a": 1, "b": 2 })) },
|
||||
CallToolRequestParam { name: "longRunningOperation".into(), arguments: Some(object!({"duration": 1, "steps": 5 })) },
|
||||
CallToolRequestParam { name: "structuredContent".into(), arguments: Some(object!({"location": "11238"})) },
|
||||
],
|
||||
vec![]
|
||||
)]
|
||||
#[test_case(
|
||||
vec!["github-mcp-server", "stdio"],
|
||||
vec![
|
||||
ToolCall::new("get_file_contents", json!({
|
||||
CallToolRequestParam { name: "get_file_contents".into(), arguments: Some(object!({
|
||||
"owner": "block",
|
||||
"repo": "goose",
|
||||
"path": "README.md",
|
||||
"sha": "ab62b863c1666232a67048b6c4e10007a2a5b83c"
|
||||
})),
|
||||
}))},
|
||||
],
|
||||
vec!["GITHUB_PERSONAL_ACCESS_TOKEN"]
|
||||
)]
|
||||
#[test_case(
|
||||
vec!["uvx", "mcp-server-fetch"],
|
||||
vec![
|
||||
ToolCall::new("fetch", json!({
|
||||
CallToolRequestParam { name: "fetch".into(), arguments: Some(object!({
|
||||
"url": "https://example.com",
|
||||
})),
|
||||
})) }
|
||||
],
|
||||
vec![]
|
||||
)]
|
||||
#[test_case(
|
||||
vec!["cargo", "run", "--quiet", "-p", "goose-server", "--bin", "goosed", "--", "mcp", "developer"],
|
||||
vec![
|
||||
ToolCall::new("text_editor", json!({
|
||||
CallToolRequestParam { name: "text_editor".into(), arguments: Some(object!({
|
||||
"command": "view",
|
||||
"path": "~/goose/crates/goose/tests/tmp/goose.txt"
|
||||
})),
|
||||
ToolCall::new("text_editor", json!({
|
||||
}))},
|
||||
CallToolRequestParam { name: "text_editor".into(), arguments: Some(object!({
|
||||
"command": "str_replace",
|
||||
"path": "~/goose/crates/goose/tests/tmp/goose.txt",
|
||||
"old_str": "# goose",
|
||||
"new_str": "# goose (modified by test)"
|
||||
})),
|
||||
}))},
|
||||
// Test shell command to verify file was modified
|
||||
ToolCall::new("shell", json!({
|
||||
CallToolRequestParam { name: "shell".into(), arguments: Some(object!({
|
||||
"command": "cat ~/goose/crates/goose/tests/tmp/goose.txt"
|
||||
})),
|
||||
})) },
|
||||
// Test text_editor tool to restore original content
|
||||
ToolCall::new("text_editor", json!({
|
||||
CallToolRequestParam { name: "text_editor".into(), arguments: Some(object!({
|
||||
"command": "str_replace",
|
||||
"path": "~/goose/crates/goose/tests/tmp/goose.txt",
|
||||
"old_str": "# goose (modified by test)",
|
||||
"new_str": "# goose"
|
||||
})),
|
||||
ToolCall::new("list_windows", json!({})),
|
||||
}))},
|
||||
CallToolRequestParam { name: "list_windows".into(), arguments: Some(object!({})) },
|
||||
],
|
||||
vec![]
|
||||
)]
|
||||
#[tokio::test]
|
||||
async fn test_replayed_session(
|
||||
command: Vec<&str>,
|
||||
tool_calls: Vec<ToolCall>,
|
||||
tool_calls: Vec<CallToolRequestParam>,
|
||||
required_envs: Vec<&str>,
|
||||
) {
|
||||
let replay_file_name = command
|
||||
@@ -159,10 +158,12 @@ async fn test_replayed_session(
|
||||
#[allow(clippy::redundant_closure_call)]
|
||||
let result = (async || -> Result<(), Box<dyn std::error::Error>> {
|
||||
extension_manager.add_extension(extension_config).await?;
|
||||
|
||||
let mut results = Vec::new();
|
||||
for tool_call in tool_calls {
|
||||
let tool_call = ToolCall::new(format!("test__{}", tool_call.name), tool_call.arguments);
|
||||
let tool_call = CallToolRequestParam {
|
||||
name: format!("test__{}", tool_call.name).into(),
|
||||
arguments: tool_call.arguments,
|
||||
};
|
||||
let result = extension_manager
|
||||
.dispatch_tool_call(tool_call, CancellationToken::default())
|
||||
.await;
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"0.1.0"}}}
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"1.9.0"}}}
|
||||
STDERR: [2m2025-09-27T04:13:30.409389Z[0m [32m INFO[0m [1;32mgoose_mcp::mcp_server_runner[0m[32m: [32mStarting MCP server[0m
|
||||
STDERR: [2;3mat[0m crates/goose-mcp/src/mcp_server_runner.rs:18
|
||||
STDERR:
|
||||
@@ -11,7 +11,7 @@ STDERR: [2m2025-09-27T04:13:30.418172Z[0m [32m INFO[0m [1;32mrmcp::handle
|
||||
STDERR: [2;3mat[0m /Users/angiej/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.6.2/src/handler/server.rs:218
|
||||
STDERR:
|
||||
STDIN: {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"_meta":{"progressToken":0},"name":"text_editor","arguments":{"command":"view","path":"~/goose/crates/goose/tests/tmp/goose.txt"}}}
|
||||
STDERR: [2m2025-09-27T04:13:30.418412Z[0m [32m INFO[0m [1;32mrmcp::service[0m[32m: [32mService initialized as server, [1;32mpeer_info[0m[32m: Some(InitializeRequestParam { protocol_version: ProtocolVersion("2025-03-26"), capabilities: ClientCapabilities { experimental: None, roots: None, sampling: None, elicitation: None }, client_info: Implementation { name: "goose", version: "0.1.0" } })[0m
|
||||
STDERR: [2m2025-09-27T04:13:30.418412Z[0m [32m INFO[0m [1;32mrmcp::service[0m[32m: [32mService initialized as server, [1;32mpeer_info[0m[32m: Some(InitializeRequestParam { protocol_version: ProtocolVersion("2025-03-26"), capabilities: ClientCapabilities { experimental: None, roots: None, sampling: None, elicitation: None }, client_info: Implementation { name: "goose", version: "1.9.0" } })[0m
|
||||
STDERR: [2;3mat[0m /Users/angiej/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.6.2/src/service.rs:561
|
||||
STDERR: [2;3min[0m rmcp::service::[1mserve_inner[0m
|
||||
STDERR:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"0.1.0"}}}
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"1.9.0"}}}
|
||||
STDERR: GitHub MCP Server running on stdio
|
||||
STDOUT: {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2025-03-26","capabilities":{"logging":{},"prompts":{},"resources":{"subscribe":true,"listChanged":true},"tools":{"listChanged":true}},"serverInfo":{"name":"github-mcp-server","version":"version"}}}
|
||||
STDIN: {"jsonrpc":"2.0","method":"notifications/initialized"}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"0.1.0"}}}
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"1.9.0"}}}
|
||||
STDERR: 2025-09-26 23:13:04 - Starting npx setup script.
|
||||
STDERR: 2025-09-26 23:13:04 - Creating directory ~/.config/goose/mcp-hermit/bin if it does not exist.
|
||||
STDERR: 2025-09-26 23:13:04 - Changing to directory ~/.config/goose/mcp-hermit.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"0.1.0"}}}
|
||||
STDIN: {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"goose","version":"1.9.0"}}}
|
||||
STDERR: 2025-09-26 23:13:04 - Starting uvx setup script.
|
||||
STDERR: 2025-09-26 23:13:04 - Creating directory ~/.config/goose/mcp-hermit/bin if it does not exist.
|
||||
STDERR: 2025-09-26 23:13:04 - Changing to directory ~/.config/goose/mcp-hermit.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![cfg(test)]
|
||||
|
||||
use rmcp::model::ErrorCode;
|
||||
use rmcp::model::{CallToolRequestParam, ErrorCode};
|
||||
use rmcp::object;
|
||||
use serde_json::json;
|
||||
|
||||
use goose::agents::platform_tools::PLATFORM_MANAGE_SCHEDULE_TOOL_NAME;
|
||||
@@ -808,11 +809,11 @@ async fn test_schedule_tool_dispatch() {
|
||||
.await;
|
||||
|
||||
// Test that the tool is properly dispatched through dispatch_tool_call
|
||||
let tool_call = mcp_core::tool::ToolCall {
|
||||
name: PLATFORM_MANAGE_SCHEDULE_TOOL_NAME.to_string(),
|
||||
arguments: json!({
|
||||
let tool_call = CallToolRequestParam {
|
||||
name: PLATFORM_MANAGE_SCHEDULE_TOOL_NAME.into(),
|
||||
arguments: Some(object!({
|
||||
"action": "list"
|
||||
}),
|
||||
})),
|
||||
};
|
||||
|
||||
let (request_id, result) = agent
|
||||
|
||||
@@ -7,8 +7,8 @@ use goose::providers::{
|
||||
anthropic, azure, bedrock, databricks, google, groq, litellm, ollama, openai, openrouter,
|
||||
snowflake, xai,
|
||||
};
|
||||
use rmcp::model::Tool;
|
||||
use rmcp::model::{AnnotateAble, Content, RawImageContent};
|
||||
use rmcp::model::{CallToolRequestParam, Tool};
|
||||
use rmcp::object;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -320,10 +320,10 @@ impl ProviderTester {
|
||||
let user_message = Message::user().with_text("Take a screenshot please");
|
||||
let tool_request = Message::assistant().with_tool_request(
|
||||
"test_id",
|
||||
Ok(mcp_core::tool::ToolCall::new(
|
||||
"get_screenshot",
|
||||
serde_json::json!({}),
|
||||
)),
|
||||
Ok(CallToolRequestParam {
|
||||
name: "get_screenshot".into(),
|
||||
arguments: Some(object!({})),
|
||||
}),
|
||||
);
|
||||
let tool_response = Message::user().with_tool_response(
|
||||
"test_id",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use goose::tool_monitor::{RepetitionInspector, ToolCall};
|
||||
use serde_json::json;
|
||||
use goose::tool_monitor::RepetitionInspector;
|
||||
use rmcp::model::CallToolRequestParam;
|
||||
use rmcp::object;
|
||||
|
||||
// This test targets RepetitionInspector::check_tool_call
|
||||
// It verifies that:
|
||||
@@ -12,7 +13,10 @@ fn test_repetition_inspector_denies_after_exceeding_and_resets_on_param_change()
|
||||
let mut inspector = RepetitionInspector::new(Some(2));
|
||||
|
||||
// First identical call → allowed
|
||||
let call_v1 = ToolCall::new("fetch_user".to_string(), json!({"id": 123}));
|
||||
let call_v1 = CallToolRequestParam {
|
||||
name: "fetch_user".into(),
|
||||
arguments: Some(object!({"id": 123})),
|
||||
};
|
||||
assert!(inspector.check_tool_call(call_v1.clone()));
|
||||
|
||||
// Second identical call → still allowed (at limit)
|
||||
@@ -22,7 +26,11 @@ fn test_repetition_inspector_denies_after_exceeding_and_resets_on_param_change()
|
||||
assert!(!inspector.check_tool_call(call_v1.clone()));
|
||||
|
||||
// Change parameters; this should reset the consecutive counter
|
||||
let call_v2 = ToolCall::new("fetch_user".to_string(), json!({"id": 456}));
|
||||
let call_v2 = CallToolRequestParam {
|
||||
name: "fetch_user".into(),
|
||||
arguments: Some(object!({"id": 456})),
|
||||
};
|
||||
|
||||
assert!(inspector.check_tool_call(call_v2.clone()));
|
||||
|
||||
// Another identical call with new params → allowed (second in a row for this variant)
|
||||
|
||||
Reference in New Issue
Block a user