roboticus_core/config/
agent_paths.rs1#[derive(Debug, Clone, Serialize, Deserialize)]
2pub struct AgentConfig {
3 pub name: String,
4 pub id: String,
5 #[serde(default = "default_workspace")]
6 pub workspace: PathBuf,
7 #[serde(default = "default_log_level")]
8 pub log_level: String,
9 #[serde(default = "default_true")]
10 pub delegation_enabled: bool,
11 #[serde(default = "default_min_decomposition_complexity")]
12 pub delegation_min_complexity: f64,
13 #[serde(default = "default_min_delegation_utility_margin")]
14 pub delegation_min_utility_margin: f64,
15 #[serde(default = "default_true")]
16 pub specialist_creation_requires_approval: bool,
17 #[serde(default = "default_autonomy_max_react_turns")]
18 pub autonomy_max_react_turns: usize,
19 #[serde(default = "default_autonomy_max_turn_duration_seconds")]
20 pub autonomy_max_turn_duration_seconds: u64,
21}
22
23fn default_workspace() -> PathBuf {
24 dirs_next().join("workspace")
25}
26
27fn default_log_level() -> String {
28 "info".into()
29}
30
31fn default_min_decomposition_complexity() -> f64 {
32 0.35
33}
34
35fn default_min_delegation_utility_margin() -> f64 {
36 0.15
37}
38
39fn default_autonomy_max_react_turns() -> usize {
40 10
41}
42
43fn default_autonomy_max_turn_duration_seconds() -> u64 {
44 90
45}
46
47fn default_log_dir() -> PathBuf {
48 let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".into());
49 PathBuf::from(home).join(".roboticus").join("logs")
50}
51
52fn default_log_max_days() -> u32 {
53 7
54}
55
56fn dirs_next() -> PathBuf {
57 let home = home_dir();
58 let legacy = home.join(".ironclad");
59 let new_dir = home.join(".roboticus");
60 if legacy.exists() && !new_dir.exists() {
61 if let Err(e) = std::fs::rename(&legacy, &new_dir) {
62 tracing::warn!(error = %e, "failed to migrate ~/.ironclad to ~/.roboticus");
63 } else {
64 tracing::info!("Migrated config directory from ~/.ironclad to ~/.roboticus");
65 }
66 }
67 new_dir
68}
69
70pub fn home_dir() -> PathBuf {
73 std::env::var("HOME")
74 .or_else(|_| std::env::var("USERPROFILE"))
75 .map(PathBuf::from)
76 .unwrap_or_else(|_| std::env::temp_dir())
77}
78
79pub fn resolve_config_path(explicit: Option<&str>) -> Option<PathBuf> {
86 if let Some(p) = explicit {
87 return Some(expand_tilde(Path::new(p)));
88 }
89 let home_config = home_dir().join(".roboticus").join("roboticus.toml");
90 if home_config.exists() {
91 return Some(home_config);
92 }
93 let cwd_config = PathBuf::from("roboticus.toml");
94 if cwd_config.exists() {
95 return Some(cwd_config);
96 }
97 None
98}
99
100fn expand_tilde(path: &Path) -> PathBuf {
102 if let Ok(stripped) = path.strip_prefix("~") {
103 home_dir().join(stripped)
104 } else {
105 path.to_path_buf()
106 }
107}
108