adk_browser/tools/
navigate.rs

1//! Navigate tool for browser navigation.
2
3use crate::session::BrowserSession;
4use adk_core::{Result, Tool, ToolContext};
5use async_trait::async_trait;
6use serde_json::{json, Value};
7use std::sync::Arc;
8
9/// Tool for navigating to URLs.
10pub struct NavigateTool {
11    browser: Arc<BrowserSession>,
12}
13
14impl NavigateTool {
15    /// Create a new navigate tool with a shared browser session.
16    pub fn new(browser: Arc<BrowserSession>) -> Self {
17        Self { browser }
18    }
19}
20
21#[async_trait]
22impl Tool for NavigateTool {
23    fn name(&self) -> &str {
24        "browser_navigate"
25    }
26
27    fn description(&self) -> &str {
28        "Navigate the browser to a specified URL. Use this to open web pages."
29    }
30
31    fn parameters_schema(&self) -> Option<Value> {
32        Some(json!({
33            "type": "object",
34            "properties": {
35                "url": {
36                    "type": "string",
37                    "description": "The URL to navigate to (e.g., 'https://example.com')"
38                }
39            },
40            "required": ["url"]
41        }))
42    }
43
44    fn response_schema(&self) -> Option<Value> {
45        Some(json!({
46            "type": "object",
47            "properties": {
48                "success": { "type": "boolean" },
49                "url": { "type": "string" },
50                "title": { "type": "string" }
51            }
52        }))
53    }
54
55    async fn execute(&self, _ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
56        let url = args
57            .get("url")
58            .and_then(|v| v.as_str())
59            .ok_or_else(|| adk_core::AdkError::Tool("Missing 'url' parameter".to_string()))?;
60
61        // Validate URL
62        url::Url::parse(url)
63            .map_err(|e| adk_core::AdkError::Tool(format!("Invalid URL '{}': {}", url, e)))?;
64
65        // Navigate
66        self.browser.navigate(url).await?;
67
68        // Get result info
69        let current_url = self.browser.current_url().await.unwrap_or_default();
70        let title = self.browser.title().await.unwrap_or_default();
71
72        Ok(json!({
73            "success": true,
74            "url": current_url,
75            "title": title
76        }))
77    }
78}
79
80/// Tool for going back in browser history.
81pub struct BackTool {
82    browser: Arc<BrowserSession>,
83}
84
85impl BackTool {
86    pub fn new(browser: Arc<BrowserSession>) -> Self {
87        Self { browser }
88    }
89}
90
91#[async_trait]
92impl Tool for BackTool {
93    fn name(&self) -> &str {
94        "browser_back"
95    }
96
97    fn description(&self) -> &str {
98        "Go back to the previous page in browser history."
99    }
100
101    fn parameters_schema(&self) -> Option<Value> {
102        Some(json!({
103            "type": "object",
104            "properties": {}
105        }))
106    }
107
108    async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
109        self.browser.back().await?;
110
111        let url = self.browser.current_url().await.unwrap_or_default();
112        let title = self.browser.title().await.unwrap_or_default();
113
114        Ok(json!({
115            "success": true,
116            "url": url,
117            "title": title
118        }))
119    }
120}
121
122/// Tool for going forward in browser history.
123pub struct ForwardTool {
124    browser: Arc<BrowserSession>,
125}
126
127impl ForwardTool {
128    pub fn new(browser: Arc<BrowserSession>) -> Self {
129        Self { browser }
130    }
131}
132
133#[async_trait]
134impl Tool for ForwardTool {
135    fn name(&self) -> &str {
136        "browser_forward"
137    }
138
139    fn description(&self) -> &str {
140        "Go forward to the next page in browser history."
141    }
142
143    fn parameters_schema(&self) -> Option<Value> {
144        Some(json!({
145            "type": "object",
146            "properties": {}
147        }))
148    }
149
150    async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
151        self.browser.forward().await?;
152
153        let url = self.browser.current_url().await.unwrap_or_default();
154        let title = self.browser.title().await.unwrap_or_default();
155
156        Ok(json!({
157            "success": true,
158            "url": url,
159            "title": title
160        }))
161    }
162}
163
164/// Tool for refreshing the current page.
165pub struct RefreshTool {
166    browser: Arc<BrowserSession>,
167}
168
169impl RefreshTool {
170    pub fn new(browser: Arc<BrowserSession>) -> Self {
171        Self { browser }
172    }
173}
174
175#[async_trait]
176impl Tool for RefreshTool {
177    fn name(&self) -> &str {
178        "browser_refresh"
179    }
180
181    fn description(&self) -> &str {
182        "Refresh the current page."
183    }
184
185    fn parameters_schema(&self) -> Option<Value> {
186        Some(json!({
187            "type": "object",
188            "properties": {}
189        }))
190    }
191
192    async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
193        self.browser.refresh().await?;
194
195        let url = self.browser.current_url().await.unwrap_or_default();
196        let title = self.browser.title().await.unwrap_or_default();
197
198        Ok(json!({
199            "success": true,
200            "url": url,
201            "title": title
202        }))
203    }
204}