Skip to main content

browsr_types/
browser_step.rs

1//! Browser step types for the /browser_step API.
2//!
3//! These types are shared between browsr-client and browsr server.
4
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8use crate::Commands;
9
10/// Input for browser_step execution (tool parameters).
11#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
12pub struct BrowserStepInput {
13    /// Browser commands to execute
14    pub commands: Vec<Commands>,
15    /// Whether to run browser in headless mode
16    #[serde(default)]
17    pub headless: Option<bool>,
18    /// Thinking/reasoning about current step
19    #[serde(default)]
20    pub thinking: Option<String>,
21    /// Evaluation of how well the previous goal was achieved
22    #[serde(default)]
23    pub evaluation_previous_goal: Option<String>,
24    /// Memory/context to persist across steps
25    #[serde(default)]
26    pub memory: Option<String>,
27    /// Next goal to achieve
28    #[serde(default)]
29    pub next_goal: Option<String>,
30}
31
32impl BrowserStepInput {
33    /// Create a new BrowserStepInput with commands only.
34    pub fn new(commands: Vec<Commands>) -> Self {
35        Self {
36            commands,
37            headless: None,
38            thinking: None,
39            evaluation_previous_goal: None,
40            memory: None,
41            next_goal: None,
42        }
43    }
44
45    /// Set headless mode.
46    pub fn with_headless(mut self, headless: bool) -> Self {
47        self.headless = Some(headless);
48        self
49    }
50}
51
52/// Request payload for the /browser_step API.
53#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
54pub struct BrowserStepRequest {
55    /// Browser session ID (managed by server)
56    #[serde(default)]
57    pub session_id: String,
58    /// Distri thread ID (used for sequence persistence)
59    #[serde(default)]
60    pub thread_id: String,
61    /// Distri task ID (optional)
62    #[serde(default)]
63    pub task_id: Option<String>,
64    /// Distri run ID (optional)
65    #[serde(default)]
66    pub run_id: Option<String>,
67    /// Tool call ID (optional)
68    #[serde(default)]
69    pub tool_call_id: Option<String>,
70    /// Browser commands to execute
71    pub commands: Vec<Commands>,
72    /// Whether to run browser in headless mode
73    #[serde(default)]
74    pub headless: Option<bool>,
75    /// Thinking/reasoning about current step
76    #[serde(default)]
77    pub thinking: Option<String>,
78    /// Evaluation of how well the previous goal was achieved
79    #[serde(default)]
80    pub evaluation_previous_goal: Option<String>,
81    /// Memory/context to persist across steps
82    #[serde(default)]
83    pub memory: Option<String>,
84    /// Next goal to achieve
85    #[serde(default)]
86    pub next_goal: Option<String>,
87}
88
89impl BrowserStepRequest {
90    /// Create a new request from input with context.
91    pub fn new(input: BrowserStepInput) -> Self {
92        Self {
93            session_id: String::new(),
94            thread_id: String::new(),
95            task_id: None,
96            run_id: None,
97            tool_call_id: None,
98            commands: input.commands,
99            headless: input.headless,
100            thinking: input.thinking,
101            evaluation_previous_goal: input.evaluation_previous_goal,
102            memory: input.memory,
103            next_goal: input.next_goal,
104        }
105    }
106
107    /// Set session ID.
108    pub fn with_session_id(mut self, session_id: impl Into<String>) -> Self {
109        self.session_id = session_id.into();
110        self
111    }
112
113    /// Set thread ID.
114    pub fn with_thread_id(mut self, thread_id: impl Into<String>) -> Self {
115        self.thread_id = thread_id.into();
116        self
117    }
118
119    /// Set task ID.
120    pub fn with_task_id(mut self, task_id: impl Into<String>) -> Self {
121        self.task_id = Some(task_id.into());
122        self
123    }
124
125    /// Set run ID.
126    pub fn with_run_id(mut self, run_id: impl Into<String>) -> Self {
127        self.run_id = Some(run_id.into());
128        self
129    }
130
131    /// Set tool call ID.
132    pub fn with_tool_call_id(mut self, tool_call_id: impl Into<String>) -> Self {
133        self.tool_call_id = Some(tool_call_id.into());
134        self
135    }
136}
137
138/// Result of browser_step execution.
139#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
140pub struct BrowserStepResult {
141    /// Whether all commands succeeded
142    pub success: bool,
143    /// Browser session ID
144    pub session_id: String,
145    /// Summary of execution
146    pub summary: Option<String>,
147    /// Current URL after execution
148    pub url: Option<String>,
149    /// Error message if any command failed
150    pub error: Option<String>,
151    /// Sequence ID for persistence
152    pub sequence_id: Option<String>,
153    /// Extracted data from commands (e.g., ExtractStructuredContent)
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub data: Option<serde_json::Value>,
156}
157
158impl BrowserStepResult {
159    /// Create a successful result.
160    pub fn success(session_id: impl Into<String>) -> Self {
161        Self {
162            success: true,
163            session_id: session_id.into(),
164            summary: None,
165            url: None,
166            error: None,
167            sequence_id: None,
168            data: None,
169        }
170    }
171
172    /// Create an error result.
173    pub fn error(session_id: impl Into<String>, error: impl Into<String>) -> Self {
174        Self {
175            success: false,
176            session_id: session_id.into(),
177            summary: None,
178            url: None,
179            error: Some(error.into()),
180            sequence_id: None,
181            data: None,
182        }
183    }
184}