browser_use/tools/
switch_tab.rs

1use crate::error::Result;
2use crate::tools::{Tool, ToolContext, ToolResult};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// Parameters for the switch_tab tool
7#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
8pub struct SwitchTabParams {
9    /// Tab index to switch to
10    pub index: usize,
11}
12
13/// Tool for switching to a specific tab
14#[derive(Default)]
15pub struct SwitchTabTool;
16
17impl Tool for SwitchTabTool {
18    type Params = SwitchTabParams;
19
20    fn name(&self) -> &str {
21        "switch_tab"
22    }
23
24    fn execute_typed(
25        &self,
26        params: SwitchTabParams,
27        context: &mut ToolContext,
28    ) -> Result<ToolResult> {
29        // Get all tabs to validate index
30        let tabs = context.session.get_tabs()?;
31
32        if params.index >= tabs.len() {
33            return Ok(ToolResult::failure(format!(
34                "Invalid tab index: {}. Valid range: 0-{}",
35                params.index,
36                tabs.len() - 1
37            )));
38        }
39
40        // Note: We can't directly call session.switch_tab() because we only have &BrowserSession
41        // Instead, we'll need to work with the browser directly
42        // However, since this requires mutable access to the session, we need to handle this differently
43
44        // Get the tab at the specified index
45        let target_tab = tabs[params.index].clone();
46
47        // Activate the tab
48        target_tab.activate().map_err(|e| {
49            crate::error::BrowserError::TabOperationFailed(format!(
50                "Failed to activate tab {}: {}",
51                params.index, e
52            ))
53        })?;
54
55        // Get updated tab info
56        let title = target_tab.get_title().unwrap_or_default();
57        let url = target_tab.get_url();
58
59        // Build tab list summary
60        let mut tab_list_str = String::new();
61        for (idx, tab) in tabs.iter().enumerate() {
62            let tab_title = tab.get_title().unwrap_or_default();
63            let tab_url = tab.get_url();
64            tab_list_str.push_str(&format!("[{}] {} ({})\n", idx, tab_title, tab_url));
65        }
66
67        let summary = format!(
68            "Switched to tab {}\nAll Tabs:\n{}",
69            params.index, tab_list_str
70        );
71
72        Ok(ToolResult::success_with(serde_json::json!({
73            "index": params.index,
74            "title": title,
75            "url": url,
76            "message": summary
77        })))
78    }
79}