browsr_types/
agent.rs

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