use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub analysis: AnalysisConfig,
pub generation: GenerationConfig,
pub output: OutputConfig,
pub telemetry: TelemetryConfig,
#[serde(default)]
pub agent: AgentConfig,
#[serde(default)]
pub syncable_auth: SyncableAuth,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisConfig {
pub include_dev_dependencies: bool,
pub deep_analysis: bool,
pub ignore_patterns: Vec<String>,
pub max_file_size: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenerationConfig {
pub dockerfile: DockerfileConfig,
pub compose: ComposeConfig,
pub terraform: TerraformConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DockerfileConfig {
pub base_image_override: Option<String>,
pub use_multi_stage: bool,
pub optimize_for_size: bool,
pub include_health_check: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComposeConfig {
pub version: String,
pub include_database: bool,
pub include_redis: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TerraformConfig {
pub provider: String,
pub include_networking: bool,
pub include_monitoring: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutputConfig {
pub format: OutputFormat,
pub overwrite_existing: bool,
pub create_backup: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OutputFormat {
Files,
Stdout,
Json,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TelemetryConfig {
pub enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct AgentConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub openai_api_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub anthropic_api_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bedrock: Option<BedrockConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bedrock_configured: Option<bool>,
#[serde(default = "default_provider")]
pub default_provider: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub profiles: HashMap<String, Profile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub active_profile: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub openai_profiles: HashMap<String, OpenAIProfile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub openai_active_profile: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub anthropic_profiles: HashMap<String, AnthropicProfile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub anthropic_active_profile: Option<String>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub bedrock_profiles: HashMap<String, BedrockConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bedrock_active_profile: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Profile {
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_provider: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub openai: Option<OpenAIProfile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub anthropic: Option<AnthropicProfile>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bedrock: Option<BedrockConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct OpenAIProfile {
pub api_key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct AnthropicProfile {
pub api_key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct BedrockConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub profile: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub access_key_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub secret_access_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bearer_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_model: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SyncableAuth {
#[serde(skip_serializing_if = "Option::is_none")]
pub access_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_email: Option<String>,
}
fn default_provider() -> String {
"openai".to_string()
}
impl Default for Config {
fn default() -> Self {
Self {
analysis: AnalysisConfig {
include_dev_dependencies: false,
deep_analysis: true,
ignore_patterns: vec![
"node_modules".to_string(),
".git".to_string(),
"target".to_string(),
"build".to_string(),
],
max_file_size: 1024 * 1024, },
generation: GenerationConfig {
dockerfile: DockerfileConfig {
base_image_override: None,
use_multi_stage: true,
optimize_for_size: true,
include_health_check: true,
},
compose: ComposeConfig {
version: "3.8".to_string(),
include_database: false,
include_redis: false,
},
terraform: TerraformConfig {
provider: "docker".to_string(),
include_networking: true,
include_monitoring: false,
},
},
output: OutputConfig {
format: OutputFormat::Files,
overwrite_existing: false,
create_backup: true,
},
telemetry: TelemetryConfig { enabled: true },
agent: AgentConfig::default(),
syncable_auth: SyncableAuth::default(),
}
}
}