package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) type Config struct { Server ServerConfig `yaml:"server"` AI AIConfig `yaml:"ai"` Agent AgentConfig `yaml:"agent"` Tools ToolsConfig `yaml:"tools"` Logging LoggingConfig `yaml:"logging"` } type ServerConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` } type AIConfig struct { DefaultProvider string `yaml:"default_provider"` Ollama OllamaConfig `yaml:"ollama"` OpenAI OpenAIConfig `yaml:"openai"` Anthropic AnthropicConfig `yaml:"anthropic"` Google GoogleConfig `yaml:"google"` } type OllamaConfig struct { BaseURL string `yaml:"base_url"` Model string `yaml:"model"` } type OpenAIConfig struct { APIKey string `yaml:"api_key"` Model string `yaml:"model"` BaseURL string `yaml:"base_url"` } type AnthropicConfig struct { APIKey string `yaml:"api_key"` Model string `yaml:"model"` BaseURL string `yaml:"base_url"` } type GoogleConfig struct { APIKey string `yaml:"api_key"` Model string `yaml:"model"` } type AgentConfig struct { MaxIterations int `yaml:"max_iterations"` TimeoutSeconds int `yaml:"timeout_seconds"` SystemPrompt string `yaml:"system_prompt"` } type ToolsConfig struct { Terminal TerminalToolConfig `yaml:"terminal"` Browser BrowserToolConfig `yaml:"browser"` Desktop DesktopToolConfig `yaml:"desktop"` Filesystem FilesystemToolConfig `yaml:"filesystem"` Clipboard ClipboardToolConfig `yaml:"clipboard"` } type TerminalToolConfig struct { Enabled bool `yaml:"enabled"` Shell string `yaml:"shell"` TimeoutSeconds int `yaml:"timeout_seconds"` BlockedCommands []string `yaml:"blocked_commands"` } type BrowserToolConfig struct { Enabled bool `yaml:"enabled"` Headless bool `yaml:"headless"` } type DesktopToolConfig struct { Enabled bool `yaml:"enabled"` } type FilesystemToolConfig struct { Enabled bool `yaml:"enabled"` AllowedPaths []string `yaml:"allowed_paths"` } type ClipboardToolConfig struct { Enabled bool `yaml:"enabled"` } type LoggingConfig struct { Level string `yaml:"level"` Format string `yaml:"format"` } func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading config file: %w", err) } cfg := &Config{} if err := yaml.Unmarshal(data, cfg); err != nil { return nil, fmt.Errorf("parsing config file: %w", err) } cfg.applyEnvOverrides() cfg.setDefaults() return cfg, nil } func (c *Config) applyEnvOverrides() { if key := os.Getenv("OPENAI_API_KEY"); key != "" { c.AI.OpenAI.APIKey = key } if key := os.Getenv("ANTHROPIC_API_KEY"); key != "" { c.AI.Anthropic.APIKey = key } if key := os.Getenv("GOOGLE_API_KEY"); key != "" { c.AI.Google.APIKey = key } if url := os.Getenv("OLLAMA_BASE_URL"); url != "" { c.AI.Ollama.BaseURL = url } } func (c *Config) setDefaults() { if c.Server.Port == 0 { c.Server.Port = 8080 } if c.Server.Host == "" { c.Server.Host = "0.0.0.0" } if c.AI.DefaultProvider == "" { c.AI.DefaultProvider = "ollama" } if c.AI.Ollama.BaseURL == "" { c.AI.Ollama.BaseURL = "http://localhost:11434" } if c.AI.Ollama.Model == "" { c.AI.Ollama.Model = "llama3" } if c.Agent.MaxIterations == 0 { c.Agent.MaxIterations = 20 } if c.Agent.TimeoutSeconds == 0 { c.Agent.TimeoutSeconds = 300 } if c.Tools.Terminal.Shell == "" { c.Tools.Terminal.Shell = "/bin/bash" } if c.Tools.Terminal.TimeoutSeconds == 0 { c.Tools.Terminal.TimeoutSeconds = 60 } if c.Logging.Level == "" { c.Logging.Level = "info" } if c.Logging.Format == "" { c.Logging.Format = "text" } }