// Package config provides configuration management for the CLI Proxy API server. // It handles loading and parsing YAML configuration files, and provides structured // access to application settings including server port, authentication directory, // debug settings, proxy configuration, and API keys. package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) // Config represents the application's configuration, loaded from a YAML file. type Config struct { // Port is the network port on which the API server will listen. Port int `yaml:"port"` // AuthDir is the directory where authentication token files are stored. AuthDir string `yaml:"auth-dir"` // Debug enables or disables debug-level logging and other debug features. Debug bool `yaml:"debug"` // ProxyURL is the URL of an optional proxy server to use for outbound requests. ProxyURL string `yaml:"proxy-url"` // APIKeys is a list of keys for authenticating clients to this proxy server. APIKeys []string `yaml:"api-keys"` // QuotaExceeded defines the behavior when a quota is exceeded. QuotaExceeded QuotaExceeded `yaml:"quota-exceeded"` // GlAPIKey is the API key for the generative language API. GlAPIKey []string `yaml:"generative-language-api-key"` // RequestLog enables or disables detailed request logging functionality. RequestLog bool `yaml:"request-log"` // RequestRetry defines the retry times when the request failed. RequestRetry int `yaml:"request-retry"` // ClaudeKey defines a list of Claude API key configurations as specified in the YAML configuration file. ClaudeKey []ClaudeKey `yaml:"claude-api-key"` // OpenAICompatibility defines OpenAI API compatibility configurations for external providers. OpenAICompatibility []OpenAICompatibility `yaml:"openai-compatibility"` // AllowLocalhostUnauthenticated allows unauthenticated requests from localhost. AllowLocalhostUnauthenticated bool `yaml:"allow-localhost-unauthenticated"` } // QuotaExceeded defines the behavior when API quota limits are exceeded. // It provides configuration options for automatic failover mechanisms. type QuotaExceeded struct { // SwitchProject indicates whether to automatically switch to another project when a quota is exceeded. SwitchProject bool `yaml:"switch-project"` // SwitchPreviewModel indicates whether to automatically switch to a preview model when a quota is exceeded. SwitchPreviewModel bool `yaml:"switch-preview-model"` } // ClaudeKey represents the configuration for a Claude API key, // including the API key itself and an optional base URL for the API endpoint. type ClaudeKey struct { // APIKey is the authentication key for accessing Claude API services. APIKey string `yaml:"api-key"` // BaseURL is the base URL for the Claude API endpoint. // If empty, the default Claude API URL will be used. BaseURL string `yaml:"base-url"` } // OpenAICompatibility represents the configuration for OpenAI API compatibility // with external providers, allowing model aliases to be routed through OpenAI API format. type OpenAICompatibility struct { // Name is the identifier for this OpenAI compatibility configuration. Name string `yaml:"name"` // BaseURL is the base URL for the external OpenAI-compatible API endpoint. BaseURL string `yaml:"base-url"` // APIKeys are the authentication keys for accessing the external API services. APIKeys []string `yaml:"api-keys"` // Models defines the model configurations including aliases for routing. Models []OpenAICompatibilityModel `yaml:"models"` } // OpenAICompatibilityModel represents a model configuration for OpenAI compatibility, // including the actual model name and its alias for API routing. type OpenAICompatibilityModel struct { // Name is the actual model name used by the external provider. Name string `yaml:"name"` // Alias is the model name alias that clients will use to reference this model. Alias string `yaml:"alias"` } // LoadConfig reads a YAML configuration file from the given path, // unmarshals it into a Config struct, applies environment variable overrides, // and returns it. // // Parameters: // - configFile: The path to the YAML configuration file // // Returns: // - *Config: The loaded configuration // - error: An error if the configuration could not be loaded func LoadConfig(configFile string) (*Config, error) { // Read the entire configuration file into memory. data, err := os.ReadFile(configFile) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } // Unmarshal the YAML data into the Config struct. var config Config if err = yaml.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } // Return the populated configuration struct. return &config, nil }