agent_diva_agent/agent_loop/
loop_tools.rs1use super::{AgentLoop, ToolConfig};
2use crate::tool_config::network::NetworkToolConfig;
3use agent_diva_core::config::MCPServerConfig;
4use agent_diva_tools::{
5 load_mcp_tools_sync, CronTool, EditFileTool, ExecTool, ListDirTool, ReadFileTool, SpawnTool,
6 ToolError, ToolRegistry, WebFetchTool, WebSearchTool, WriteFileTool,
7};
8use std::collections::HashMap;
9use std::sync::Arc;
10use tracing::info;
11
12impl AgentLoop {
13 pub fn register_default_tools(&mut self, tool_config: ToolConfig) {
15 let sm = self.subagent_manager.clone();
17 self.tools.register(Arc::new(SpawnTool::new(
18 move |task, label, channel, chat_id| {
19 let sm = sm.clone();
20 async move {
21 sm.spawn(task, label, channel, chat_id)
22 .await
23 .map_err(|e| ToolError::ExecutionFailed(e.to_string()))
24 }
25 },
26 )));
27
28 let allowed_dir = if tool_config.restrict_to_workspace {
30 Some(self.workspace.clone())
31 } else {
32 None
33 };
34 self.tools
35 .register(Arc::new(ReadFileTool::new(allowed_dir.clone())));
36 self.tools
37 .register(Arc::new(WriteFileTool::new(allowed_dir.clone())));
38 self.tools
39 .register(Arc::new(EditFileTool::new(allowed_dir.clone())));
40 self.tools.register(Arc::new(ListDirTool::new(allowed_dir)));
41
42 self.tools.register(Arc::new(ExecTool::with_config(
44 tool_config.exec_timeout,
45 Some(self.workspace.clone()),
46 tool_config.restrict_to_workspace,
47 )));
48
49 Self::register_web_tools(&mut self.tools, &tool_config.network);
51
52 for mcp_tool in load_mcp_tools_sync(&tool_config.mcp_servers) {
54 self.tools.register(mcp_tool);
55 }
56
57 if let Some(cron_service) = tool_config.cron_service {
59 self.tools.register(Arc::new(CronTool::new(cron_service)));
60 }
61 }
62
63 pub(super) fn register_web_tools(tools: &mut ToolRegistry, network: &NetworkToolConfig) {
64 if network.web.search.enabled {
65 tools.register(Arc::new(WebSearchTool::with_provider_and_max_results(
66 network.web.search.provider.clone(),
67 network.web.search.api_key.clone(),
68 network.web.search.normalized_max_results(),
69 )));
70 }
71 if network.web.fetch.enabled {
72 tools.register(Arc::new(WebFetchTool::new()));
73 }
74 }
75
76 pub(super) async fn apply_network_config(&mut self, network: NetworkToolConfig) {
77 self.tools.unregister("web_search");
78 self.tools.unregister("web_fetch");
79 Self::register_web_tools(&mut self.tools, &network);
80 self.subagent_manager.update_network_config(network).await;
81 info!("Applied runtime network tool configuration update");
82 }
83
84 pub(super) async fn apply_mcp_config(&mut self, servers: HashMap<String, MCPServerConfig>) {
85 for name in self
86 .tools
87 .tool_names()
88 .into_iter()
89 .filter(|name| name.starts_with("mcp_"))
90 {
91 self.tools.unregister(&name);
92 }
93
94 for mcp_tool in load_mcp_tools_sync(&servers) {
95 self.tools.register(mcp_tool);
96 }
97
98 info!("Applied runtime MCP tool configuration update");
99 }
100}