Skip to main content

matrixcode_core/tools/
browser.rs

1//! 浏览器打开工具
2//!
3//! 使用系统默认浏览器打开指定的 URL
4
5use async_trait::async_trait;
6use serde_json::{json, Value};
7
8use crate::tools::Tool;
9
10/// 浏览器打开工具
11pub struct BrowserOpenTool;
12
13#[async_trait]
14impl Tool for BrowserOpenTool {
15    fn definition(&self) -> crate::tools::ToolDefinition {
16        crate::tools::ToolDefinition {
17            name: "browser_open".to_string(),
18            description: "使用系统默认浏览器打开指定的 URL。适用于预览网页、文档或在线资源。".to_string(),
19            parameters: json!({
20                "type": "object",
21                "properties": {
22                    "url": {
23                        "type": "string",
24                        "description": "要打开的 URL"
25                    }
26                },
27                "required": ["url"]
28            }),
29            ..Default::default()
30        }
31    }
32
33    async fn execute(&self, params: Value) -> anyhow::Result<String> {
34        let url = params["url"]
35            .as_str()
36            .ok_or_else(|| anyhow::anyhow!("missing 'url' parameter"))?;
37
38        // 验证 URL 格式
39        let url = url.trim();
40        if url.is_empty() {
41            return Err(anyhow::anyhow!("URL 不能为空"));
42        }
43
44        // 确保 URL 以 http:// 或 https:// 开头
45        let url = if url.starts_with("http://") || url.starts_with("https://") {
46            url.to_string()
47        } else {
48            format!("https://{}", url)
49        };
50
51        // 使用系统默认浏览器打开 URL
52        #[cfg(target_os = "windows")]
53        let result = {
54            std::process::Command::new("cmd")
55                .args(["/C", "start", &url])
56                .spawn()
57                .map(|_| ())
58                .map_err(|e| anyhow::anyhow!("无法打开浏览器: {}", e))
59        };
60
61        #[cfg(target_os = "macos")]
62        let result = {
63            std::process::Command::new("open")
64                .arg(&url)
65                .spawn()
66                .map(|_| ())
67                .map_err(|e| anyhow::anyhow!("无法打开浏览器: {}", e))
68        };
69
70        #[cfg(target_os = "linux")]
71        let result = {
72            std::process::Command::new("xdg-open")
73                .arg(&url)
74                .spawn()
75                .map(|_| ())
76                .map_err(|e| anyhow::anyhow!("无法打开浏览器: {}", e))
77        };
78
79        result.map(|_| format!("已打开浏览器: {}", url))
80    }
81}