Skip to main content

codetether_agent/tool/browserctl/
mod.rs

1mod actions;
2mod dispatch;
3mod helpers;
4mod input;
5mod response;
6mod schema;
7mod screenshot;
8
9use super::{Tool, ToolResult};
10use anyhow::{Context, Result};
11use async_trait::async_trait;
12use serde_json::Value;
13
14pub struct BrowserCtlTool;
15
16impl BrowserCtlTool {
17    pub fn new() -> Self {
18        Self
19    }
20}
21
22impl Default for BrowserCtlTool {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28#[async_trait]
29impl Tool for BrowserCtlTool {
30    fn id(&self) -> &str {
31        "browserctl"
32    }
33    fn name(&self) -> &str {
34        "Browser Control"
35    }
36    fn description(&self) -> &str {
37        "Control the browser session for navigation, DOM inspection, evaluation, screenshots, tabs, and robust interaction with modern web apps."
38    }
39    fn parameters(&self) -> Value {
40        schema::parameters_schema()
41    }
42
43    async fn execute(&self, args: Value) -> Result<ToolResult> {
44        let input: input::BrowserCtlInput =
45            serde_json::from_value(args).context("Invalid browserctl args")?;
46        if matches!(&input.action, input::BrowserCtlAction::Detect) {
47            return Ok(detect_result());
48        }
49        let result = match dispatch::dispatch(&input).await {
50            Ok(output) => response::success_result(&input, output).await?,
51            Err(error) => response::error_result(error),
52        };
53        if matches!(&input.action, input::BrowserCtlAction::Stop) && result.success {
54            crate::browser::browser_service().clear();
55        }
56        Ok(result)
57    }
58}
59
60fn detect_result() -> ToolResult {
61    match crate::browser::detect_browser() {
62        Some(path) => {
63            let output = serde_json::json!({
64                "found": true,
65                "executable_path": path.display().to_string(),
66                "platform": std::env::consts::OS,
67            });
68            ToolResult {
69                output: serde_json::to_string_pretty(&output).unwrap_or_default(),
70                success: true,
71                metadata: Default::default(),
72            }
73        }
74        None => {
75            let output = serde_json::json!({
76                "found": false,
77                "platform": std::env::consts::OS,
78                "hint": "Install Chrome, Edge, Brave, or Vivaldi, or pass `executable_path` to `start`. Firefox and Safari are not supported.",
79            });
80            ToolResult {
81                output: serde_json::to_string_pretty(&output).unwrap_or_default(),
82                success: true,
83                metadata: Default::default(),
84            }
85        }
86    }
87}