fix: resolve all compilation errors and clippy warnings
This commit fixes 12 categories of errors across the codebase: - Fix owlen-mcp-llm-server build target conflict by renaming lib.rs to main.rs - Resolve ambiguous glob re-exports in owlen-core by using explicit exports - Add Default derive to MockMcpClient and MockProvider test utilities - Remove unused imports from owlen-core test files - Fix needless borrows in test file arguments - Improve Config initialization style in mode_tool_filter tests - Make AgentExecutor::parse_response public for testing - Remove non-existent max_tool_calls field from AgentConfig usage - Fix AgentExecutor::new calls to use correct 3-argument signature - Fix AgentResult field access in agent tests - Use Debug formatting instead of Display for AgentResult - Remove unnecessary default() calls on unit structs All changes ensure the project compiles cleanly with: - cargo check --all-targets ✓ - cargo clippy --all-targets -- -D warnings ✓ - cargo test --no-run ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -82,10 +82,9 @@ async fn test_agent_single_tool_scenario() {
|
||||
model: "llama3.2".to_string(),
|
||||
temperature: Some(0.7),
|
||||
max_tokens: None,
|
||||
max_tool_calls: 10,
|
||||
};
|
||||
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config, None);
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config);
|
||||
|
||||
// Simple query that should complete in one tool call
|
||||
let result = executor
|
||||
@@ -93,9 +92,12 @@ async fn test_agent_single_tool_scenario() {
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(answer) => {
|
||||
assert!(!answer.is_empty(), "Answer should not be empty");
|
||||
println!("Agent answer: {}", answer);
|
||||
Ok(agent_result) => {
|
||||
assert!(
|
||||
!agent_result.answer.is_empty(),
|
||||
"Answer should not be empty"
|
||||
);
|
||||
println!("Agent answer: {}", agent_result.answer);
|
||||
}
|
||||
Err(e) => {
|
||||
// It's okay if this fails due to LLM not following format
|
||||
@@ -116,10 +118,9 @@ async fn test_agent_multi_step_workflow() {
|
||||
model: "llama3.2".to_string(),
|
||||
temperature: Some(0.5), // Lower temperature for more consistent behavior
|
||||
max_tokens: None,
|
||||
max_tool_calls: 20,
|
||||
};
|
||||
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config, None);
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config);
|
||||
|
||||
// Query requiring multiple steps: list -> read -> analyze
|
||||
let result = executor
|
||||
@@ -127,9 +128,9 @@ async fn test_agent_multi_step_workflow() {
|
||||
.await;
|
||||
|
||||
match result {
|
||||
Ok(answer) => {
|
||||
assert!(!answer.is_empty());
|
||||
println!("Multi-step answer: {}", answer);
|
||||
Ok(agent_result) => {
|
||||
assert!(!agent_result.answer.is_empty());
|
||||
println!("Multi-step answer: {:?}", agent_result);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Multi-step test skipped: {}", e);
|
||||
@@ -148,10 +149,9 @@ async fn test_agent_iteration_limit() {
|
||||
model: "llama3.2".to_string(),
|
||||
temperature: Some(0.7),
|
||||
max_tokens: None,
|
||||
max_tool_calls: 5,
|
||||
};
|
||||
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config, None);
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config);
|
||||
|
||||
// Complex query that would require many iterations
|
||||
let result = executor
|
||||
@@ -186,14 +186,13 @@ async fn test_agent_tool_budget_enforcement() {
|
||||
let mcp_client = Arc::clone(&provider) as Arc<RemoteMcpClient>;
|
||||
|
||||
let config = AgentConfig {
|
||||
max_iterations: 20,
|
||||
max_iterations: 3, // Very low iteration limit to enforce budget
|
||||
model: "llama3.2".to_string(),
|
||||
temperature: Some(0.7),
|
||||
max_tokens: None,
|
||||
max_tool_calls: 3, // Very low tool call budget
|
||||
};
|
||||
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config, None);
|
||||
let executor = AgentExecutor::new(provider, mcp_client, config);
|
||||
|
||||
// Query that would require many tool calls
|
||||
let result = executor
|
||||
@@ -238,7 +237,7 @@ fn create_test_executor() -> AgentExecutor {
|
||||
let mcp_client = Arc::clone(&provider) as Arc<RemoteMcpClient>;
|
||||
|
||||
let config = AgentConfig::default();
|
||||
AgentExecutor::new(provider, mcp_client, config, None)
|
||||
AgentExecutor::new(provider, mcp_client, config)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -248,7 +247,7 @@ fn test_agent_config_defaults() {
|
||||
assert_eq!(config.max_iterations, 10);
|
||||
assert_eq!(config.model, "ollama");
|
||||
assert_eq!(config.temperature, Some(0.7));
|
||||
assert_eq!(config.max_tool_calls, 20);
|
||||
// max_tool_calls field removed - agent now tracks iterations instead
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -258,12 +257,10 @@ fn test_agent_config_custom() {
|
||||
model: "custom-model".to_string(),
|
||||
temperature: Some(0.5),
|
||||
max_tokens: Some(2000),
|
||||
max_tool_calls: 30,
|
||||
};
|
||||
|
||||
assert_eq!(config.max_iterations, 15);
|
||||
assert_eq!(config.model, "custom-model");
|
||||
assert_eq!(config.temperature, Some(0.5));
|
||||
assert_eq!(config.max_tokens, Some(2000));
|
||||
assert_eq!(config.max_tool_calls, 30);
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ impl AgentExecutor {
|
||||
}
|
||||
|
||||
/// Parse LLM response into structured format
|
||||
fn parse_response(&self, text: &str) -> Result<LlmResponse> {
|
||||
pub fn parse_response(&self, text: &str) -> Result<LlmResponse> {
|
||||
let lines: Vec<&str> = text.lines().collect();
|
||||
let mut thought = String::new();
|
||||
let mut action = String::new();
|
||||
@@ -370,8 +370,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_tool_call() {
|
||||
let executor = AgentExecutor {
|
||||
llm_client: Arc::new(MockProvider::new()),
|
||||
tool_client: Arc::new(MockMcpClient::new()),
|
||||
llm_client: Arc::new(MockProvider),
|
||||
tool_client: Arc::new(MockMcpClient),
|
||||
config: AgentConfig::default(),
|
||||
};
|
||||
|
||||
@@ -399,8 +399,8 @@ ACTION_INPUT: {"query": "Rust programming language"}
|
||||
#[test]
|
||||
fn test_parse_final_answer() {
|
||||
let executor = AgentExecutor {
|
||||
llm_client: Arc::new(MockProvider::new()),
|
||||
tool_client: Arc::new(MockMcpClient::new()),
|
||||
llm_client: Arc::new(MockProvider),
|
||||
tool_client: Arc::new(MockMcpClient),
|
||||
config: AgentConfig::default(),
|
||||
};
|
||||
|
||||
|
||||
@@ -34,10 +34,15 @@ pub use credentials::*;
|
||||
pub use encryption::*;
|
||||
pub use formatting::*;
|
||||
pub use input::*;
|
||||
pub use mcp::*;
|
||||
// Export MCP types but exclude test_utils to avoid ambiguity
|
||||
pub use mcp::{
|
||||
client, factory, failover, permission, protocol, remote_client, LocalMcpClient, McpServer,
|
||||
McpToolCall, McpToolDescriptor, McpToolResponse,
|
||||
};
|
||||
pub use mode::*;
|
||||
pub use model::*;
|
||||
pub use provider::*;
|
||||
// Export provider types but exclude test_utils to avoid ambiguity
|
||||
pub use provider::{ChatStream, Provider, ProviderConfig, ProviderRegistry};
|
||||
pub use router::*;
|
||||
pub use sandbox::*;
|
||||
pub use session::*;
|
||||
|
||||
@@ -149,14 +149,9 @@ pub mod test_utils {
|
||||
use super::*;
|
||||
|
||||
/// Mock MCP client for testing
|
||||
#[derive(Default)]
|
||||
pub struct MockMcpClient;
|
||||
|
||||
impl MockMcpClient {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl McpClient for MockMcpClient {
|
||||
async fn list_tools(&self) -> Result<Vec<McpToolDescriptor>> {
|
||||
|
||||
@@ -181,14 +181,9 @@ pub mod test_utils {
|
||||
use crate::types::{ChatRequest, ChatResponse, Message, ModelInfo, Role};
|
||||
|
||||
/// Mock provider for testing
|
||||
#[derive(Default)]
|
||||
pub struct MockProvider;
|
||||
|
||||
impl MockProvider {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Provider for MockProvider {
|
||||
fn name(&self) -> &str {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use owlen_core::mcp::client::McpClient;
|
||||
use owlen_core::mcp::remote_client::RemoteMcpClient;
|
||||
use owlen_core::mcp::McpToolCall;
|
||||
use owlen_core::McpToolCall;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use tempfile::tempdir;
|
||||
@@ -22,7 +21,7 @@ async fn remote_file_server_read_and_list() {
|
||||
.join("../..")
|
||||
.join("Cargo.toml");
|
||||
let build_status = std::process::Command::new("cargo")
|
||||
.args(&["build", "-p", "owlen-mcp-server", "--manifest-path"])
|
||||
.args(["build", "-p", "owlen-mcp-server", "--manifest-path"])
|
||||
.arg(manifest_path)
|
||||
.status()
|
||||
.expect("failed to run cargo build for MCP server");
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use owlen_core::mcp::client::McpClient;
|
||||
use owlen_core::mcp::remote_client::RemoteMcpClient;
|
||||
use owlen_core::mcp::McpToolCall;
|
||||
use owlen_core::McpToolCall;
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[tokio::test]
|
||||
async fn remote_write_and_delete() {
|
||||
// Build the server binary first
|
||||
let status = std::process::Command::new("cargo")
|
||||
.args(&["build", "-p", "owlen-mcp-server"])
|
||||
.args(["build", "-p", "owlen-mcp-server"])
|
||||
.status()
|
||||
.expect("failed to build MCP server");
|
||||
assert!(status.success());
|
||||
@@ -42,7 +41,7 @@ async fn remote_write_and_delete() {
|
||||
async fn write_outside_root_is_rejected() {
|
||||
// Build server (already built in previous test, but ensure it exists)
|
||||
let status = std::process::Command::new("cargo")
|
||||
.args(&["build", "-p", "owlen-mcp-server"])
|
||||
.args(["build", "-p", "owlen-mcp-server"])
|
||||
.status()
|
||||
.expect("failed to build MCP server");
|
||||
assert!(status.success());
|
||||
|
||||
@@ -42,14 +42,16 @@ impl Tool for EchoTool {
|
||||
#[tokio::test]
|
||||
async fn test_tool_allowed_in_chat_mode() {
|
||||
// Build a config where the `echo` tool is explicitly allowed in chat.
|
||||
let mut cfg = Config::default();
|
||||
cfg.modes = ModeConfig {
|
||||
let cfg = Config {
|
||||
modes: ModeConfig {
|
||||
chat: ModeToolConfig {
|
||||
allowed_tools: vec!["echo".to_string()],
|
||||
},
|
||||
code: ModeToolConfig {
|
||||
allowed_tools: vec!["*".to_string()],
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let cfg = Arc::new(Mutex::new(cfg));
|
||||
|
||||
@@ -70,17 +72,18 @@ async fn test_tool_allowed_in_chat_mode() {
|
||||
#[tokio::test]
|
||||
async fn test_tool_not_allowed_in_any_mode() {
|
||||
// Config that does NOT list `echo` in either mode.
|
||||
let mut cfg = Config::default();
|
||||
cfg.modes = ModeConfig {
|
||||
let cfg = Config {
|
||||
modes: ModeConfig {
|
||||
chat: ModeToolConfig {
|
||||
allowed_tools: vec!["web_search".to_string()],
|
||||
},
|
||||
code: ModeToolConfig {
|
||||
allowed_tools: vec!["*".to_string()], // allow all in code
|
||||
// Strict denial - only web_search allowed
|
||||
allowed_tools: vec!["web_search".to_string()],
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
// Remove the wildcard for code to simulate strict denial.
|
||||
cfg.modes.code.allowed_tools = vec!["web_search".to_string()];
|
||||
let cfg = Arc::new(Mutex::new(cfg));
|
||||
|
||||
let ui: Arc<dyn UiController> = Arc::new(NoOpUiController);
|
||||
|
||||
@@ -12,9 +12,6 @@ serde_json = "1.0"
|
||||
anyhow = "1.0"
|
||||
tokio-stream = "0.1"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "owlen-mcp-llm-server"
|
||||
path = "src/lib.rs"
|
||||
path = "src/main.rs"
|
||||
|
||||
Reference in New Issue
Block a user