1use crate::constants::reasoning;
4use crate::core::PromptCachingConfig;
5use serde::{Deserialize, Deserializer, Serialize};
6use serde_json::Value;
7use std::collections::{BTreeMap, HashMap};
8use std::fmt;
9use std::path::PathBuf;
10
11#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
17#[serde(rename_all = "lowercase")]
18#[derive(Default)]
19pub enum ReasoningEffortLevel {
20 None,
22 Minimal,
24 Low,
26 #[default]
28 Medium,
29 High,
31}
32
33impl ReasoningEffortLevel {
34 pub fn as_str(self) -> &'static str {
36 match self {
37 Self::None => "none",
38 Self::Minimal => "minimal",
39 Self::Low => reasoning::LOW,
40 Self::Medium => reasoning::MEDIUM,
41 Self::High => reasoning::HIGH,
42 }
43 }
44
45 pub fn parse(value: &str) -> Option<Self> {
47 let normalized = value.trim();
48 if normalized.eq_ignore_ascii_case("none") {
49 Some(Self::None)
50 } else if normalized.eq_ignore_ascii_case("minimal") {
51 Some(Self::Minimal)
52 } else if normalized.eq_ignore_ascii_case(reasoning::LOW) {
53 Some(Self::Low)
54 } else if normalized.eq_ignore_ascii_case(reasoning::MEDIUM) {
55 Some(Self::Medium)
56 } else if normalized.eq_ignore_ascii_case(reasoning::HIGH) {
57 Some(Self::High)
58 } else {
59 None
60 }
61 }
62
63 pub fn allowed_values() -> &'static [&'static str] {
65 reasoning::ALLOWED_LEVELS
66 }
67}
68
69#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
72#[serde(rename_all = "lowercase")]
73#[derive(Default)]
74pub enum VerbosityLevel {
75 Low,
76 #[default]
77 Medium,
78 High,
79}
80
81impl VerbosityLevel {
82 pub fn as_str(self) -> &'static str {
84 match self {
85 Self::Low => "low",
86 Self::Medium => "medium",
87 Self::High => "high",
88 }
89 }
90
91 pub fn parse(value: &str) -> Option<Self> {
93 let normalized = value.trim();
94 if normalized.eq_ignore_ascii_case("low") {
95 Some(Self::Low)
96 } else if normalized.eq_ignore_ascii_case("medium") {
97 Some(Self::Medium)
98 } else if normalized.eq_ignore_ascii_case("high") {
99 Some(Self::High)
100 } else {
101 None
102 }
103 }
104
105 pub fn allowed_values() -> &'static [&'static str] {
107 &["low", "medium", "high"]
108 }
109}
110
111impl fmt::Display for VerbosityLevel {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 f.write_str(self.as_str())
114 }
115}
116
117impl<'de> Deserialize<'de> for VerbosityLevel {
118 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
119 where
120 D: Deserializer<'de>,
121 {
122 let raw = String::deserialize(deserializer)?;
123 if let Some(parsed) = Self::parse(&raw) {
124 Ok(parsed)
125 } else {
126 tracing::warn!(
127 input = raw,
128 allowed = ?Self::allowed_values(),
129 "Invalid verbosity level provided; falling back to default"
130 );
131 Ok(Self::default())
132 }
133 }
134}
135
136impl fmt::Display for ReasoningEffortLevel {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.write_str(self.as_str())
139 }
140}
141
142impl<'de> Deserialize<'de> for ReasoningEffortLevel {
143 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144 where
145 D: Deserializer<'de>,
146 {
147 let raw = String::deserialize(deserializer)?;
148 if let Some(parsed) = Self::parse(&raw) {
149 Ok(parsed)
150 } else {
151 tracing::warn!(
152 input = raw,
153 allowed = ?Self::allowed_values(),
154 "Invalid reasoning effort level provided; falling back to default"
155 );
156 Ok(Self::default())
157 }
158 }
159}
160
161#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
164#[serde(rename_all = "lowercase")]
165#[derive(Default)]
166pub enum UiSurfacePreference {
167 #[default]
168 Auto,
169 Alternate,
170 Inline,
171}
172
173impl UiSurfacePreference {
174 pub fn as_str(self) -> &'static str {
176 match self {
177 Self::Auto => "auto",
178 Self::Alternate => "alternate",
179 Self::Inline => "inline",
180 }
181 }
182
183 pub fn parse(value: &str) -> Option<Self> {
185 let normalized = value.trim();
186 if normalized.eq_ignore_ascii_case("auto") {
187 Some(Self::Auto)
188 } else if normalized.eq_ignore_ascii_case("alternate")
189 || normalized.eq_ignore_ascii_case("alt")
190 {
191 Some(Self::Alternate)
192 } else if normalized.eq_ignore_ascii_case("inline") {
193 Some(Self::Inline)
194 } else {
195 None
196 }
197 }
198
199 pub fn allowed_values() -> &'static [&'static str] {
201 &["auto", "alternate", "inline"]
202 }
203}
204
205impl fmt::Display for UiSurfacePreference {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 f.write_str(self.as_str())
208 }
209}
210
211impl<'de> Deserialize<'de> for UiSurfacePreference {
212 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213 where
214 D: Deserializer<'de>,
215 {
216 let raw = String::deserialize(deserializer)?;
217 if let Some(parsed) = Self::parse(&raw) {
218 Ok(parsed)
219 } else {
220 tracing::warn!(
221 input = raw,
222 allowed = ?Self::allowed_values(),
223 "Invalid UI surface preference provided; falling back to default"
224 );
225 Ok(Self::default())
226 }
227 }
228}
229
230#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
232pub enum ModelSelectionSource {
233 #[default]
235 WorkspaceConfig,
236 CliOverride,
238}
239
240#[derive(Debug, Clone)]
242pub struct AgentConfig {
243 pub model: String,
244 pub api_key: String,
245 pub provider: String,
246 pub api_key_env: String,
247 pub workspace: std::path::PathBuf,
248 pub verbose: bool,
249 pub theme: String,
250 pub reasoning_effort: ReasoningEffortLevel,
251 pub ui_surface: UiSurfacePreference,
252 pub prompt_cache: PromptCachingConfig,
253 pub model_source: ModelSelectionSource,
254 pub custom_api_keys: BTreeMap<String, String>,
255 pub checkpointing_enabled: bool,
256 pub checkpointing_storage_dir: Option<PathBuf>,
257 pub checkpointing_max_snapshots: usize,
258 pub checkpointing_max_age_days: Option<u64>,
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
263pub enum CapabilityLevel {
264 Basic,
266 FileReading,
268 FileListing,
270 Bash,
272 Editing,
274 CodeSearch,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct SessionInfo {
281 pub session_id: String,
282 pub start_time: u64,
283 pub total_turns: usize,
284 pub total_decisions: usize,
285 pub error_count: usize,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
290pub struct ConversationTurn {
291 pub turn_number: usize,
292 pub timestamp: u64,
293 pub user_input: Option<String>,
294 pub agent_response: Option<String>,
295 pub tool_calls: Vec<ToolCallInfo>,
296 pub decision: Option<DecisionInfo>,
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct ToolCallInfo {
302 pub name: String,
303 pub args: Value,
304 pub result: Option<Value>,
305 pub error: Option<String>,
306 pub execution_time_ms: Option<u64>,
307}
308
309#[derive(Debug, Clone, Serialize, Deserialize)]
311pub struct DecisionInfo {
312 pub turn_number: usize,
313 pub action_type: String,
314 pub description: String,
315 pub reasoning: String,
316 pub outcome: Option<String>,
317 pub confidence_score: Option<f64>,
318 pub timestamp: u64,
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
323pub struct ErrorInfo {
324 pub error_type: String,
325 pub message: String,
326 pub turn_number: usize,
327 pub recoverable: bool,
328 pub timestamp: u64,
329}
330
331#[derive(Debug, Clone, Serialize, Deserialize)]
333pub struct TaskInfo {
334 pub task_type: String,
335 pub description: String,
336 pub completed: bool,
337 pub success: bool,
338 pub duration_seconds: Option<u64>,
339 pub tools_used: Vec<String>,
340 pub dependencies: Vec<String>,
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
345pub struct ProjectSpec {
346 pub name: String,
347 pub features: Vec<String>,
348 pub template: Option<String>,
349 pub dependencies: HashMap<String, String>,
350}
351
352#[derive(Debug, Clone, Serialize, Deserialize)]
354pub struct WorkspaceAnalysis {
355 pub root_path: String,
356 pub project_type: Option<String>,
357 pub languages: Vec<String>,
358 pub frameworks: Vec<String>,
359 pub config_files: Vec<String>,
360 pub source_files: Vec<String>,
361 pub test_files: Vec<String>,
362 pub documentation_files: Vec<String>,
363 pub total_files: usize,
364 pub total_size_bytes: u64,
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize)]
369pub struct CommandResult {
370 pub command: String,
371 pub success: bool,
372 pub stdout: String,
373 pub stderr: String,
374 pub exit_code: Option<i32>,
375 pub execution_time_ms: u64,
376}
377
378#[derive(Debug, Clone, Serialize, Deserialize)]
380pub struct FileOperationResult {
381 pub operation: String,
382 pub path: String,
383 pub success: bool,
384 pub details: HashMap<String, Value>,
385 pub error: Option<String>,
386}
387
388#[derive(Debug, Clone, Serialize, Deserialize)]
390pub struct PerformanceMetrics {
391 pub session_duration_seconds: u64,
392 pub total_api_calls: usize,
393 pub total_tokens_used: Option<usize>,
394 pub average_response_time_ms: f64,
395 pub tool_execution_count: usize,
396 pub error_count: usize,
397 pub recovery_success_rate: f64,
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize)]
402pub struct QualityMetrics {
403 pub decision_confidence_avg: f64,
404 pub tool_success_rate: f64,
405 pub error_recovery_rate: f64,
406 pub context_preservation_rate: f64,
407 pub user_satisfaction_score: Option<f64>,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize)]
412pub struct ToolConfig {
413 pub enable_validation: bool,
414 pub max_execution_time_seconds: u64,
415 pub allow_file_creation: bool,
416 pub allow_file_deletion: bool,
417 pub working_directory: Option<String>,
418}
419
420#[derive(Debug, Clone, Serialize, Deserialize)]
422pub struct ContextConfig {
423 pub max_context_length: usize,
424 pub compression_threshold: usize,
425 pub summarization_interval: usize,
426 pub preservation_priority: Vec<String>,
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct LoggingConfig {
432 pub level: String,
433 pub file_logging: bool,
434 pub log_directory: Option<String>,
435 pub max_log_files: usize,
436 pub max_log_size_mb: usize,
437}
438
439#[derive(Debug, Clone, Serialize, Deserialize)]
441pub enum AnalysisDepth {
442 Basic,
443 Standard,
444 Deep,
445}
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
449pub enum OutputFormat {
450 Text,
451 Json,
452 Html,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
457pub enum CompressionLevel {
458 Light,
459 Medium,
460 Aggressive,
461}