use crate::error::Result;
use crate::tools::{Tool, ToolContext, ToolResult};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct TabInfo {
pub index: usize,
pub active: bool,
pub title: String,
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct TabListParams {}
#[derive(Default)]
pub struct TabListTool;
impl Tool for TabListTool {
type Params = TabListParams;
fn name(&self) -> &str {
"tab_list"
}
fn execute_typed(
&self,
_params: TabListParams,
context: &mut ToolContext,
) -> Result<ToolResult> {
let tabs = context.session.get_tabs()?;
let active_tab = context.session.tab()?;
let mut tab_list = Vec::new();
for (index, tab) in tabs.iter().enumerate() {
let is_active = std::sync::Arc::ptr_eq(tab, &active_tab);
let title = tab.get_title().unwrap_or_default();
let url = tab.get_url();
tab_list.push(TabInfo {
index,
active: is_active,
title,
url,
});
}
let active_index = tab_list.iter().position(|t| t.active).unwrap_or(0);
let active_info = &tab_list[active_index];
let summary = if !tab_list.is_empty() {
let all_tabs_str = tab_list
.iter()
.map(|tab| format!("[{}] Title: {} (URL: {})", tab.index, tab.title, tab.url))
.collect::<Vec<_>>()
.join("\n");
format!(
"Current Tab: [{}] {}\nAll Tabs:\n{}",
active_index, active_info.title, all_tabs_str
)
} else {
"No tabs available".to_string()
};
Ok(ToolResult::success_with(serde_json::json!({
"tab_list": tab_list,
"count": tab_list.len(),
"summary": summary
})))
}
}