package config import ( "encoding/json" "fmt" "os" ) // Config represents the application configuration type Config struct { Server ServerConfig `json:"server"` LLM LLMConfig `json:"llm"` PackageAPI PackageAPIConfig `json:"package_api"` Verify VerifyConfig `json:"verify"` WeatherAPI WeatherAPIConfig `json:"weather_api"` CacheDir string `json:"cache_dir"` LogLevel string `json:"log_level"` // "info" or "verbose" } // ServerConfig contains server configuration type ServerConfig struct { Port string `json:"port"` } // LLMConfig contains configuration for LLM provider type LLMConfig struct { Provider string `json:"provider"` // "openrouter" or "lmstudio" Model string `json:"model"` APIKey string `json:"api_key,omitempty"` // For OpenRouter BaseURL string `json:"base_url,omitempty"` // For LM Studio } // PackageAPIConfig contains configuration for package API type PackageAPIConfig struct { BaseURL string `json:"base_url"` APIKey string `json:"api_key"` } // VerifyConfig contains configuration for verify endpoint type VerifyConfig struct { URL string `json:"url"` TunnelURL string `json:"tunnel_url"` APIKey string `json:"api_key"` } // WeatherAPIConfig contains configuration for weather API type WeatherAPIConfig struct { BaseURL string `json:"base_url"` APIKey string `json:"api_key"` } // Load loads configuration from a JSON file func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading config file: %w", err) } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("parsing config file: %w", err) } return &cfg, nil } // Validate validates the configuration func (c *Config) Validate() error { if c.Server.Port == "" { return fmt.Errorf("server.port is required") } if c.LLM.Provider == "" { return fmt.Errorf("llm.provider is required") } if c.LLM.Provider != "openrouter" && c.LLM.Provider != "lmstudio" { return fmt.Errorf("llm.provider must be 'openrouter' or 'lmstudio'") } if c.LLM.Model == "" { return fmt.Errorf("llm.model is required") } if c.LLM.Provider == "openrouter" && c.LLM.APIKey == "" { return fmt.Errorf("llm.api_key is required for openrouter provider") } if c.LLM.Provider == "lmstudio" && c.LLM.BaseURL == "" { return fmt.Errorf("llm.base_url is required for lmstudio provider") } if c.PackageAPI.BaseURL == "" { return fmt.Errorf("package_api.base_url is required") } if c.PackageAPI.APIKey == "" { return fmt.Errorf("package_api.api_key is required") } if c.CacheDir == "" { return fmt.Errorf("cache_dir is required") } if c.Verify.URL == "" { return fmt.Errorf("verify.url is required") } if c.Verify.TunnelURL == "" { return fmt.Errorf("verify.tunnel_url is required") } if c.Verify.APIKey == "" { return fmt.Errorf("verify.api_key is required") } // Weather API is optional if c.WeatherAPI.BaseURL == "" { c.WeatherAPI.BaseURL = "https://api.openweathermap.org/data/2.5" } // Set default log level if not specified if c.LogLevel == "" { c.LogLevel = "info" } // Validate log level if c.LogLevel != "info" && c.LogLevel != "verbose" { return fmt.Errorf("log_level must be 'info' or 'verbose'") } return nil } // IsVerbose returns true if verbose logging is enabled func (c *Config) IsVerbose() bool { return c.LogLevel == "verbose" }