Skip to main content

a3s_code_core/tools/builtin/
mod.rs

1//! Native Rust implementations of all built-in tools
2//!
3//! These replace the previous `a3s-tools` binary backend with direct Rust
4//! implementations that execute in-process. Each tool implements the `Tool` trait.
5//!
6//! `agentic_search` and `agentic_parse` are native built-in tools.
7//! Session builders decide whether they are enabled by default based on config.
8
9pub(crate) mod agentic_parse;
10pub(crate) mod agentic_search;
11mod bash;
12pub mod batch;
13mod edit;
14mod git_worktree;
15mod glob_tool;
16mod grep;
17mod ls;
18mod patch;
19mod read;
20mod web_fetch;
21mod web_search;
22mod write;
23
24use super::registry::ToolRegistry;
25use std::sync::Arc;
26
27/// Register all baseline built-in tools with the registry.
28///
29/// Note: `batch` is NOT registered here — it requires an `Arc<ToolRegistry>`
30/// and must be registered after the registry is wrapped in an Arc.
31pub fn register_builtins(registry: &ToolRegistry) {
32    registry.register_builtin(Arc::new(read::ReadTool));
33    registry.register_builtin(Arc::new(write::WriteTool));
34    registry.register_builtin(Arc::new(edit::EditTool));
35    registry.register_builtin(Arc::new(patch::PatchTool));
36    registry.register_builtin(Arc::new(bash::BashTool));
37    registry.register_builtin(Arc::new(grep::GrepTool));
38    registry.register_builtin(Arc::new(glob_tool::GlobTool));
39    registry.register_builtin(Arc::new(ls::LsTool));
40    registry.register_builtin(Arc::new(web_fetch::WebFetchTool));
41    registry.register_builtin(Arc::new(web_search::WebSearchTool));
42    registry.register_builtin(Arc::new(git_worktree::GitWorktreeTool));
43}
44
45/// Register the batch tool. Must be called after the registry is wrapped in Arc.
46pub fn register_batch(registry: &Arc<ToolRegistry>) {
47    registry.register_builtin(Arc::new(batch::BatchTool::new(Arc::clone(registry))));
48}
49
50/// Register the built-in agentic tools.
51///
52/// - `agentic_search`: multi-phase semantic code search
53/// - `agentic_parse`: LLM-enhanced document parsing
54pub fn register_agentic_tools(
55    registry: &Arc<ToolRegistry>,
56    llm: Option<Arc<dyn crate::llm::LlmClient>>,
57    search_enabled: bool,
58    parse_enabled: bool,
59) {
60    if search_enabled {
61        registry.register_builtin(Arc::new(agentic_search::AgenticSearchTool::new()));
62    }
63    if parse_enabled {
64        if let Some(llm_client) = llm {
65            registry.register_builtin(Arc::new(agentic_parse::AgenticParseTool::new(llm_client)));
66        } else {
67            tracing::warn!(
68                "Skipping built-in agentic_parse registration because no default LLM client is configured"
69            );
70        }
71    }
72}
73
74/// Register the task delegation tools (task, parallel_task).
75///
76/// Must be called after the registry is wrapped in Arc. Requires an LLM client
77/// and the workspace path so child agent loops can be spawned inline.
78/// Optionally accepts an MCP manager so child sessions inherit MCP tools.
79pub fn register_task(
80    registry: &Arc<ToolRegistry>,
81    llm_client: Arc<dyn crate::llm::LlmClient>,
82    agent_registry: Arc<crate::subagent::AgentRegistry>,
83    workspace: String,
84) {
85    register_task_with_mcp(registry, llm_client, agent_registry, workspace, None);
86}
87
88/// Register the task delegation tools with optional MCP manager.
89///
90/// When `mcp_manager` is provided, child subagent sessions will have access
91/// to all MCP tools from connected servers.
92pub fn register_task_with_mcp(
93    registry: &Arc<ToolRegistry>,
94    llm_client: Arc<dyn crate::llm::LlmClient>,
95    agent_registry: Arc<crate::subagent::AgentRegistry>,
96    workspace: String,
97    mcp_manager: Option<Arc<crate::mcp::manager::McpManager>>,
98) {
99    use crate::tools::task::{ParallelTaskTool, RunTeamTool, TaskExecutor, TaskTool};
100    let executor = Arc::new(match mcp_manager {
101        Some(mcp) => TaskExecutor::with_mcp(agent_registry, llm_client, workspace, mcp),
102        None => TaskExecutor::new(agent_registry, llm_client, workspace),
103    });
104    registry.register_builtin(Arc::new(TaskTool::new(Arc::clone(&executor))));
105    registry.register_builtin(Arc::new(ParallelTaskTool::new(Arc::clone(&executor))));
106    registry.register_builtin(Arc::new(RunTeamTool::new(executor)));
107}
108
109/// Register the Skill tool for skill-based tool access control.
110pub fn register_skill(
111    registry: &Arc<ToolRegistry>,
112    llm_client: Arc<dyn crate::llm::LlmClient>,
113    skill_registry: Arc<crate::skills::SkillRegistry>,
114    tool_executor: Arc<crate::tools::ToolExecutor>,
115    base_config: crate::agent::AgentConfig,
116) {
117    use crate::tools::skill::SkillTool;
118    registry.register_builtin(Arc::new(SkillTool::new(
119        skill_registry,
120        llm_client,
121        tool_executor,
122        base_config,
123    )));
124}