Skip to main content

beam_core/
config.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::{Map, Value};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub struct DaemonConfig {
8    #[serde(default)]
9    pub quiet_restart: bool,
10    #[serde(default = "default_working_dirs")]
11    pub working_dirs: Vec<String>,
12}
13
14fn default_working_dirs() -> Vec<String> {
15    vec!["~".to_string()]
16}
17
18impl Default for DaemonConfig {
19    fn default() -> Self {
20        Self {
21            quiet_restart: false,
22            working_dirs: default_working_dirs(),
23        }
24    }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
28pub struct WebConfig {
29    #[serde(default = "default_web_host")]
30    pub host: String,
31    #[serde(default = "default_proxy_base_port")]
32    pub proxy_base_port: u16,
33}
34
35fn default_web_host() -> String {
36    "0.0.0.0".to_string()
37}
38
39fn default_proxy_base_port() -> u16 {
40    8800
41}
42
43impl Default for WebConfig {
44    fn default() -> Self {
45        Self {
46            host: default_web_host(),
47            proxy_base_port: default_proxy_base_port(),
48        }
49    }
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
53pub struct Config {
54    #[serde(default)]
55    pub daemon: DaemonConfig,
56    #[serde(default)]
57    pub web: WebConfig,
58    #[serde(default)]
59    pub lark: LarkConfig,
60    #[serde(default, rename = "screenAnalyzer")]
61    pub screen_analyzer: ScreenAnalyzerConfig,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
65pub struct BotConfig {
66    #[serde(default)]
67    pub name: Option<String>,
68    #[serde(rename = "larkAppId")]
69    pub lark_app_id: String,
70    #[serde(rename = "larkAppSecret")]
71    pub lark_app_secret: String,
72    #[serde(rename = "cliId")]
73    pub cli_id: String,
74    #[serde(rename = "cliBin", default)]
75    pub cli_bin: Option<String>,
76    #[serde(default)]
77    pub model: Option<String>,
78    #[serde(rename = "workingDir", default)]
79    pub working_dir: Option<String>,
80    #[serde(rename = "larkEncryptKey", default)]
81    pub lark_encrypt_key: Option<String>,
82    #[serde(rename = "larkVerificationToken", default)]
83    pub lark_verification_token: Option<String>,
84    #[serde(rename = "allowedUsers", default)]
85    pub allowed_users: Vec<String>,
86    #[serde(rename = "privateCard", default)]
87    pub private_card: bool,
88    #[serde(rename = "allowedChatGroups", default)]
89    pub allowed_chat_groups: Vec<String>,
90    #[serde(rename = "chatGrants", default)]
91    pub chat_grants: std::collections::HashMap<String, Vec<String>>,
92    #[serde(rename = "globalGrants", default)]
93    pub global_grants: Vec<String>,
94    #[serde(rename = "oncallChats", default)]
95    pub oncall_chats: Vec<OncallChatBinding>,
96    #[serde(rename = "restrictGrantCommands", default)]
97    pub restrict_grant_commands: bool,
98    #[serde(rename = "messageQuota", default)]
99    pub message_quota: Option<MessageQuotaConfig>,
100    #[serde(rename = "quotaState", default)]
101    pub quota_state: std::collections::HashMap<String, QuotaEntry>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
105pub struct OncallChatBinding {
106    #[serde(rename = "chatId")]
107    pub chat_id: String,
108    #[serde(rename = "workingDir", default)]
109    pub working_dir: Option<String>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
113pub struct MessageQuotaConfig {
114    #[serde(rename = "defaultLimit", default)]
115    pub default_limit: Option<u32>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
119pub struct QuotaEntry {
120    pub limit: u32,
121    pub used: u32,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
125pub struct LarkConfig {
126    #[serde(default = "default_lark_event_mode")]
127    pub event_mode: String,
128    #[serde(default)]
129    pub verification_token: Option<String>,
130    #[serde(default)]
131    pub encrypt_key: Option<String>,
132}
133
134#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
135pub struct ScreenAnalyzerConfig {
136    #[serde(default)]
137    pub enabled: bool,
138    #[serde(default)]
139    pub base_url: String,
140    #[serde(default)]
141    pub api_key: String,
142    #[serde(default)]
143    pub model: String,
144    #[serde(default = "default_screen_analyzer_interval_ms")]
145    pub interval_ms: u64,
146    #[serde(default = "default_screen_analyzer_stable_count")]
147    pub stable_count: u32,
148    #[serde(default = "default_screen_analyzer_snapshot_max_chars")]
149    pub snapshot_max_chars: usize,
150    #[serde(default)]
151    pub extra_headers: HashMap<String, String>,
152    #[serde(default)]
153    pub extra_body: Map<String, Value>,
154}
155
156fn default_screen_analyzer_interval_ms() -> u64 {
157    2_000
158}
159
160fn default_screen_analyzer_stable_count() -> u32 {
161    6
162}
163
164fn default_screen_analyzer_snapshot_max_chars() -> usize {
165    8_000
166}
167
168impl Default for ScreenAnalyzerConfig {
169    fn default() -> Self {
170        Self {
171            enabled: false,
172            base_url: String::new(),
173            api_key: String::new(),
174            model: String::new(),
175            interval_ms: default_screen_analyzer_interval_ms(),
176            stable_count: default_screen_analyzer_stable_count(),
177            snapshot_max_chars: default_screen_analyzer_snapshot_max_chars(),
178            extra_headers: HashMap::new(),
179            extra_body: Map::new(),
180        }
181    }
182}
183
184fn default_lark_event_mode() -> String {
185    "http".to_string()
186}
187
188impl Default for LarkConfig {
189    fn default() -> Self {
190        Self {
191            event_mode: default_lark_event_mode(),
192            verification_token: None,
193            encrypt_key: None,
194        }
195    }
196}