PicoBot/src/tools/mod.rs

172 lines
5.6 KiB
Rust

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<String> {
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<f64> {
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::<f64>().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<i64> {
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::<i64>().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<u64> {
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::<u64>().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<bool> {
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<String, String> {
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<f64, String> {
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<i64, String> {
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<u64, String> {
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<bool, String> {
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<ToolResult> {
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
}