1use std::sync::Arc;
4
5use agentic_tools_core::ToolRegistry;
6use agentic_tools_core::context::ToolContext;
7use agentic_tools_core::error::ToolError;
8use agentic_tools_core::tool::Tool;
9use futures::future::BoxFuture;
10
11use crate::WebTools;
12use crate::types::{WebFetchInput, WebFetchOutput, WebSearchInput, WebSearchOutput};
13
14#[derive(Clone)]
20pub struct WebFetchTool {
21 tools: Arc<WebTools>,
22}
23
24impl WebFetchTool {
25 #[must_use]
27 pub const fn new(tools: Arc<WebTools>) -> Self {
28 Self { tools }
29 }
30}
31
32impl Tool for WebFetchTool {
33 type Input = WebFetchInput;
34 type Output = WebFetchOutput;
35
36 const NAME: &'static str = "web_fetch";
37 const DESCRIPTION: &'static str = "Fetch a URL over HTTP and convert the page to clean Markdown with metadata. Default summarize=false; set summarize=true to generate a short Haiku summary (requires Anthropic credentials).";
38
39 fn call(
40 &self,
41 input: Self::Input,
42 _ctx: &ToolContext,
43 ) -> BoxFuture<'static, Result<Self::Output, ToolError>> {
44 let tools = self.tools.clone();
45 Box::pin(async move { crate::fetch::web_fetch(&tools, input).await })
46 }
47}
48
49#[derive(Clone)]
55pub struct WebSearchTool {
56 tools: Arc<WebTools>,
57}
58
59impl WebSearchTool {
60 #[must_use]
62 pub const fn new(tools: Arc<WebTools>) -> Self {
63 Self { tools }
64 }
65}
66
67impl Tool for WebSearchTool {
68 type Input = WebSearchInput;
69 type Output = WebSearchOutput;
70
71 const NAME: &'static str = "web_search";
72 const DESCRIPTION: &'static str = "Semantic/neural web search (Exa). Use NATURAL LANGUAGE queries (questions/descriptions). Do NOT use keyword-stuffed, Google-style queries. Returns compact, citable result cards with URLs plus a short trimmed context to orient you.";
73
74 fn call(
75 &self,
76 input: Self::Input,
77 _ctx: &ToolContext,
78 ) -> BoxFuture<'static, Result<Self::Output, ToolError>> {
79 let tools = self.tools.clone();
80 Box::pin(async move { crate::search::web_search(&tools, input).await })
81 }
82}
83
84pub fn build_registry(tools: Arc<WebTools>) -> ToolRegistry {
90 ToolRegistry::builder()
91 .register::<WebFetchTool, ()>(WebFetchTool::new(tools.clone()))
92 .register::<WebSearchTool, ()>(WebSearchTool::new(tools))
93 .finish()
94}