microclaw_engine/config/
governance.rs1use super::*;
2
3#[derive(Clone, Debug, Default, Serialize, Deserialize)]
6pub struct SelfRecheckConfig {
7 #[serde(default)]
8 pub enabled: bool,
9 #[serde(default)]
12 pub prompt: Option<String>,
13}
14
15pub(crate) fn default_token_budget_exempt_control_chats() -> bool {
16 true
17}
18
19#[derive(Clone, Debug, Serialize, Deserialize)]
25pub struct TokenBudgetConfig {
26 #[serde(default)]
28 pub daily_per_chat: i64,
29 #[serde(default = "default_token_budget_exempt_control_chats")]
30 pub exempt_control_chats: bool,
31}
32
33impl Default for TokenBudgetConfig {
34 fn default() -> Self {
35 Self {
36 daily_per_chat: 0,
37 exempt_control_chats: default_token_budget_exempt_control_chats(),
38 }
39 }
40}
41
42impl TokenBudgetConfig {
43 pub fn blocks(&self, is_control_chat: bool, used: i64) -> bool {
46 if self.daily_per_chat <= 0 {
47 return false;
48 }
49 if self.exempt_control_chats && is_control_chat {
50 return false;
51 }
52 used >= self.daily_per_chat
53 }
54}
55
56pub(crate) fn default_alerts_interval_secs() -> u64 {
57 60
58}
59
60pub(crate) fn default_alerts_cooldown_secs() -> u64 {
61 900
62}
63
64pub(crate) fn default_alerts_restart_storm_threshold() -> u64 {
65 5
66}
67
68#[derive(Clone, Debug, Serialize, Deserialize)]
75pub struct AlertsConfig {
76 #[serde(default)]
77 pub enabled: bool,
78 #[serde(default)]
81 pub webhook_url: String,
82 #[serde(default = "default_alerts_interval_secs")]
84 pub interval_secs: u64,
85 #[serde(default = "default_alerts_cooldown_secs")]
87 pub cooldown_secs: u64,
88 #[serde(default = "default_alerts_restart_storm_threshold")]
91 pub restart_storm_threshold: u64,
92}
93
94impl Default for AlertsConfig {
95 fn default() -> Self {
96 Self {
97 enabled: false,
98 webhook_url: String::new(),
99 interval_secs: default_alerts_interval_secs(),
100 cooldown_secs: default_alerts_cooldown_secs(),
101 restart_storm_threshold: default_alerts_restart_storm_threshold(),
102 }
103 }
104}
105
106pub(crate) fn default_trust_report_interval_days() -> u64 {
107 7
108}
109
110#[derive(Clone, Debug, Serialize, Deserialize)]
117pub struct TrustReportConfig {
118 #[serde(default)]
119 pub enabled: bool,
120 #[serde(default = "default_trust_report_interval_days")]
122 pub interval_days: u64,
123}
124
125impl Default for TrustReportConfig {
126 fn default() -> Self {
127 Self {
128 enabled: false,
129 interval_days: default_trust_report_interval_days(),
130 }
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137 #[allow(unused_imports)]
138 use crate::config::test_prelude::*;
139
140 #[test]
141 fn token_budget_disabled_never_blocks() {
142 let cfg = TokenBudgetConfig::default();
143 assert!(!cfg.blocks(false, i64::MAX));
144 assert!(!cfg.blocks(true, i64::MAX));
145 }
146
147 #[test]
148 fn token_budget_blocks_at_cap_but_exempts_control_chats() {
149 let cfg = TokenBudgetConfig {
150 daily_per_chat: 1000,
151 exempt_control_chats: true,
152 };
153 assert!(!cfg.blocks(false, 999));
154 assert!(cfg.blocks(false, 1000));
155 assert!(cfg.blocks(false, 5000));
156 assert!(!cfg.blocks(true, 5000));
158 let strict = TokenBudgetConfig {
160 daily_per_chat: 1000,
161 exempt_control_chats: false,
162 };
163 assert!(strict.blocks(true, 1000));
164 }
165}