sh_layer3/builtin_tools/
mod.rs1pub mod adapter;
6pub mod code;
7pub mod data_processing;
8pub mod file_ops;
9pub mod git_tools;
10pub mod memory_tools;
11pub mod network;
12pub mod network_tools;
13pub mod search;
14pub mod shell;
15pub mod system_tools;
16pub mod text_tools;
17pub mod web_search;
18pub mod workflow_tools;
19
20pub use adapter::{register_builtin_tools, ToolAdapter};
22
23use crate::types::{Layer3Result, ToolCategory, ToolMeta};
24use async_trait::async_trait;
25use std::collections::HashMap;
26
27#[async_trait]
31pub trait BuiltinTool: Send + Sync {
32 fn name(&self) -> &str;
34
35 fn description(&self) -> &str;
37
38 fn parameters_schema(&self) -> serde_json::Value;
40
41 fn category(&self) -> ToolCategory;
43
44 fn requires_confirmation(&self) -> bool {
46 false
47 }
48
49 fn is_dangerous(&self) -> bool {
51 false
52 }
53
54 async fn execute(&self, args: serde_json::Value) -> Layer3Result<String>;
56
57 fn meta(&self) -> ToolMeta {
59 ToolMeta {
60 name: self.name().to_string(),
61 description: self.description().to_string(),
62 parameters: self.parameters_schema(),
63 requires_confirmation: self.requires_confirmation(),
64 is_dangerous: self.is_dangerous(),
65 category: self.category(),
66 }
67 }
68}
69
70pub struct BuiltinToolRegistry {
74 tools: HashMap<String, Box<dyn BuiltinTool>>,
75}
76
77impl BuiltinToolRegistry {
78 pub fn new() -> Self {
80 Self {
81 tools: HashMap::new(),
82 }
83 }
84
85 pub fn with_defaults() -> Self {
87 let mut registry = Self::new();
88
89 registry.register(Box::new(shell::BashTool));
91
92 registry.register(Box::new(search::GrepTool));
94 registry.register(Box::new(search::GlobTool));
95
96 registry.register(Box::new(web_search::WebSearchTool::new()));
98
99 registry.register(Box::new(file_ops::ReadFileTool));
101 registry.register(Box::new(file_ops::WriteFileTool));
102 registry.register(Box::new(file_ops::EditFileTool));
103 registry.register(Box::new(file_ops::ListDirectoryTool));
104 registry.register(Box::new(file_ops::CreateDirectoryTool));
105 registry.register(Box::new(file_ops::MoveFileTool));
106 registry.register(Box::new(file_ops::CopyFileTool));
107 registry.register(Box::new(file_ops::DeleteFileTool));
108
109 registry.register(Box::new(workflow_tools::CreateCheckpointTool::new()));
111 registry.register(Box::new(workflow_tools::RestoreCheckpointTool::new()));
112 registry.register(Box::new(workflow_tools::ListCheckpointsTool::new()));
113
114 registry.register(Box::new(code::GoToDefinitionTool));
116 registry.register(Box::new(code::FindReferencesTool));
117 registry.register(Box::new(code::GetHoverTool));
118 registry.register(Box::new(code::RenameSymbolTool));
119
120 registry.register(Box::new(network::HttpRequestTool));
122 registry.register(Box::new(network::WebFetchTool));
123
124 registry.register(Box::new(memory_tools::SaveMemoryTool::new()));
126 registry.register(Box::new(memory_tools::QueryMemoryTool::new()));
127 registry.register(Box::new(memory_tools::ClearMemoryTool::new()));
128
129 registry.register(Box::new(data_processing::JsonParseTool));
131 registry.register(Box::new(data_processing::JsonStringifyTool));
132 registry.register(Box::new(data_processing::YamlParseTool));
133 registry.register(Box::new(data_processing::YamlStringifyTool));
134 registry.register(Box::new(data_processing::TomlParseTool));
135 registry.register(Box::new(data_processing::CsvParseTool));
136 registry.register(Box::new(data_processing::Base64EncodeTool));
137 registry.register(Box::new(data_processing::Base64DecodeTool));
138 registry.register(Box::new(data_processing::UrlEncodeTool));
139 registry.register(Box::new(data_processing::UrlDecodeTool));
140 registry.register(Box::new(data_processing::HashTool));
141 registry.register(Box::new(data_processing::UuidGenerateTool));
142
143 registry.register(Box::new(network_tools::HttpGetTool));
145 registry.register(Box::new(network_tools::HttpPostTool));
146 registry.register(Box::new(network_tools::DownloadFileTool));
147 registry.register(Box::new(network_tools::PingTool));
148 registry.register(Box::new(network_tools::DnsLookupTool));
149
150 registry.register(Box::new(git_tools::GitStatusTool));
152 registry.register(Box::new(git_tools::GitLogTool));
153 registry.register(Box::new(git_tools::GitDiffTool));
154 registry.register(Box::new(git_tools::GitBranchTool));
155 registry.register(Box::new(git_tools::GitAddTool));
156 registry.register(Box::new(git_tools::GitCommitTool));
157 registry.register(Box::new(git_tools::GitShowTool));
158 registry.register(Box::new(git_tools::GitStashTool));
159
160 registry.register(Box::new(system_tools::GetEnvTool));
162 registry.register(Box::new(system_tools::ListEnvTool));
163 registry.register(Box::new(system_tools::SetEnvTool));
164 registry.register(Box::new(system_tools::GetCwdTool));
165 registry.register(Box::new(system_tools::ChangeDirTool));
166 registry.register(Box::new(system_tools::SystemInfoTool));
167 registry.register(Box::new(system_tools::ProcessListTool));
168 registry.register(Box::new(system_tools::DiskUsageTool));
169 registry.register(Box::new(system_tools::MemoryUsageTool));
170
171 registry.register(Box::new(text_tools::CountLinesTool));
173 registry.register(Box::new(text_tools::WordFrequencyTool));
174 registry.register(Box::new(text_tools::TextTransformTool));
175 registry.register(Box::new(text_tools::TextSplitTool));
176 registry.register(Box::new(text_tools::RegexMatchTool));
177 registry.register(Box::new(text_tools::TextDiffTool));
178 registry.register(Box::new(text_tools::SortLinesTool));
179
180 registry
181 }
182
183 pub fn register(&mut self, tool: Box<dyn BuiltinTool>) {
185 let name = tool.name().to_string();
186 self.tools.insert(name, tool);
187 }
188
189 pub fn get(&self, name: &str) -> Option<&dyn BuiltinTool> {
191 self.tools.get(name).map(|b| b.as_ref())
192 }
193
194 pub fn list(&self) -> Vec<&dyn BuiltinTool> {
196 self.tools.values().map(|b| b.as_ref()).collect()
197 }
198
199 pub fn list_meta(&self) -> Vec<ToolMeta> {
201 self.tools.values().map(|t| t.meta()).collect()
202 }
203
204 pub fn list_by_category(&self, category: ToolCategory) -> Vec<&dyn BuiltinTool> {
206 self.tools
207 .values()
208 .filter(|t| t.category() == category)
209 .map(|b| b.as_ref())
210 .collect()
211 }
212}
213
214impl Default for BuiltinToolRegistry {
215 fn default() -> Self {
216 Self::new()
217 }
218}
219
220pub const FILE_OPS_TOOLS: &[&str] = &[
222 "read_file",
223 "write_file",
224 "edit_file",
225 "create_file",
226 "delete_file",
227 "list_directory",
228 "copy_file",
229 "move_file",
230];
231
232pub const SEARCH_TOOLS: &[&str] = &["grep", "glob", "find_in_files", "search_content"];
233
234pub const SHELL_TOOLS: &[&str] = &["bash", "run_command", "shell_exec"];
235
236pub const CODE_TOOLS: &[&str] = &[
237 "go_to_definition",
238 "find_references",
239 "get_hover",
240 "list_symbols",
241];
242
243pub const MEMORY_TOOLS: &[&str] = &["save_memory", "load_memory", "query_memory", "clear_memory"];
244
245pub const WORKFLOW_TOOLS: &[&str] = &[
246 "create_checkpoint",
247 "restore_checkpoint",
248 "list_checkpoints",
249];
250
251#[cfg(test)]
252mod tests {
253 use super::*;
254
255 #[test]
256 fn test_registry_creation() {
257 let registry = BuiltinToolRegistry::new();
258 assert!(registry.list().is_empty());
259 }
260
261 #[test]
262 fn test_tool_categories() {
263 assert!(!FILE_OPS_TOOLS.is_empty());
264 assert!(!SEARCH_TOOLS.is_empty());
265 }
266}