Skip to main content

matrixcode_core/tools/
browser.rs

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