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(&self, params: SwitchTabParams, context: &mut ToolContext) -> Result<ToolResult> {
25        // Get all tabs to validate index
26        let tabs = context.session.get_tabs()?;
27        
28        if params.index >= tabs.len() {
29            return Ok(ToolResult::failure(format!(
30                "Invalid tab index: {}. Valid range: 0-{}",
31                params.index,
32                tabs.len() - 1
33            )));
34        }
35
36        // Note: We can't directly call session.switch_tab() because we only have &BrowserSession
37        // Instead, we'll need to work with the browser directly
38        // However, since this requires mutable access to the session, we need to handle this differently
39        
40        // Get the tab at the specified index
41        let target_tab = tabs[params.index].clone();
42        
43        // Activate the tab
44        target_tab.activate().map_err(|e| {
45            crate::error::BrowserError::TabOperationFailed(format!(
46                "Failed to activate tab {}: {}",
47                params.index, e
48            ))
49        })?;
50
51        // Get updated tab info
52        let title = target_tab.get_title().unwrap_or_default();
53        let url = target_tab.get_url();
54
55        // Build tab list summary
56        let mut tab_list_str = String::new();
57        for (idx, tab) in tabs.iter().enumerate() {
58            let tab_title = tab.get_title().unwrap_or_default();
59            let tab_url = tab.get_url();
60            tab_list_str.push_str(&format!("[{}] {} ({})\n", idx, tab_title, tab_url));
61        }
62
63        let summary = format!(
64            "Switched to tab {}\nAll Tabs:\n{}",
65            params.index, tab_list_str
66        );
67
68        Ok(ToolResult::success_with(serde_json::json!({
69            "index": params.index,
70            "title": title,
71            "url": url,
72            "message": summary
73        })))
74    }
75}