claude_agent/tools/
builder.rs1use std::path::PathBuf;
4use std::sync::Arc;
5
6use super::ProcessManager;
7use super::access::ToolAccess;
8use super::context::ExecutionContext;
9use super::env::ToolExecutionEnv;
10use super::registry::ToolRegistry;
11use super::traits::Tool;
12use crate::agent::{TaskOutputTool, TaskRegistry, TaskTool};
13use crate::common::IndexRegistry;
14use crate::permissions::PermissionPolicy;
15use crate::session::session_state::ToolState;
16use crate::session::{MemoryPersistence, SessionId};
17use crate::subagents::SubagentIndex;
18
19pub struct ToolRegistryBuilder {
20 access: ToolAccess,
21 working_dir: Option<PathBuf>,
22 task_registry: Option<TaskRegistry>,
23 skill_executor: Option<crate::skills::SkillExecutor>,
24 subagent_registry: Option<IndexRegistry<SubagentIndex>>,
25 policy: Option<PermissionPolicy>,
26 sandbox_config: Option<crate::security::SandboxConfig>,
27 tool_state: Option<ToolState>,
28 session_id: Option<SessionId>,
29}
30
31impl ToolRegistryBuilder {
32 pub fn new() -> Self {
33 Self {
34 access: ToolAccess::default(),
35 working_dir: None,
36 task_registry: None,
37 skill_executor: None,
38 subagent_registry: None,
39 policy: None,
40 sandbox_config: None,
41 tool_state: None,
42 session_id: None,
43 }
44 }
45
46 pub fn access(mut self, access: ToolAccess) -> Self {
47 self.access = access;
48 self
49 }
50
51 pub fn working_dir(mut self, dir: impl Into<PathBuf>) -> Self {
52 self.working_dir = Some(dir.into());
53 self
54 }
55
56 pub fn task_registry(mut self, registry: TaskRegistry) -> Self {
57 self.task_registry = Some(registry);
58 self
59 }
60
61 pub fn skill_executor(mut self, executor: crate::skills::SkillExecutor) -> Self {
62 self.skill_executor = Some(executor);
63 self
64 }
65
66 pub fn subagent_registry(mut self, registry: IndexRegistry<SubagentIndex>) -> Self {
67 self.subagent_registry = Some(registry);
68 self
69 }
70
71 pub fn policy(mut self, policy: PermissionPolicy) -> Self {
72 self.policy = Some(policy);
73 self
74 }
75
76 pub fn sandbox_config(mut self, config: crate::security::SandboxConfig) -> Self {
77 self.sandbox_config = Some(config);
78 self
79 }
80
81 pub fn tool_state(mut self, state: ToolState) -> Self {
82 self.tool_state = Some(state);
83 self
84 }
85
86 pub fn session_id(mut self, id: SessionId) -> Self {
87 self.session_id = Some(id);
88 self
89 }
90
91 pub fn build(self) -> ToolRegistry {
92 let access = &self.access;
93 let wd = self
94 .working_dir
95 .unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
96 let permission_policy = self.policy.unwrap_or_default();
97
98 let sandbox_config = self.sandbox_config.unwrap_or_else(|| {
99 crate::security::SandboxConfig::disabled().with_working_dir(wd.clone())
100 });
101
102 let security = crate::security::SecurityContext::builder()
103 .root(&wd)
104 .sandbox(sandbox_config)
105 .build()
106 .map(|mut security| {
107 security.policy = crate::security::SecurityPolicy::new(permission_policy);
108 security
109 })
110 .unwrap_or_else(|_| crate::security::SecurityContext::permissive());
111
112 let context = ExecutionContext::new(security);
113 let task_registry = self
114 .task_registry
115 .unwrap_or_else(|| TaskRegistry::new(Arc::new(MemoryPersistence::new())));
116 let process_manager = Arc::new(ProcessManager::new());
117
118 let session_id = self.session_id.unwrap_or_default();
119 let tool_state = self
120 .tool_state
121 .unwrap_or_else(|| ToolState::new(session_id));
122
123 let task_tool: Arc<dyn Tool> = match self.subagent_registry {
124 Some(sr) => Arc::new(TaskTool::new(task_registry.clone()).with_subagent_registry(sr)),
125 None => Arc::new(TaskTool::new(task_registry.clone())),
126 };
127
128 let skill_tool: Arc<dyn Tool> = match self.skill_executor {
129 Some(executor) => Arc::new(crate::skills::SkillTool::new(executor)),
130 None => Arc::new(crate::skills::SkillTool::with_defaults()),
131 };
132
133 let all_tools: Vec<Arc<dyn Tool>> = vec![
134 Arc::new(super::ReadTool),
135 Arc::new(super::WriteTool),
136 Arc::new(super::EditTool),
137 Arc::new(super::GlobTool),
138 Arc::new(super::GrepTool),
139 Arc::new(super::BashTool::with_process_manager(
140 process_manager.clone(),
141 )),
142 Arc::new(super::KillShellTool::with_process_manager(
143 process_manager.clone(),
144 )),
145 task_tool,
146 Arc::new(TaskOutputTool::new(task_registry.clone())),
147 Arc::new(super::TodoWriteTool::new(tool_state.clone(), session_id)),
148 Arc::new(super::PlanTool::new(tool_state.clone())),
149 skill_tool,
150 ];
151
152 let env = ToolExecutionEnv {
153 context,
154 tool_state: Some(tool_state),
155 process_manager: Some(process_manager),
156 };
157
158 let mut registry = ToolRegistry::with_env(task_registry, env);
159
160 for tool in all_tools {
161 if access.is_allowed(tool.name()) {
162 registry.register(tool);
163 }
164 }
165
166 registry
167 }
168}
169
170impl Default for ToolRegistryBuilder {
171 fn default() -> Self {
172 Self::new()
173 }
174}