mockforge_core/ai_studio/
config.rs1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
12#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
13#[serde(rename_all = "snake_case")]
14pub enum AiMode {
15 GenerateOnceFreeze,
18
19 Live,
21}
22
23impl Default for AiMode {
24 fn default() -> Self {
25 Self::Live
26 }
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize, Default)]
31#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
32pub struct AiStudioConfig {
33 #[serde(default)]
35 pub deterministic_mode: DeterministicModeConfig,
36
37 #[serde(default)]
39 pub budgets: BudgetConfig,
40
41 #[serde(default)]
43 pub features: FeatureConfig,
44}
45
46#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
48#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
49#[serde(rename_all = "snake_case")]
50pub enum FreezeMode {
51 Auto,
53 Manual,
55}
56
57impl Default for FreezeMode {
58 fn default() -> Self {
59 Self::Manual
60 }
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
68#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
69pub struct DeterministicModeConfig {
70 #[serde(default = "default_false")]
72 pub enabled: bool,
73
74 #[serde(default)]
76 pub mode: FreezeMode,
77
78 #[serde(default = "default_true")]
81 pub auto_freeze: bool,
82
83 #[serde(default = "default_freeze_format")]
85 pub freeze_format: String,
86
87 #[serde(default = "default_freeze_directory")]
89 pub freeze_directory: String,
90
91 #[serde(default = "default_true")]
93 pub track_metadata: bool,
94}
95
96impl DeterministicModeConfig {
97 pub fn is_auto_freeze_enabled(&self) -> bool {
99 self.mode == FreezeMode::Auto || self.auto_freeze
100 }
101}
102
103impl Default for DeterministicModeConfig {
104 fn default() -> Self {
105 Self {
106 enabled: false,
107 mode: FreezeMode::Manual,
108 auto_freeze: true, freeze_format: "yaml".to_string(),
110 freeze_directory: ".mockforge/frozen".to_string(),
111 track_metadata: true,
112 }
113 }
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
119pub struct BudgetConfig {
120 #[serde(default = "default_max_tokens")]
122 pub max_tokens_per_workspace: u64,
123
124 #[serde(default = "default_max_calls")]
126 pub max_ai_calls_per_day: u64,
127
128 #[serde(default = "default_rate_limit")]
130 pub rate_limit_per_minute: u64,
131
132 #[serde(default = "default_alert_threshold")]
134 pub alert_threshold: f64,
135}
136
137impl Default for BudgetConfig {
138 fn default() -> Self {
139 Self {
140 max_tokens_per_workspace: 100_000,
141 max_ai_calls_per_day: 1_000,
142 rate_limit_per_minute: 10,
143 alert_threshold: 0.8, }
145 }
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
151pub struct FeatureConfig {
152 #[serde(default = "default_true")]
154 pub mock_generation: bool,
155
156 #[serde(default = "default_true")]
158 pub contract_diff: bool,
159
160 #[serde(default = "default_true")]
162 pub persona_generation: bool,
163
164 #[serde(default = "default_true")]
166 pub free_form_generation: bool,
167
168 #[serde(default = "default_true")]
170 pub debug_analysis: bool,
171}
172
173impl Default for FeatureConfig {
174 fn default() -> Self {
175 Self {
176 mock_generation: true,
177 contract_diff: true,
178 persona_generation: true,
179 free_form_generation: true,
180 debug_analysis: true,
181 }
182 }
183}
184
185fn default_false() -> bool {
188 false
189}
190
191fn default_true() -> bool {
192 true
193}
194
195fn default_freeze_format() -> String {
196 "yaml".to_string()
197}
198
199fn default_freeze_directory() -> String {
200 ".mockforge/frozen".to_string()
201}
202
203fn default_max_tokens() -> u64 {
204 100_000
205}
206
207fn default_max_calls() -> u64 {
208 1_000
209}
210
211fn default_rate_limit() -> u64 {
212 10
213}
214
215fn default_alert_threshold() -> f64 {
216 0.8
217}