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//! ## Plugin tools
7//!
8//! `agentic_search` and `agentic_parse` are NOT registered by default.
9//! They are opt-in plugins: users enable them via `SessionOptions` or by
10//! calling `register_agentic_tools` directly.
11
12pub(crate) mod agentic_parse;
13pub(crate) mod agentic_search;
14mod bash;
15pub mod batch;
16mod edit;
17mod git_worktree;
18mod glob_tool;
19mod grep;
20mod ls;
21mod patch;
22mod read;
23mod web_fetch;
24mod web_search;
25mod write;
26
27use super::registry::ToolRegistry;
28use std::sync::Arc;
29
30/// Register all core built-in tools with the registry.
31///
32/// Does NOT include plugin tools (`agentic_search`, `agentic_parse`).
33/// Those are opt-in — call `register_agentic_tools` to enable them.
34///
35/// Note: `batch` is NOT registered here — it requires an `Arc<ToolRegistry>`
36/// and must be registered after the registry is wrapped in an Arc.
37pub fn register_builtins(registry: &ToolRegistry) {
38    registry.register_builtin(Arc::new(read::ReadTool));
39    registry.register_builtin(Arc::new(write::WriteTool));
40    registry.register_builtin(Arc::new(edit::EditTool));
41    registry.register_builtin(Arc::new(patch::PatchTool));
42    registry.register_builtin(Arc::new(bash::BashTool));
43    registry.register_builtin(Arc::new(grep::GrepTool));
44    registry.register_builtin(Arc::new(glob_tool::GlobTool));
45    registry.register_builtin(Arc::new(ls::LsTool));
46    registry.register_builtin(Arc::new(web_fetch::WebFetchTool));
47    registry.register_builtin(Arc::new(web_search::WebSearchTool));
48    registry.register_builtin(Arc::new(git_worktree::GitWorktreeTool));
49}
50
51/// Register the batch tool. Must be called after the registry is wrapped in Arc.
52pub fn register_batch(registry: &Arc<ToolRegistry>) {
53    registry.register_builtin(Arc::new(batch::BatchTool::new(Arc::clone(registry))));
54}
55
56/// Register the agentic plugin tools (`agentic_search`, `agentic_parse`).
57///
58/// These are opt-in — they are NOT part of the default toolset.
59///
60/// - `agentic_search`: multi-phase semantic code search
61/// - `agentic_parse`: LLM-enhanced document parsing
62///
63/// `llm` is required by `agentic_parse` for its extraction pass.
64/// Pass `None` to register only `agentic_search`.
65pub fn register_agentic_tools(
66    registry: &Arc<ToolRegistry>,
67    llm: Option<Arc<dyn crate::llm::LlmClient>>,
68) {
69    registry.register_builtin(Arc::new(agentic_search::AgenticSearchTool::new()));
70    if let Some(llm_client) = llm {
71        registry.register_builtin(Arc::new(agentic_parse::AgenticParseTool::new(llm_client)));
72    }
73}
74
75/// Register the task delegation tools (task, parallel_task).
76///
77/// Must be called after the registry is wrapped in Arc. Requires an LLM client
78/// and the workspace path so child agent loops can be spawned inline.
79/// Optionally accepts an MCP manager so child sessions inherit MCP tools.
80pub fn register_task(
81    registry: &Arc<ToolRegistry>,
82    llm_client: Arc<dyn crate::llm::LlmClient>,
83    agent_registry: Arc<crate::subagent::AgentRegistry>,
84    workspace: String,
85) {
86    register_task_with_mcp(registry, llm_client, agent_registry, workspace, None);
87}
88
89/// Register the task delegation tools with optional MCP manager.
90///
91/// When `mcp_manager` is provided, child subagent sessions will have access
92/// to all MCP tools from connected servers.
93pub fn register_task_with_mcp(
94    registry: &Arc<ToolRegistry>,
95    llm_client: Arc<dyn crate::llm::LlmClient>,
96    agent_registry: Arc<crate::subagent::AgentRegistry>,
97    workspace: String,
98    mcp_manager: Option<Arc<crate::mcp::manager::McpManager>>,
99) {
100    use crate::tools::task::{ParallelTaskTool, RunTeamTool, TaskExecutor, TaskTool};
101    let executor = Arc::new(match mcp_manager {
102        Some(mcp) => TaskExecutor::with_mcp(agent_registry, llm_client, workspace, mcp),
103        None => TaskExecutor::new(agent_registry, llm_client, workspace),
104    });
105    registry.register_builtin(Arc::new(TaskTool::new(Arc::clone(&executor))));
106    registry.register_builtin(Arc::new(ParallelTaskTool::new(Arc::clone(&executor))));
107    registry.register_builtin(Arc::new(RunTeamTool::new(executor)));
108}
109
110/// Register the Skill tool for skill-based tool access control.
111pub fn register_skill(
112    registry: &Arc<ToolRegistry>,
113    llm_client: Arc<dyn crate::llm::LlmClient>,
114    skill_registry: Arc<crate::skills::SkillRegistry>,
115    tool_executor: Arc<crate::tools::ToolExecutor>,
116    base_config: crate::agent::AgentConfig,
117) {
118    use crate::tools::skill::SkillTool;
119    registry.register_builtin(Arc::new(SkillTool::new(
120        skill_registry,
121        llm_client,
122        tool_executor,
123        base_config,
124    )));
125}