1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Config {
7 pub analysis: AnalysisConfig,
8 pub generation: GenerationConfig,
9 pub output: OutputConfig,
10 pub telemetry: TelemetryConfig,
11 #[serde(default)]
12 pub agent: AgentConfig,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct AnalysisConfig {
18 pub include_dev_dependencies: bool,
19 pub deep_analysis: bool,
20 pub ignore_patterns: Vec<String>,
21 pub max_file_size: usize,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct GenerationConfig {
27 pub dockerfile: DockerfileConfig,
28 pub compose: ComposeConfig,
29 pub terraform: TerraformConfig,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct DockerfileConfig {
35 pub base_image_override: Option<String>,
36 pub use_multi_stage: bool,
37 pub optimize_for_size: bool,
38 pub include_health_check: bool,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct ComposeConfig {
44 pub version: String,
45 pub include_database: bool,
46 pub include_redis: bool,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct TerraformConfig {
52 pub provider: String,
53 pub include_networking: bool,
54 pub include_monitoring: bool,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct OutputConfig {
60 pub format: OutputFormat,
61 pub overwrite_existing: bool,
62 pub create_backup: bool,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub enum OutputFormat {
67 Files,
68 Stdout,
69 Json,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct TelemetryConfig {
75 pub enabled: bool,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize, Default)]
80pub struct AgentConfig {
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub openai_api_key: Option<String>,
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub anthropic_api_key: Option<String>,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub bedrock: Option<BedrockConfig>,
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub bedrock_configured: Option<bool>,
93 #[serde(default = "default_provider")]
95 pub default_provider: String,
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub default_model: Option<String>,
99
100 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
103 pub profiles: HashMap<String, Profile>,
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub active_profile: Option<String>,
107
108 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
110 pub openai_profiles: HashMap<String, OpenAIProfile>,
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub openai_active_profile: Option<String>,
113 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
114 pub anthropic_profiles: HashMap<String, AnthropicProfile>,
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub anthropic_active_profile: Option<String>,
117 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
118 pub bedrock_profiles: HashMap<String, BedrockConfig>,
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub bedrock_active_profile: Option<String>,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize, Default)]
125pub struct Profile {
126 #[serde(skip_serializing_if = "Option::is_none")]
128 pub description: Option<String>,
129 #[serde(skip_serializing_if = "Option::is_none")]
131 pub default_provider: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub default_model: Option<String>,
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub openai: Option<OpenAIProfile>,
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub anthropic: Option<AnthropicProfile>,
141 #[serde(skip_serializing_if = "Option::is_none")]
143 pub bedrock: Option<BedrockConfig>,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, Default)]
148pub struct OpenAIProfile {
149 pub api_key: String,
151 #[serde(skip_serializing_if = "Option::is_none")]
153 pub description: Option<String>,
154 #[serde(skip_serializing_if = "Option::is_none")]
156 pub default_model: Option<String>,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize, Default)]
161pub struct AnthropicProfile {
162 pub api_key: String,
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub description: Option<String>,
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub default_model: Option<String>,
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize, Default)]
174pub struct BedrockConfig {
175 #[serde(skip_serializing_if = "Option::is_none")]
177 pub region: Option<String>,
178 #[serde(skip_serializing_if = "Option::is_none")]
180 pub profile: Option<String>,
181 #[serde(skip_serializing_if = "Option::is_none")]
183 pub access_key_id: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
186 pub secret_access_key: Option<String>,
187 #[serde(skip_serializing_if = "Option::is_none")]
189 pub bearer_token: Option<String>,
190 #[serde(skip_serializing_if = "Option::is_none")]
192 pub default_model: Option<String>,
193}
194
195fn default_provider() -> String {
196 "openai".to_string()
197}
198
199impl Default for Config {
200 fn default() -> Self {
201 Self {
202 analysis: AnalysisConfig {
203 include_dev_dependencies: false,
204 deep_analysis: true,
205 ignore_patterns: vec![
206 "node_modules".to_string(),
207 ".git".to_string(),
208 "target".to_string(),
209 "build".to_string(),
210 ],
211 max_file_size: 1024 * 1024, },
213 generation: GenerationConfig {
214 dockerfile: DockerfileConfig {
215 base_image_override: None,
216 use_multi_stage: true,
217 optimize_for_size: true,
218 include_health_check: true,
219 },
220 compose: ComposeConfig {
221 version: "3.8".to_string(),
222 include_database: false,
223 include_redis: false,
224 },
225 terraform: TerraformConfig {
226 provider: "docker".to_string(),
227 include_networking: true,
228 include_monitoring: false,
229 },
230 },
231 output: OutputConfig {
232 format: OutputFormat::Files,
233 overwrite_existing: false,
234 create_backup: true,
235 },
236 telemetry: TelemetryConfig { enabled: true },
237 agent: AgentConfig::default(),
238 }
239 }
240}