Documentation
¶
Index ¶
- Constants
- Variables
- func BackupConfig(path string) (string, error)
- func DataDir() (string, error)
- func DefaultConfigPath(flagPath string) (string, error)
- func EnsureDataDir() (string, error)
- func PruneBackups(path string, keep int) error
- func RestoreConfig(path, name string) error
- func SplitProviderModel(value, defaultProvider string) (string, string)
- func ValidFormat(f string) bool
- func WriteConfig(path string, cfg *Config) error
- type BackupInfo
- type Config
- type Provider
- type ProviderConfig
- type ProviderPreset
- type RouteRule
- type ServerConfig
- type Severity
- type ValidationIssue
- type ValidationResult
Constants ¶
const ( DefaultHost = "127.0.0.1" DefaultPort = 12345 DataDirName = ".ai-switch" UsageDBName = "usage.db" ConfigFile = "config.yaml" PidFileName = "ai-switch.pid" DefaultLogRetentionDays = 30 )
const DefaultBackupKeep = 10
DefaultBackupKeep is the default number of timestamped backups to retain.
Variables ¶
var ProviderPresets []ProviderPreset
Functions ¶
func BackupConfig ¶ added in v0.1.17
BackupConfig copies the current file at path to a timestamped backup. Returns the absolute path of the new backup, or "" if the source does not exist (first-time write). Returns an error only on real I/O failures.
The copy uses io.Copy — never os.Rename — because:
- We want to *create a new* timestamped file, not move the existing one.
- os.Rename to an existing destination fails on Windows.
- io.Copy works identically on Linux, macOS, and Windows.
The backup filename includes nanosecond resolution and is created with O_EXCL — if a file with the same name already exists (extremely unlikely given nanosecond resolution, but possible on a clock with sub-nanosecond resolution or non-monotonic sources), we retry up to 3 times with a fresh timestamp before giving up.
The source is read fully into memory so the retry loop can copy from the same byte slice each attempt. Config files are small (KB), so this is preferable to seeking or re-opening the source.
func DefaultConfigPath ¶
DefaultConfigPath returns the config file path following the priority: 1. provided path (from -c flag) 2. ~/.ai-switch/config.yaml
func EnsureDataDir ¶
EnsureDataDir creates the data directory if it does not exist.
func PruneBackups ¶ added in v0.1.17
PruneBackups keeps at most keep timestamped backups for path, deleting the oldest. keep must be >= 0. keep == 0 deletes all backups. Errors deleting individual files are logged but do not abort the prune.
func RestoreConfig ¶ added in v0.1.17
RestoreConfig copies the named backup back to path. The name must be a basename returned by ListBackups — any other value is rejected to prevent path traversal.
func SplitProviderModel ¶
SplitProviderModel splits "provider|model" format. Plain names use defaultProvider.
func ValidFormat ¶
func WriteConfig ¶
WriteConfig marshals the config and writes it to the given file path atomically. Before the atomic rename, the existing file (if any) is copied to a timestamped backup via BackupConfig. A backup failure is logged but does not block the write — atomicity of the new config is more important than preservation of the backup. On a successful write, PruneBackups is called to keep at most DefaultBackupKeep backups.
Types ¶
type BackupInfo ¶ added in v0.1.17
type BackupInfo struct {
Name string `json:"name"` // basename, e.g. "config.yaml.bak.20260601-143052.123456789"
Path string `json:"path"` // absolute path
Size int64 `json:"size"`
ModTime time.Time `json:"mod_time"`
}
BackupInfo describes a single timestamped backup file.
func ListBackups ¶ added in v0.1.17
func ListBackups(path string) ([]BackupInfo, error)
ListBackups returns all timestamped backups of path, sorted newest-first. Returns an empty slice (not nil) when no backups exist.
type Config ¶
type Config struct {
Server ServerConfig `mapstructure:"server" yaml:"server"`
LogRetentionDays int `mapstructure:"log_retention_days" yaml:"log_retention_days,omitempty"`
DefaultRoute string `mapstructure:"default_route" yaml:"default_route,omitempty"`
DefaultAnthropicRoute string `mapstructure:"default_anthropic_route" yaml:"default_anthropic_route,omitempty"`
DefaultResponsesRoute string `mapstructure:"default_responses_route" yaml:"default_responses_route,omitempty"`
DefaultChatRoute string `mapstructure:"default_chat_route" yaml:"default_chat_route,omitempty"`
Providers map[string]ProviderConfig `mapstructure:"providers" yaml:"providers"`
Routes map[string]RouteRule `mapstructure:"routes" yaml:"routes"`
}
func (*Config) DefaultRouteConfig ¶
DefaultRouteConfig returns the default route rule for the given protocol, falling back to the global default_route. Returns nil if none configured.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider holds the current configuration with thread-safe access.
func NewProvider ¶
NewProvider creates a new config provider with the initial config.
type ProviderConfig ¶
type ProviderConfig struct {
Name string `mapstructure:"name" yaml:"name"`
BaseURL string `mapstructure:"base_url" yaml:"base_url"`
Path string `mapstructure:"path" yaml:"path"`
APIKey string `mapstructure:"api_key" yaml:"api_key"`
FallbackKeys []string `mapstructure:"fallback_keys" yaml:"fallback_keys,omitempty"`
Format string `mapstructure:"format" yaml:"format"`
LogoURL string `mapstructure:"logo_url" yaml:"logo_url"`
ThinkTag string `mapstructure:"think_tag" yaml:"think_tag,omitempty"`
Models []string `mapstructure:"models" yaml:"models,omitempty"`
EnableProxy bool `mapstructure:"enable_proxy" yaml:"enable_proxy,omitempty"`
}
type ProviderPreset ¶
type ProviderPreset struct {
Key string `json:"key" yaml:"key"`
Name string `json:"name" yaml:"name"`
BaseURL string `json:"base_url" yaml:"base_url"`
Format string `json:"format" yaml:"format"`
Icon string `json:"icon" yaml:"icon"`
IconColor string `json:"icon_color" yaml:"icon_color"`
Category string `json:"category" yaml:"category"`
APIKeyURL string `json:"api_key_url" yaml:"api_key_url"`
IsPartner bool `json:"is_partner" yaml:"is_partner"`
}
type RouteRule ¶
type RouteRule struct {
Provider string `mapstructure:"provider" yaml:"provider"`
DefaultModel string `mapstructure:"default_model" yaml:"default_model"`
Disabled bool `mapstructure:"disabled" yaml:"disabled,omitempty"`
SceneMap map[string]string `mapstructure:"scene_map" yaml:"scene_map"`
ModelMap map[string]string `mapstructure:"model_map" yaml:"model_map"`
LongContextThreshold int `mapstructure:"long_context_threshold" yaml:"long_context_threshold,omitempty"`
}
type ServerConfig ¶
type ServerConfig struct {
Host string `mapstructure:"host" yaml:"host"`
Port int `mapstructure:"port" yaml:"port"`
AllowedIPs []string `mapstructure:"allowed_ips" yaml:"allowed_ips,omitempty"`
ProxyURL string `mapstructure:"proxy_url" yaml:"proxy_url,omitempty"`
}
func (ServerConfig) IsLocalhost ¶ added in v0.1.13
func (s ServerConfig) IsLocalhost() bool
IsLocalhost returns true if the host is 127.0.0.1 or localhost.
type ValidationIssue ¶
type ValidationResult ¶
type ValidationResult struct {
Errors []ValidationIssue
Warnings []ValidationIssue
}
func Validate ¶
func Validate(cfg *Config) *ValidationResult
func (*ValidationResult) ErrorMessages ¶
func (r *ValidationResult) ErrorMessages() []string
func (*ValidationResult) HasErrors ¶
func (r *ValidationResult) HasErrors() bool
func (*ValidationResult) HasOnlyWarnings ¶
func (r *ValidationResult) HasOnlyWarnings() bool
func (*ValidationResult) WarningMessages ¶
func (r *ValidationResult) WarningMessages() []string