pub mod bash; pub mod calculator; pub mod file_edit; pub mod file_read; pub mod file_write; pub mod http_request; pub mod memory_manage; pub mod memory_search; pub mod registry; pub mod scheduler_manage; pub mod session_send; pub mod schema; pub mod skill_activate; pub mod skill_manage; pub mod task; pub mod time; pub mod traits; pub mod web_fetch; pub use bash::BashTool; pub use calculator::CalculatorTool; pub use file_edit::FileEditTool; pub use file_read::FileReadTool; pub use file_write::FileWriteTool; pub use http_request::HttpRequestTool; pub use memory_manage::MemoryManageTool; pub use memory_search::MemorySearchTool; pub use registry::ToolRegistry; pub use scheduler_manage::SchedulerManageTool; pub use session_send::{ NoopSessionMessageSender, SessionMessageSender, SessionSendOutcome, SessionSendRequest, SessionSendTool, }; pub use schema::{CleaningStrategy, SchemaCleanr}; pub use skill_activate::SkillActivateTool; pub use skill_manage::{SkillListTool, SkillManageTool}; pub use task::{ DefaultSubAgentRuntime, InMemoryTaskRepository, SubAgentRuntime, SubAgentRuntimeConfig, TaskError, TaskRepository, TaskTool, }; pub use time::TimeTool; pub use traits::{Tool, ToolContext, ToolResult}; pub use web_fetch::WebFetchTool; /// Extract a string parameter from JSON args. pub fn extract_string(args: &serde_json::Value, key: &str) -> Option { args.get(key).and_then(|v| { if let Some(s) = v.as_str() { Some(s.to_string()) } else if let Some(n) = v.as_number() { // Handle case where LLM sends a number but we need a string Some(n.to_string()) } else { None } }) } /// Extract an f64 parameter from JSON args, handling both numbers and strings. pub fn extract_f64(args: &serde_json::Value, key: &str) -> Option { args.get(key).and_then(|v| { if let Some(n) = v.as_f64() { Some(n) } else if let Some(s) = v.as_str() { s.parse::().ok() } else { None } }) } /// Extract an i64 parameter from JSON args, handling both numbers and strings. pub fn extract_i64(args: &serde_json::Value, key: &str) -> Option { args.get(key).and_then(|v| { if let Some(n) = v.as_i64() { Some(n) } else if let Some(s) = v.as_str() { s.parse::().ok() } else { None } }) } /// Extract a u64 parameter from JSON args, handling both numbers and strings. pub fn extract_u64(args: &serde_json::Value, key: &str) -> Option { args.get(key).and_then(|v| { if let Some(n) = v.as_u64() { Some(n) } else if let Some(s) = v.as_str() { s.parse::().ok() } else { None } }) } /// Extract a bool parameter from JSON args, handling both booleans and strings. pub fn extract_bool(args: &serde_json::Value, key: &str) -> Option { args.get(key).and_then(|v| { if let Some(b) = v.as_bool() { Some(b) } else if let Some(s) = v.as_str() { match s.to_lowercase().as_str() { "true" | "1" | "yes" | "on" => Some(true), "false" | "0" | "no" | "off" => Some(false), _ => None, } } else { None } }) } /// Extract a required string parameter, returning an error message if missing. pub fn require_string(args: &serde_json::Value, key: &str) -> Result { extract_string(args, key) .filter(|s| !s.trim().is_empty()) .ok_or_else(|| format!("Missing required parameter: {}", key)) } /// Extract a required f64 parameter, returning an error message if missing. pub fn require_f64(args: &serde_json::Value, key: &str) -> Result { extract_f64(args, key) .ok_or_else(|| format!("Missing required parameter: {}", key)) } /// Extract a required i64 parameter, returning an error message if missing. pub fn require_i64(args: &serde_json::Value, key: &str) -> Result { extract_i64(args, key) .ok_or_else(|| format!("Missing required parameter: {}", key)) } /// Extract a required u64 parameter, returning an error message if missing. pub fn require_u64(args: &serde_json::Value, key: &str) -> Result { extract_u64(args, key) .ok_or_else(|| format!("Missing required parameter: {}", key)) } /// Extract a required bool parameter, returning an error message if missing. pub fn require_bool(args: &serde_json::Value, key: &str) -> Result { extract_bool(args, key) .ok_or_else(|| format!("Missing required parameter: {}", key)) } /// Check if args is null and return an error result if so. /// Returns the provided error message if args is null. pub fn check_null_args(args: &serde_json::Value, tool_name: &str) -> Option { if args.is_null() { return Some(ToolResult { success: false, output: String::new(), error: Some(format!( "Missing required parameters: {} expects a JSON object with required fields. Check the tool schema and provide the necessary arguments.", tool_name )), }); } if !args.is_object() { return Some(ToolResult { success: false, output: String::new(), error: Some(format!( "Invalid parameters: {} expects a JSON object, got {}", tool_name, if args.is_array() { "an array" } else if args.is_string() { "a string" } else { "an unexpected type" } )), }); } None }