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))]
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
14#[serde(rename_all = "lowercase")]
15pub enum ReasoningEffortLevel {
16 None,
17 Minimal,
18 Low,
19 Medium,
20 High,
21}
22
23impl ReasoningEffortLevel {
24 pub fn as_str(self) -> &'static str {
26 match self {
27 Self::None => "none",
28 Self::Minimal => "minimal",
29 Self::Low => reasoning::LOW,
30 Self::Medium => reasoning::MEDIUM,
31 Self::High => reasoning::HIGH,
32 }
33 }
34
35 pub fn parse(value: &str) -> Option<Self> {
37 let normalized = value.trim();
38 if normalized.eq_ignore_ascii_case("none") {
39 Some(Self::None)
40 } else if normalized.eq_ignore_ascii_case("minimal") {
41 Some(Self::Minimal)
42 } else if normalized.eq_ignore_ascii_case(reasoning::LOW) {
43 Some(Self::Low)
44 } else if normalized.eq_ignore_ascii_case(reasoning::MEDIUM) {
45 Some(Self::Medium)
46 } else if normalized.eq_ignore_ascii_case(reasoning::HIGH) {
47 Some(Self::High)
48 } else {
49 None
50 }
51 }
52
53 pub fn allowed_values() -> &'static [&'static str] {
55 reasoning::ALLOWED_LEVELS
56 }
57}
58
59impl Default for ReasoningEffortLevel {
60 fn default() -> Self {
61 Self::Medium
62 }
63}
64
65#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
68#[serde(rename_all = "lowercase")]
69pub enum VerbosityLevel {
70 Low,
71 Medium,
72 High,
73}
74
75impl VerbosityLevel {
76 pub fn as_str(self) -> &'static str {
78 match self {
79 Self::Low => "low",
80 Self::Medium => "medium",
81 Self::High => "high",
82 }
83 }
84
85 pub fn parse(value: &str) -> Option<Self> {
87 let normalized = value.trim();
88 if normalized.eq_ignore_ascii_case("low") {
89 Some(Self::Low)
90 } else if normalized.eq_ignore_ascii_case("medium") {
91 Some(Self::Medium)
92 } else if normalized.eq_ignore_ascii_case("high") {
93 Some(Self::High)
94 } else {
95 None
96 }
97 }
98
99 pub fn allowed_values() -> &'static [&'static str] {
101 &["low", "medium", "high"]
102 }
103}
104
105impl Default for VerbosityLevel {
106 fn default() -> Self {
107 Self::Medium
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")]
165pub enum UiSurfacePreference {
166 Auto,
167 Alternate,
168 Inline,
169}
170
171impl UiSurfacePreference {
172 pub fn as_str(self) -> &'static str {
174 match self {
175 Self::Auto => "auto",
176 Self::Alternate => "alternate",
177 Self::Inline => "inline",
178 }
179 }
180
181 pub fn parse(value: &str) -> Option<Self> {
183 let normalized = value.trim();
184 if normalized.eq_ignore_ascii_case("auto") {
185 Some(Self::Auto)
186 } else if normalized.eq_ignore_ascii_case("alternate")
187 || normalized.eq_ignore_ascii_case("alt")
188 {
189 Some(Self::Alternate)
190 } else if normalized.eq_ignore_ascii_case("inline") {
191 Some(Self::Inline)
192 } else {
193 None
194 }
195 }
196
197 pub fn allowed_values() -> &'static [&'static str] {
199 &["auto", "alternate", "inline"]
200 }
201}
202
203impl Default for UiSurfacePreference {
204 fn default() -> Self {
205 Self::Auto
206 }
207}
208
209impl fmt::Display for UiSurfacePreference {
210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211 f.write_str(self.as_str())
212 }
213}
214
215impl<'de> Deserialize<'de> for UiSurfacePreference {
216 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217 where
218 D: Deserializer<'de>,
219 {
220 let raw = String::deserialize(deserializer)?;
221 if let Some(parsed) = Self::parse(&raw) {
222 Ok(parsed)
223 } else {
224 tracing::warn!(
225 input = raw,
226 allowed = ?Self::allowed_values(),
227 "Invalid UI surface preference provided; falling back to default"
228 );
229 Ok(Self::default())
230 }
231 }
232}
233
234#[derive(Debug, Clone, Copy, PartialEq, Eq)]
236pub enum ModelSelectionSource {
237 WorkspaceConfig,
239 CliOverride,
241}
242
243impl Default for ModelSelectionSource {
244 fn default() -> Self {
245 Self::WorkspaceConfig
246 }
247}
248
249#[derive(Debug, Clone)]
251pub struct AgentConfig {
252 pub model: String,
253 pub api_key: String,
254 pub provider: String,
255 pub api_key_env: String,
256 pub workspace: std::path::PathBuf,
257 pub verbose: bool,
258 pub theme: String,
259 pub reasoning_effort: ReasoningEffortLevel,
260 pub ui_surface: UiSurfacePreference,
261 pub prompt_cache: PromptCachingConfig,
262 pub model_source: ModelSelectionSource,
263 pub custom_api_keys: BTreeMap<String, String>,
264 pub checkpointing_enabled: bool,
265 pub checkpointing_storage_dir: Option<PathBuf>,
266 pub checkpointing_max_snapshots: usize,
267 pub checkpointing_max_age_days: Option<u64>,
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
272pub enum CapabilityLevel {
273 Basic,
275 FileReading,
277 FileListing,
279 Bash,
281 Editing,
283 CodeSearch,
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct SessionInfo {
290 pub session_id: String,
291 pub start_time: u64,
292 pub total_turns: usize,
293 pub total_decisions: usize,
294 pub error_count: usize,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct ConversationTurn {
300 pub turn_number: usize,
301 pub timestamp: u64,
302 pub user_input: Option<String>,
303 pub agent_response: Option<String>,
304 pub tool_calls: Vec<ToolCallInfo>,
305 pub decision: Option<DecisionInfo>,
306}
307
308#[derive(Debug, Clone, Serialize, Deserialize)]
310pub struct ToolCallInfo {
311 pub name: String,
312 pub args: Value,
313 pub result: Option<Value>,
314 pub error: Option<String>,
315 pub execution_time_ms: Option<u64>,
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
320pub struct DecisionInfo {
321 pub turn_number: usize,
322 pub action_type: String,
323 pub description: String,
324 pub reasoning: String,
325 pub outcome: Option<String>,
326 pub confidence_score: Option<f64>,
327 pub timestamp: u64,
328}
329
330#[derive(Debug, Clone, Serialize, Deserialize)]
332pub struct ErrorInfo {
333 pub error_type: String,
334 pub message: String,
335 pub turn_number: usize,
336 pub recoverable: bool,
337 pub timestamp: u64,
338}
339
340#[derive(Debug, Clone, Serialize, Deserialize)]
342pub struct TaskInfo {
343 pub task_type: String,
344 pub description: String,
345 pub completed: bool,
346 pub success: bool,
347 pub duration_seconds: Option<u64>,
348 pub tools_used: Vec<String>,
349 pub dependencies: Vec<String>,
350}
351
352#[derive(Debug, Clone, Serialize, Deserialize)]
354pub struct ProjectSpec {
355 pub name: String,
356 pub features: Vec<String>,
357 pub template: Option<String>,
358 pub dependencies: HashMap<String, String>,
359}
360
361#[derive(Debug, Clone, Serialize, Deserialize)]
363pub struct WorkspaceAnalysis {
364 pub root_path: String,
365 pub project_type: Option<String>,
366 pub languages: Vec<String>,
367 pub frameworks: Vec<String>,
368 pub config_files: Vec<String>,
369 pub source_files: Vec<String>,
370 pub test_files: Vec<String>,
371 pub documentation_files: Vec<String>,
372 pub total_files: usize,
373 pub total_size_bytes: u64,
374}
375
376#[derive(Debug, Clone, Serialize, Deserialize)]
378pub struct CommandResult {
379 pub command: String,
380 pub success: bool,
381 pub stdout: String,
382 pub stderr: String,
383 pub exit_code: Option<i32>,
384 pub execution_time_ms: u64,
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize)]
389pub struct FileOperationResult {
390 pub operation: String,
391 pub path: String,
392 pub success: bool,
393 pub details: HashMap<String, Value>,
394 pub error: Option<String>,
395}
396
397#[derive(Debug, Clone, Serialize, Deserialize)]
399pub struct PerformanceMetrics {
400 pub session_duration_seconds: u64,
401 pub total_api_calls: usize,
402 pub total_tokens_used: Option<usize>,
403 pub average_response_time_ms: f64,
404 pub tool_execution_count: usize,
405 pub error_count: usize,
406 pub recovery_success_rate: f64,
407}
408
409#[derive(Debug, Clone, Serialize, Deserialize)]
411pub struct QualityMetrics {
412 pub decision_confidence_avg: f64,
413 pub tool_success_rate: f64,
414 pub error_recovery_rate: f64,
415 pub context_preservation_rate: f64,
416 pub user_satisfaction_score: Option<f64>,
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
421pub struct ToolConfig {
422 pub enable_validation: bool,
423 pub max_execution_time_seconds: u64,
424 pub allow_file_creation: bool,
425 pub allow_file_deletion: bool,
426 pub working_directory: Option<String>,
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct ContextConfig {
432 pub max_context_length: usize,
433 pub compression_threshold: usize,
434 pub summarization_interval: usize,
435 pub preservation_priority: Vec<String>,
436}
437
438#[derive(Debug, Clone, Serialize, Deserialize)]
440pub struct LoggingConfig {
441 pub level: String,
442 pub file_logging: bool,
443 pub log_directory: Option<String>,
444 pub max_log_files: usize,
445 pub max_log_size_mb: usize,
446}
447
448#[derive(Debug, Clone, Serialize, Deserialize)]
450pub enum AnalysisDepth {
451 Basic,
452 Standard,
453 Deep,
454}
455
456#[derive(Debug, Clone, Serialize, Deserialize)]
458pub enum OutputFormat {
459 Text,
460 Json,
461 Html,
462}
463
464#[derive(Debug, Clone, Serialize, Deserialize)]
466pub enum CompressionLevel {
467 Light,
468 Medium,
469 Aggressive,
470}