browser_agent/
interpreter.rs

1use anyhow::{anyhow, Context, Result};
2use chromiumoxide::Element;
3
4/// Translates the given elements into a format GPT-4 can understand.
5///
6/// # Arguments
7///
8/// * `elements` - The elements to translate.
9/// * `should_include_p` - Whether to include paragraphs in the translation.
10///
11/// # Errors
12///
13/// * If the elements cannot be translated.
14pub async fn translate(elements: &[Element], should_include_p: bool) -> Result<String> {
15    let mut summary = Vec::new();
16
17    for (i, element) in elements.iter().enumerate() {
18        let inner_text = element.inner_text().await?;
19
20        match element
21            .property("tagName")
22            .await
23            .context("Failed to get tag name")?
24            .ok_or_else(|| anyhow!("Failed to get tag name"))?
25            .as_str()
26            .context("Failed to get tag name")?
27        {
28            "BUTTON" => {
29                let Some(inner_text) = inner_text else {
30                    continue
31                };
32
33                summary.push(format!("<button id={i}>{inner_text}</button>"));
34            }
35            "P" => {
36                if !should_include_p {
37                    continue;
38                }
39
40                let Some(inner_text) = inner_text else {
41                    continue
42                };
43
44                summary.push(format!("<p id={i}>{inner_text}</p>"));
45            }
46            "IMG" => {
47                let Some(alt_text) = element.attribute("alt").await? else {
48                    continue
49                };
50
51                summary.push(format!("<img id={i} alt=\"{alt_text}\"/>"));
52            }
53            "A" => {
54                let Some(inner_text) = inner_text else {
55                    continue
56                };
57
58                let Some(href) = element.attribute("href").await? else {
59                    continue
60                };
61
62                summary.push(format!("<link id={i} href={href}>{inner_text}<link>",));
63            }
64            "INPUT" => {
65                let Some(placeholder) = element.attribute("placeholder").await? else {
66                    continue
67                };
68
69                summary.push(format!("<input id={i}>{placeholder}</input>"));
70            }
71            _ => {}
72        }
73    }
74
75    Ok(summary.join("\n"))
76}