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", content = "address", rename_all = "snake_case")]
7pub enum BrowserProxy {
8    /// Route traffic through an HTTPS proxy at the provided host:port
9    Https(String),
10    /// Route traffic through a SOCKS5 proxy at the provided host:port
11    Socks5(String),
12}
13
14/// Chromium driver configuration shared across orchestrator + CLI
15#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
16#[serde(default, deny_unknown_fields)]
17pub struct BrowsrClientConfig {
18    /// Preferred viewport size (defaults to 1920x1080)
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub window_size: Option<(u32, u32)>,
21    /// Whether to run Chromium in headless mode
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub headless: Option<bool>,
24    /// Enable stealth adjustments to reduce detection heuristics
25    pub enable_stealth_mode: bool,
26    /// Enable Spider's "real" emulation for fonts, media, etc.
27    pub enable_real_emulation: bool,
28    /// Optional proxy information passed to Chromium
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub proxy: Option<BrowserProxy>,
31    /// Model settings for structured extraction (loaded from browsr.toml) - stored as JSON to avoid circular dependencies
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub analysis_model_settings: Option<serde_json::Value>,
34}
35
36impl Default for BrowsrClientConfig {
37    fn default() -> Self {
38        Self {
39            window_size: None,
40            headless: Some(true),
41            enable_stealth_mode: true,
42            enable_real_emulation: true,
43            proxy: None,
44            analysis_model_settings: None,
45        }
46    }
47}
48
49/// Serializable cookie representation used for session persistence
50#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
51#[serde(deny_unknown_fields)]
52pub struct BrowserCookie {
53    pub name: String,
54    pub value: String,
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub domain: Option<String>,
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub path: Option<String>,
59    #[serde(default, skip_serializing_if = "Option::is_none")]
60    pub expires: Option<f64>,
61    #[serde(default)]
62    pub http_only: bool,
63    #[serde(default)]
64    pub secure: bool,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub same_site: Option<String>,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub priority: Option<String>,
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub source_scheme: Option<String>,
71}
72
73/// Captured browser state (cookies + last URL)
74#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
75pub struct BrowserSessionState {
76    pub cookies: Vec<BrowserCookie>,
77    #[serde(default, skip_serializing_if = "Option::is_none")]
78    pub last_url: Option<String>,
79    #[schemars(with = "String")]
80    pub captured_at: chrono::DateTime<chrono::Utc>,
81}
82
83/// Persisted browser session entry keyed by user id
84#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
85pub struct BrowserSessionRecord {
86    pub user_id: String,
87    pub state: BrowserSessionState,
88    #[schemars(with = "String")]
89    pub updated_at: chrono::DateTime<chrono::Utc>,
90}