Skip to main content

browsr_types/
agent.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4/// Supported proxy options for the embedded Chromium browser
5#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
6#[serde(tag = "kind", rename_all = "snake_case")]
7pub enum BrowserProxy {
8    /// Route traffic through an HTTPS proxy at the provided host:port
9    Https { address: String },
10    /// Route traffic through a SOCKS5 proxy at the provided host:port
11    Socks5 { address: String },
12    /// Route traffic through an HTTP proxy with username/password authentication
13    HttpAuth {
14        address: String,
15        username: String,
16        password: String,
17    },
18}
19
20/// Chromium driver configuration shared across orchestrator + CLI
21#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
22#[serde(default, deny_unknown_fields)]
23pub struct BrowsrClientConfig {
24    /// Preferred viewport size (defaults to 1920x1080)
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub window_size: Option<(u32, u32)>,
27    /// Whether to run Chromium in headless mode
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub headless: Option<bool>,
30    /// Enable stealth adjustments to reduce detection heuristics
31    pub enable_stealth_mode: bool,
32    /// Enable Spider's "real" emulation for fonts, media, etc.
33    pub enable_real_emulation: bool,
34    /// Optional proxy information passed to Chromium
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub proxy: Option<BrowserProxy>,
37    /// Model settings for structured extraction (loaded from browsr.toml) - stored as JSON to avoid circular dependencies
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub analysis_model_settings: Option<serde_json::Value>,
40    /// Custom user agent string (defaults to modern Chrome on macOS)
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub user_agent: Option<String>,
43    /// Generate a random modern Chrome user agent on session start (overrides user_agent if set)
44    #[serde(default)]
45    pub use_random_user_agent: bool,
46    /// Disable automation detection features (webdriver flag, etc.)
47    #[serde(default = "default_true")]
48    pub disable_automation_detection: bool,
49}
50
51fn default_true() -> bool {
52    true
53}
54
55impl Default for BrowsrClientConfig {
56    fn default() -> Self {
57        Self {
58            window_size: None,
59            headless: Some(true),
60            enable_stealth_mode: true,
61            enable_real_emulation: true,
62            proxy: None,
63            analysis_model_settings: None,
64            user_agent: None,
65            use_random_user_agent: false,
66            disable_automation_detection: true,
67        }
68    }
69}
70
71/// Serializable cookie representation used for session persistence
72#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
73#[serde(deny_unknown_fields)]
74pub struct BrowserCookie {
75    pub name: String,
76    pub value: String,
77    #[serde(default, skip_serializing_if = "Option::is_none")]
78    pub domain: Option<String>,
79    #[serde(default, skip_serializing_if = "Option::is_none")]
80    pub path: Option<String>,
81    #[serde(default, skip_serializing_if = "Option::is_none")]
82    pub expires: Option<f64>,
83    #[serde(default)]
84    pub http_only: bool,
85    #[serde(default)]
86    pub secure: bool,
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub same_site: Option<String>,
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub priority: Option<String>,
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub source_scheme: Option<String>,
93}
94
95/// Captured browser state (cookies + last URL)
96#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
97pub struct BrowserSessionState {
98    pub cookies: Vec<BrowserCookie>,
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub last_url: Option<String>,
101    #[schemars(with = "String")]
102    pub captured_at: chrono::DateTime<chrono::Utc>,
103}
104
105/// Persisted browser session entry keyed by user id
106#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
107pub struct BrowserSessionRecord {
108    pub user_id: String,
109    pub state: BrowserSessionState,
110    #[schemars(with = "String")]
111    pub updated_at: chrono::DateTime<chrono::Utc>,
112}