Skip to main content

telos_agent/tools/builtin/browser/tool_impls/
navigation.rs

1use async_trait::async_trait;
2use serde_json::{Value, json};
3
4use crate::error::AgentError;
5use crate::tools::api::{Tool, ToolContext, ToolDefinition, ToolOutput};
6use crate::tools::browser::manager::BrowserManager;
7use crate::tools::browser::util::*;
8
9pub struct BrowserNavigateTool {
10    manager: BrowserManager,
11}
12
13impl BrowserNavigateTool {
14    pub fn new(manager: BrowserManager) -> Self {
15        Self { manager }
16    }
17}
18
19#[async_trait]
20impl Tool for BrowserNavigateTool {
21    fn definition(&self) -> ToolDefinition {
22        ToolDefinition {
23            name: "BrowserNavigate".into(),
24            description:
25                "Navigate a browser session to an http/https URL and return a page summary.".into(),
26            input_schema: json!({
27                "type": "object",
28                "properties": {
29                    "url": { "type": "string" },
30                    "browser_session_id": { "type": "string" },
31                    "headless": { "type": "boolean" },
32                    "width": { "type": "integer" },
33                    "height": { "type": "integer" },
34                    "allowed_domains": { "type": "array", "items": { "type": "string" } },
35                    "prohibited_domains": { "type": "array", "items": { "type": "string" } }
36                },
37                "required": ["url"]
38            }),
39        }
40    }
41
42    async fn validate(&self, arguments: &Value, _context: &ToolContext) -> Result<(), AgentError> {
43        let url = arguments
44            .get("url")
45            .and_then(Value::as_str)
46            .ok_or_else(|| AgentError::Validation("missing string `url`".into()))?;
47        validate_http_url(url)
48    }
49
50    async fn invoke(
51        &self,
52        arguments: Value,
53        context: ToolContext,
54    ) -> Result<ToolOutput, AgentError> {
55        let url = arguments.get("url").and_then(Value::as_str).unwrap();
56        let (_, session, _) = self.manager.start_or_update(&arguments, &context).await?;
57        let mut session = session.lock().await;
58        let result = session.navigate(url, &context).await?;
59        Ok(ToolOutput::json(result))
60    }
61}