Skip to main content

limit_cli/tools/browser/handlers/
interaction.rs

1use super::super::args::ArgsExt;
2use super::super::client::BrowserClient;
3use super::super::client_ext::{InteractionExt, QueryExt};
4use super::super::response::ok_msg;
5use limit_agent::error::AgentError;
6use serde_json::Value;
7
8pub async fn click(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
9    let selector = args.get_str("selector", "click")?;
10    client.click(selector).await?;
11    Ok(ok_msg(format!("Clicked element: {}", selector)))
12}
13
14pub async fn fill(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
15    let selector = args.get_str("selector", "fill")?;
16    let text = args.get_str("text", "fill")?;
17    client.fill(selector, text).await?;
18    Ok(ok_msg(format!("Filled element {} with text", selector)))
19}
20
21pub async fn type_(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
22    let selector = args.get_str("selector", "type")?;
23    let text = args.get_str("text", "type")?;
24    client.type_text(selector, text).await?;
25    Ok(ok_msg(format!("Typed text into element: {}", selector)))
26}
27
28pub async fn press(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
29    let key = args.get_str("key", "press")?;
30    client.press(key).await?;
31    Ok(ok_msg(format!("Pressed key: {}", key)))
32}
33
34pub async fn hover(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
35    let selector = args.get_str("selector", "hover")?;
36    client.hover(selector).await?;
37    Ok(ok_msg(format!("Hovered over element: {}", selector)))
38}
39
40pub async fn select(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
41    let selector = args.get_str("selector", "select")?;
42    let value = args.get_str("value", "select")?;
43    client.select_option(selector, value).await?;
44    Ok(ok_msg(format!(
45        "Selected option '{}' in element: {}",
46        value, selector
47    )))
48}
49
50pub async fn dblclick(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
51    let selector = args.get_str("selector", "dblclick")?;
52    client.dblclick(selector).await?;
53    Ok(ok_msg(format!("Double-clicked element: {}", selector)))
54}
55
56pub async fn focus(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
57    let selector = args.get_str("selector", "focus")?;
58    client.focus(selector).await?;
59    Ok(ok_msg(format!("Focused element: {}", selector)))
60}
61
62pub async fn check(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
63    let selector = args.get_str("selector", "check")?;
64    client.check(selector).await?;
65    Ok(ok_msg(format!("Checked element: {}", selector)))
66}
67
68pub async fn uncheck(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
69    let selector = args.get_str("selector", "uncheck")?;
70    client.uncheck(selector).await?;
71    Ok(ok_msg(format!("Unchecked element: {}", selector)))
72}
73
74pub async fn scrollintoview(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
75    let selector = args.get_str("selector", "scrollintoview")?;
76    client.scrollintoview(selector).await?;
77    Ok(ok_msg(format!("Scrolled element into view: {}", selector)))
78}
79
80pub async fn drag(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
81    let source = args.get_str("source", "drag")?;
82    let target = args.get_str("target", "drag")?;
83    client.drag(source, target).await?;
84    Ok(ok_msg(format!("Dragged from {} to {}", source, target)))
85}
86
87pub async fn upload(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
88    let selector = args.get_str("selector", "upload")?;
89    let files = args
90        .get("files")
91        .and_then(|v| v.as_array())
92        .ok_or_else(|| {
93            AgentError::ToolError("Missing 'files' argument for upload action".to_string())
94        })?;
95
96    let file_paths: Vec<&str> = files.iter().filter_map(|f| f.as_str()).collect();
97
98    if file_paths.is_empty() {
99        return Err(AgentError::ToolError(
100            "At least one file path required".to_string(),
101        ));
102    }
103
104    client.upload(selector, &file_paths).await?;
105    Ok(ok_msg(format!(
106        "Uploaded {} file(s) to {}",
107        file_paths.len(),
108        selector
109    )))
110}
111
112pub async fn pdf(client: &BrowserClient, args: &Value) -> Result<Value, AgentError> {
113    let path = args.get_str("path", "pdf")?;
114    client.pdf(path).await?;
115    Ok(ok_msg(format!("Saved page as PDF: {}", path)))
116}