browsr_types/
commands.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
5pub struct CommandPoint {
6    pub x: f64,
7    pub y: f64,
8}
9
10#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
11#[serde(rename_all = "snake_case")]
12pub enum CommandType {
13    Action,
14    Extraction,
15}
16
17#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
18#[serde(rename_all = "snake_case")]
19pub enum PageContentKind {
20    Markdown,
21    Html,
22    Json,
23}
24
25impl Default for PageContentKind {
26    fn default() -> Self {
27        PageContentKind::Markdown
28    }
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
32#[serde(tag = "command", rename_all = "snake_case", content = "data")]
33pub enum Commands {
34    ToggleClickOverlay {
35        enabled: bool,
36    },
37    ToggleBoundingBoxes {
38        enabled: bool,
39        selector: Option<String>,
40        limit: Option<usize>,
41        include_html: Option<bool>,
42    },
43    // Navigation commands
44    NavigateTo {
45        url: String,
46    },
47    Refresh,
48    WaitForNavigation {
49        timeout_ms: Option<u64>,
50    },
51    WaitForElement {
52        selector: String,
53        timeout_ms: Option<u64>,
54        visible_only: Option<bool>,
55    },
56
57    // Element interaction commands
58    Click {
59        selector: String,
60    },
61    ClickAt {
62        x: f64,
63        y: f64,
64    },
65    TypeText {
66        selector: String,
67        text: String,
68    },
69    Clear {
70        selector: String,
71    },
72    PressKey {
73        selector: String,
74        key: String,
75    },
76
77    // Content extraction
78    GetContent {
79        #[serde(default, skip_serializing_if = "Option::is_none")]
80        selector: Option<String>,
81        #[serde(default)]
82        kind: Option<PageContentKind>,
83    },
84    GetText {
85        selector: String,
86    },
87    GetAttribute {
88        selector: String,
89        attribute: String,
90    },
91
92    // Page information
93    GetTitle,
94    ExtractStructuredContent {
95        query: String,
96        #[serde(default, skip_serializing_if = "Option::is_none")]
97        schema: Option<String>,
98        #[serde(default, skip_serializing_if = "Option::is_none")]
99        max_chars: Option<usize>,
100    },
101
102    // JavaScript execution
103    Evaluate {
104        expression: String,
105    },
106    GetBoundingBoxes {
107        selector: String,
108        limit: Option<usize>,
109        include_html: Option<bool>,
110    },
111    InspectElement {
112        selector: String,
113    },
114
115    // Mouse and keyboard
116    ScrollTo {
117        x: f64,
118        y: f64,
119    },
120    Drag {
121        from: CommandPoint,
122        to: CommandPoint,
123        modifiers: Option<i64>,
124    },
125    ScrollIntoView {
126        selector: String,
127    },
128
129    // Screenshot and capture
130    Screenshot {
131        full_page: Option<bool>,
132        path: Option<String>,
133    },
134
135    // Element-focused interactions
136    ClickAdvanced {
137        selector: String,
138        button: Option<String>,
139        click_count: Option<u8>,
140        modifiers: Option<i64>,
141    },
142    Fill {
143        selector: String,
144        text: String,
145        clear: Option<bool>,
146    },
147    Hover {
148        selector: String,
149    },
150    Focus {
151        selector: String,
152    },
153    Check {
154        selector: String,
155    },
156    SelectOption {
157        selector: String,
158        values: Vec<String>,
159    },
160    DragTo {
161        selector: String,
162        target_selector: Option<String>,
163        source_position: Option<CommandPoint>,
164        target_position: Option<CommandPoint>,
165        modifiers: Option<i64>,
166    },
167    EvaluateOnElement {
168        selector: String,
169        expression: String,
170    },
171    GetElementBoundingBox {
172        selector: String,
173    },
174    ElementScreenshot {
175        selector: String,
176        format: Option<String>,
177        quality: Option<u8>,
178    },
179    GetBasicInfo {
180        selector: String,
181    },
182}
183
184#[derive(serde::Deserialize)]
185pub struct StepPayload {
186    pub commands: Vec<Commands>,
187    pub thinking: Option<String>,
188    pub evaluation_previous_goal: Option<String>,
189    pub memory: Option<String>,
190    pub next_goal: Option<String>,
191}
192
193impl Commands {
194    pub fn command_type(&self) -> CommandType {
195        match self {
196            Commands::GetContent { .. }
197            | Commands::GetText { .. }
198            | Commands::GetAttribute { .. }
199            | Commands::GetTitle
200            | Commands::ExtractStructuredContent { .. }
201            | Commands::Screenshot { .. }
202            | Commands::ElementScreenshot { .. }
203            | Commands::GetElementBoundingBox { .. }
204            | Commands::Evaluate { .. }
205            | Commands::EvaluateOnElement { .. }
206            | Commands::GetBoundingBoxes { .. }
207            | Commands::InspectElement { .. }
208            | Commands::GetBasicInfo { .. } => CommandType::Extraction,
209            _ => CommandType::Action,
210        }
211    }
212}