codetether_agent/tool/browserctl/
mod.rs1mod 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}