Skip to main content

opendev_tools_impl/
open_browser.rs

1//! Open browser tool — open a URL in the system's default browser.
2
3use std::collections::HashMap;
4
5use opendev_tools_core::{BaseTool, ToolContext, ToolResult};
6
7/// Tool for opening URLs in the default browser.
8#[derive(Debug)]
9pub struct OpenBrowserTool;
10
11#[async_trait::async_trait]
12impl BaseTool for OpenBrowserTool {
13    fn name(&self) -> &str {
14        "open_browser"
15    }
16
17    fn description(&self) -> &str {
18        "Open a URL in the system's default web browser."
19    }
20
21    fn parameter_schema(&self) -> serde_json::Value {
22        serde_json::json!({
23            "type": "object",
24            "properties": {
25                "url": {
26                    "type": "string",
27                    "description": "URL to open in the browser"
28                }
29            },
30            "required": ["url"]
31        })
32    }
33
34    async fn execute(
35        &self,
36        args: HashMap<String, serde_json::Value>,
37        _ctx: &ToolContext,
38    ) -> ToolResult {
39        let url = match args.get("url").and_then(|v| v.as_str()) {
40            Some(u) => u,
41            None => return ToolResult::fail("url is required"),
42        };
43
44        // Basic validation
45        if !url.starts_with("http://") && !url.starts_with("https://") {
46            return ToolResult::fail("URL must start with http:// or https://");
47        }
48
49        match open::that(url) {
50            Ok(_) => ToolResult::ok(format!("Opened {url} in default browser")),
51            Err(e) => ToolResult::fail(format!("Failed to open browser: {e}")),
52        }
53    }
54}
55
56#[cfg(test)]
57#[path = "open_browser_tests.rs"]
58mod tests;