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
6mod bash;
7pub mod batch;
8mod edit;
9mod generate_object;
10mod git;
11mod glob_tool;
12mod grep;
13mod ls;
14mod patch;
15mod read;
16mod web_fetch;
17mod web_search;
18mod write;
19
20use super::registry::ToolRegistry;
21use std::sync::Arc;
22
23/// Register all baseline built-in tools with the registry.
24///
25/// Note: `batch` is NOT registered here — it requires an `Arc<ToolRegistry>`
26/// and must be registered after the registry is wrapped in an Arc.
27pub fn register_builtins(registry: &ToolRegistry) {
28    registry.register_builtin(Arc::new(read::ReadTool));
29    registry.register_builtin(Arc::new(write::WriteTool));
30    registry.register_builtin(Arc::new(edit::EditTool));
31    registry.register_builtin(Arc::new(patch::PatchTool));
32    registry.register_builtin(Arc::new(bash::BashTool));
33    registry.register_builtin(Arc::new(grep::GrepTool));
34    registry.register_builtin(Arc::new(glob_tool::GlobTool));
35    registry.register_builtin(Arc::new(ls::LsTool));
36    registry.register_builtin(Arc::new(web_fetch::WebFetchTool));
37    registry.register_builtin(Arc::new(web_search::WebSearchTool::new()));
38    registry.register_builtin(Arc::new(git::GitTool));
39}
40
41/// Register the batch tool. Must be called after the registry is wrapped in Arc.
42pub fn register_batch(registry: &Arc<ToolRegistry>) {
43    registry.register_builtin(Arc::new(batch::BatchTool::new(Arc::clone(registry))));
44}
45
46/// Register the programmatic tool calling wrapper.
47pub fn register_program(registry: &Arc<ToolRegistry>) {
48    register_program_with_catalog(
49        registry,
50        crate::program::ProgramCatalog::with_builtin_programs(),
51    );
52}
53
54/// Register the programmatic tool calling wrapper with a custom catalog.
55pub fn register_program_with_catalog(
56    registry: &Arc<ToolRegistry>,
57    catalog: crate::program::ProgramCatalog,
58) {
59    registry.register_builtin(Arc::new(crate::tools::ProgramTool::with_catalog(
60        Arc::clone(registry),
61        catalog,
62    )));
63}
64
65/// Register the task delegation tools (task, parallel_task).
66///
67/// Must be called after the registry is wrapped in Arc. Requires an LLM client
68/// and the workspace path so child agent loops can be spawned inline.
69/// Optionally accepts an MCP manager so child sessions inherit MCP tools.
70pub fn register_task(
71    registry: &Arc<ToolRegistry>,
72    llm_client: Arc<dyn crate::llm::LlmClient>,
73    agent_registry: Arc<crate::subagent::AgentRegistry>,
74    workspace: String,
75) {
76    register_task_with_mcp(registry, llm_client, agent_registry, workspace, None, None);
77}
78
79/// Register the task delegation tools with optional MCP manager and parent context.
80///
81/// When `mcp_manager` is provided, delegated child sessions will have access
82/// to all MCP tools from connected servers.
83/// When `parent_context` is provided, child runs inherit parent capabilities.
84pub fn register_task_with_mcp(
85    registry: &Arc<ToolRegistry>,
86    llm_client: Arc<dyn crate::llm::LlmClient>,
87    agent_registry: Arc<crate::subagent::AgentRegistry>,
88    workspace: String,
89    mcp_manager: Option<Arc<crate::mcp::manager::McpManager>>,
90    parent_context: Option<crate::child_run::ChildRunContext>,
91) {
92    use crate::tools::task::{ParallelTaskTool, TaskExecutor, TaskTool};
93    let mut executor = match mcp_manager {
94        Some(mcp) => TaskExecutor::with_mcp(agent_registry, llm_client, workspace, mcp),
95        None => TaskExecutor::new(agent_registry, llm_client, workspace),
96    };
97    if let Some(ctx) = parent_context {
98        executor = executor.with_parent_context(ctx);
99    }
100    let executor = Arc::new(executor);
101    registry.register_builtin(Arc::new(TaskTool::new(Arc::clone(&executor))));
102    registry.register_builtin(Arc::new(ParallelTaskTool::new(Arc::clone(&executor))));
103}
104
105/// Register the Skill tool for skill-based tool access control.
106pub(crate) fn register_skill(
107    registry: &Arc<ToolRegistry>,
108    llm_client: Arc<dyn crate::llm::LlmClient>,
109    skill_registry: Arc<crate::skills::SkillRegistry>,
110    tool_executor: Arc<crate::tools::ToolExecutor>,
111    base_config: crate::agent::AgentConfig,
112) {
113    use crate::tools::skill::{SearchSkillsTool, SkillTool};
114    registry.register_builtin(Arc::new(SearchSkillsTool::new(Arc::clone(&skill_registry))));
115    registry.register_builtin(Arc::new(SkillTool::new(
116        skill_registry,
117        llm_client,
118        tool_executor,
119        base_config,
120    )));
121}
122
123/// Register the `generate_object` tool for structured JSON output.
124///
125/// Must be called after the registry is wrapped in Arc. Requires an LLM client
126/// so the tool can make its own LLM calls for object generation.
127pub fn register_generate_object(
128    registry: &Arc<ToolRegistry>,
129    llm_client: Arc<dyn crate::llm::LlmClient>,
130) {
131    registry.register_builtin(Arc::new(generate_object::GenerateObjectTool::new(
132        llm_client,
133    )));
134}