1#[derive(Debug, Clone, Serialize, Deserialize)]
2pub struct ContextConfig {
3 #[serde(default = "default_max_context_tokens")]
4 pub max_tokens: usize,
5 #[serde(default = "default_soft_trim_ratio")]
6 pub soft_trim_ratio: f64,
7 #[serde(default = "default_hard_clear_ratio")]
8 pub hard_clear_ratio: f64,
9 #[serde(default = "default_preserve_recent")]
10 pub preserve_recent: usize,
11 #[serde(default)]
12 pub checkpoint_enabled: bool,
13 #[serde(default = "default_checkpoint_interval")]
14 pub checkpoint_interval_turns: u32,
15}
16
17impl Default for ContextConfig {
18 fn default() -> Self {
19 Self {
20 max_tokens: default_max_context_tokens(),
21 soft_trim_ratio: default_soft_trim_ratio(),
22 hard_clear_ratio: default_hard_clear_ratio(),
23 preserve_recent: default_preserve_recent(),
24 checkpoint_enabled: false,
25 checkpoint_interval_turns: default_checkpoint_interval(),
26 }
27 }
28}
29
30fn default_checkpoint_interval() -> u32 {
31 10
32}
33
34fn default_max_context_tokens() -> usize {
35 128_000
36}
37fn default_soft_trim_ratio() -> f64 {
38 0.8
39}
40fn default_hard_clear_ratio() -> f64 {
41 0.95
42}
43fn default_preserve_recent() -> usize {
44 10
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct ApprovalsConfig {
49 #[serde(default)]
50 pub enabled: bool,
51 #[serde(default)]
52 pub gated_tools: Vec<String>,
53 #[serde(default)]
54 pub blocked_tools: Vec<String>,
55 #[serde(default = "default_approval_timeout")]
56 pub timeout_seconds: u64,
57}
58
59impl Default for ApprovalsConfig {
60 fn default() -> Self {
61 Self {
62 enabled: false,
63 gated_tools: Vec::new(),
64 blocked_tools: Vec::new(),
65 timeout_seconds: default_approval_timeout(),
66 }
67 }
68}
69
70fn default_approval_timeout() -> u64 {
71 300
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct PluginsConfig {
76 #[serde(default = "default_plugins_dir")]
77 pub dir: PathBuf,
78 #[serde(default)]
79 pub allow: Vec<String>,
80 #[serde(default)]
81 pub deny: Vec<String>,
82 #[serde(default)]
83 pub strict_permissions: bool,
84 #[serde(default)]
85 pub allowed_permissions: Vec<String>,
86}
87
88impl Default for PluginsConfig {
89 fn default() -> Self {
90 Self {
91 dir: default_plugins_dir(),
92 allow: Vec::new(),
93 deny: Vec::new(),
94 strict_permissions: true,
95 allowed_permissions: Vec::new(),
96 }
97 }
98}
99
100fn default_plugins_dir() -> PathBuf {
101 dirs_next().join("plugins")
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct BrowserConfig {
106 #[serde(default)]
107 pub enabled: bool,
108 #[serde(default)]
109 pub executable_path: Option<String>,
110 #[serde(default = "default_true")]
111 pub headless: bool,
112 #[serde(default = "default_browser_profile_dir")]
113 pub profile_dir: PathBuf,
114 #[serde(default = "default_cdp_port")]
115 pub cdp_port: u16,
116}
117
118impl Default for BrowserConfig {
119 fn default() -> Self {
120 Self {
121 enabled: false,
122 executable_path: None,
123 headless: true,
124 profile_dir: default_browser_profile_dir(),
125 cdp_port: default_cdp_port(),
126 }
127 }
128}
129
130fn default_cdp_port() -> u16 {
131 9222
132}
133
134fn default_browser_profile_dir() -> PathBuf {
135 dirs_next().join("browser-profiles")
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct DaemonConfig {
140 #[serde(default)]
141 pub auto_restart: bool,
142 #[serde(default = "default_pid_file")]
143 pub pid_file: PathBuf,
144}
145
146impl Default for DaemonConfig {
147 fn default() -> Self {
148 Self {
149 auto_restart: false,
150 pid_file: default_pid_file(),
151 }
152 }
153}
154
155fn default_pid_file() -> PathBuf {
156 dirs_next().join("roboticus.pid")
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct UpdateConfig {
161 #[serde(default = "default_true")]
162 pub check_on_start: bool,
163 #[serde(default = "default_update_channel")]
164 pub channel: String,
165 #[serde(default = "default_update_registry_url")]
169 pub registry_url: String,
170 #[serde(default)]
173 pub registries: Vec<RegistrySource>,
174}
175
176impl Default for UpdateConfig {
177 fn default() -> Self {
178 Self {
179 check_on_start: true,
180 channel: default_update_channel(),
181 registry_url: default_update_registry_url(),
182 registries: Vec::new(),
183 }
184 }
185}
186
187impl UpdateConfig {
188 pub fn resolve_registries(&self) -> Vec<RegistrySource> {
192 if !self.registries.is_empty() {
193 return self.registries.clone();
194 }
195 vec![RegistrySource {
196 name: "default".into(),
197 url: self.registry_url.clone(),
198 priority: 50,
199 enabled: true,
200 }]
201 }
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct RegistrySource {
207 pub name: String,
210 pub url: String,
212 #[serde(default = "default_registry_priority")]
215 pub priority: u32,
216 #[serde(default = "default_true")]
218 pub enabled: bool,
219}
220
221fn default_registry_priority() -> u32 {
222 50
223}
224
225fn default_update_channel() -> String {
226 "stable".into()
227}
228
229fn default_update_registry_url() -> String {
230 "https://roboticus.ai/registry/manifest.json".into()
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234pub struct PersonalityConfig {
235 #[serde(default = "default_os_file")]
236 pub os_file: String,
237 #[serde(default = "default_firmware_file")]
238 pub firmware_file: String,
239}
240
241impl Default for PersonalityConfig {
242 fn default() -> Self {
243 Self {
244 os_file: default_os_file(),
245 firmware_file: default_firmware_file(),
246 }
247 }
248}
249
250fn default_os_file() -> String {
251 "OS.toml".into()
252}
253fn default_firmware_file() -> String {
254 "FIRMWARE.toml".into()
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct SessionConfig {
259 #[serde(default = "default_session_ttl")]
260 pub ttl_seconds: u64,
261 #[serde(default = "default_session_scope_mode")]
262 pub scope_mode: String,
263 #[serde(default)]
264 pub reset_schedule: Option<String>,
265}
266
267impl Default for SessionConfig {
268 fn default() -> Self {
269 Self {
270 ttl_seconds: default_session_ttl(),
271 scope_mode: default_session_scope_mode(),
272 reset_schedule: None,
273 }
274 }
275}
276
277fn default_session_ttl() -> u64 {
278 86400
279}
280
281#[derive(Debug, Clone, Serialize, Deserialize)]
282pub struct McpConfig {
283 #[serde(default)]
284 pub server_enabled: bool,
285 #[serde(default = "default_mcp_port")]
286 pub server_port: u16,
287 #[serde(default)]
288 pub clients: Vec<McpClientConfig>,
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct McpClientConfig {
293 pub name: String,
294 pub url: String,
295 #[serde(default)]
296 pub transport: McpTransport,
297 #[serde(default)]
298 pub auth_token_env: Option<String>,
299}
300
301#[derive(Debug, Clone, Default, Serialize, Deserialize)]
302pub enum McpTransport {
303 #[default]
304 Sse,
305 Stdio,
306 Http,
307 WebSocket,
308}
309
310fn default_mcp_port() -> u16 {
311 3001
312}
313
314impl Default for McpConfig {
315 fn default() -> Self {
316 Self {
317 server_enabled: false,
318 server_port: default_mcp_port(),
319 clients: Vec::new(),
320 }
321 }
322}
323
324fn default_session_scope_mode() -> String {
325 "agent".into()
326}