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;
13use crate::types::WebFetchOutput;
14use crate::types::WebSearchInput;
15use crate::types::WebSearchOutput;
16
17#[derive(Clone)]
23pub struct WebFetchTool {
24 tools: Arc<WebTools>,
25}
26
27impl WebFetchTool {
28 #[must_use]
30 pub const fn new(tools: Arc<WebTools>) -> Self {
31 Self { tools }
32 }
33}
34
35impl Tool for WebFetchTool {
36 type Input = WebFetchInput;
37 type Output = WebFetchOutput;
38
39 const NAME: &'static str = "web_fetch";
40 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).";
41
42 fn call(
43 &self,
44 input: Self::Input,
45 _ctx: &ToolContext,
46 ) -> BoxFuture<'static, Result<Self::Output, ToolError>> {
47 let tools = Arc::clone(&self.tools);
48 Box::pin(async move { crate::fetch::web_fetch(&tools, input).await })
49 }
50}
51
52#[derive(Clone)]
58pub struct WebSearchTool {
59 tools: Arc<WebTools>,
60}
61
62impl WebSearchTool {
63 #[must_use]
65 pub const fn new(tools: Arc<WebTools>) -> Self {
66 Self { tools }
67 }
68}
69
70impl Tool for WebSearchTool {
71 type Input = WebSearchInput;
72 type Output = WebSearchOutput;
73
74 const NAME: &'static str = "web_search";
75 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.";
76
77 fn call(
78 &self,
79 input: Self::Input,
80 _ctx: &ToolContext,
81 ) -> BoxFuture<'static, Result<Self::Output, ToolError>> {
82 let tools = Arc::clone(&self.tools);
83 Box::pin(async move { crate::search::web_search(&tools, input).await })
84 }
85}
86
87pub fn build_registry(tools: Arc<WebTools>) -> ToolRegistry {
93 ToolRegistry::builder()
94 .register::<WebFetchTool, ()>(WebFetchTool::new(Arc::clone(&tools)))
95 .register::<WebSearchTool, ()>(WebSearchTool::new(tools))
96 .finish()
97}