adk_browser/tools/
frames.rs1use crate::session::BrowserSession;
4use adk_core::{AdkError, Result, Tool, ToolContext};
5use async_trait::async_trait;
6use serde_json::{json, Value};
7use std::sync::Arc;
8
9pub struct SwitchToFrameTool {
11 browser: Arc<BrowserSession>,
12}
13
14impl SwitchToFrameTool {
15 pub fn new(browser: Arc<BrowserSession>) -> Self {
16 Self { browser }
17 }
18}
19
20#[async_trait]
21impl Tool for SwitchToFrameTool {
22 fn name(&self) -> &str {
23 "browser_switch_to_frame"
24 }
25
26 fn description(&self) -> &str {
27 "Switch to an iframe by index number or CSS selector."
28 }
29
30 fn parameters_schema(&self) -> Option<Value> {
31 Some(json!({
32 "type": "object",
33 "properties": {
34 "index": {
35 "type": "integer",
36 "description": "Frame index (0-based)"
37 },
38 "selector": {
39 "type": "string",
40 "description": "CSS selector for the iframe element"
41 }
42 }
43 }))
44 }
45
46 async fn execute(&self, _ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
47 let index = args.get("index").and_then(|v| v.as_u64());
48 let selector = args.get("selector").and_then(|v| v.as_str());
49
50 if let Some(idx) = index {
51 self.browser.switch_to_frame_by_index(idx as u16).await?;
52 Ok(json!({
53 "success": true,
54 "switched_to_frame": idx
55 }))
56 } else if let Some(sel) = selector {
57 self.browser.switch_to_frame_by_selector(sel).await?;
58 Ok(json!({
59 "success": true,
60 "switched_to_frame": sel
61 }))
62 } else {
63 Err(AdkError::Tool("Must provide either 'index' or 'selector'".to_string()))
64 }
65 }
66}
67
68pub struct SwitchToParentFrameTool {
70 browser: Arc<BrowserSession>,
71}
72
73impl SwitchToParentFrameTool {
74 pub fn new(browser: Arc<BrowserSession>) -> Self {
75 Self { browser }
76 }
77}
78
79#[async_trait]
80impl Tool for SwitchToParentFrameTool {
81 fn name(&self) -> &str {
82 "browser_switch_to_parent_frame"
83 }
84
85 fn description(&self) -> &str {
86 "Switch to the parent frame (exit current iframe)."
87 }
88
89 fn parameters_schema(&self) -> Option<Value> {
90 Some(json!({
91 "type": "object",
92 "properties": {}
93 }))
94 }
95
96 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
97 self.browser.switch_to_parent_frame().await?;
98
99 Ok(json!({
100 "success": true,
101 "message": "Switched to parent frame"
102 }))
103 }
104}
105
106pub struct SwitchToDefaultContentTool {
108 browser: Arc<BrowserSession>,
109}
110
111impl SwitchToDefaultContentTool {
112 pub fn new(browser: Arc<BrowserSession>) -> Self {
113 Self { browser }
114 }
115}
116
117#[async_trait]
118impl Tool for SwitchToDefaultContentTool {
119 fn name(&self) -> &str {
120 "browser_switch_to_default_content"
121 }
122
123 fn description(&self) -> &str {
124 "Switch back to the main page content (exit all iframes)."
125 }
126
127 fn parameters_schema(&self) -> Option<Value> {
128 Some(json!({
129 "type": "object",
130 "properties": {}
131 }))
132 }
133
134 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
135 self.browser.switch_to_default_content().await?;
136
137 Ok(json!({
138 "success": true,
139 "message": "Switched to default content"
140 }))
141 }
142}