1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
6#[serde(default, deny_unknown_fields)]
7pub struct BrowserAgentConfig {
8 pub enabled: bool,
10 pub persist_session: bool,
12 #[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#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43#[serde(tag = "kind", content = "address", rename_all = "snake_case")]
44pub enum BrowserProxy {
45 Https(String),
47 Socks5(String),
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
53#[serde(default, deny_unknown_fields)]
54pub struct DistriBrowserConfig {
55 #[serde(skip_serializing_if = "Option::is_none")]
57 pub window_size: Option<(u32, u32)>,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub headless: Option<bool>,
61 pub enable_stealth_mode: bool,
63 pub enable_real_emulation: bool,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub proxy: Option<BrowserProxy>,
68 #[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#[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#[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#[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}