browser_use/tools/
read_links.rs1use crate::error::{BrowserError, Result};
2use crate::tools::{Tool, ToolContext, ToolResult};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
7pub struct ReadLinksParams {}
8
9#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
10pub struct Link {
11 pub text: String,
13 pub href: String,
15}
16
17#[derive(Default)]
18pub struct ReadLinksTool;
19
20impl Tool for ReadLinksTool {
21 type Params = ReadLinksParams;
22
23 fn name(&self) -> &str {
24 "read_links"
25 }
26
27 fn execute_typed(
28 &self,
29 _params: ReadLinksParams,
30 context: &mut ToolContext,
31 ) -> Result<ToolResult> {
32 let js_code = r#"
35 JSON.stringify(
36 Array.from(document.querySelectorAll('a[href]'))
37 .map(el => ({
38 text: el.innerText || '',
39 href: el.getAttribute('href') || ''
40 }))
41 .filter(link => link.href !== '')
42 )
43 "#;
44
45 let result = context
46 .session
47 .tab()?
48 .evaluate(js_code, false)
49 .map_err(|e| BrowserError::EvaluationFailed(e.to_string()))?;
50
51 let links: Vec<Link> = result
53 .value
54 .and_then(|v| v.as_str().map(String::from))
55 .and_then(|s| serde_json::from_str(&s).ok())
56 .unwrap_or_default();
57
58 Ok(ToolResult::success_with(serde_json::json!({
59 "links": links,
60 "count": links.len()
61 })))
62 }
63}