feat(config): add environment-based configuration with std lib

This commit is contained in:
2026-06-10 00:48:37 +03:30
parent cdc699d00b
commit ec4c3a91b3

151
internal/config/config.go Normal file
View File

@@ -0,0 +1,151 @@
package config
import (
"fmt"
"os"
"strconv"
"time"
)
type Config struct {
// llama.cpp server
LlamaCppURL string
Model string
SystemPrompt string
Temperature float64
TopP float64
MaxTokens int
ContextSize int
// SQLite
DBPath string
CompanionDB string
// Matrix
MatrixEnabled bool
MatrixHomeserver string
MatrixUser string
MatrixToken string
// Scheduler
SchedulerInterval time.Duration
AutoDiary bool
DiaryHour int
// Memory
MemoryTopK int
MemoryMinScore float64
// Embedding
EmbeddingModel string
// Personality
TraitChangeMaxDaily float64
TraitChangeMaxMonthly float64
// Logging
LogLevel string
// API
APIEnabled bool
APIPort string
}
func Load() *Config {
return &Config{
LlamaCppURL: getEnv("LLAMACPP_URL", "http://localhost:8080"),
Model: getEnv("MODEL_NAME", ""),
SystemPrompt: getEnv("SYSTEM_PROMPT", "You are Diva, a curious and thoughtful AI companion."),
Temperature: getEnvFloat("TEMPERATURE", 0.85),
TopP: getEnvFloat("TOP_P", 0.9),
MaxTokens: getEnvInt("MAX_TOKENS", 2048),
ContextSize: getEnvInt("CONTEXT_SIZE", 8192),
DBPath: getEnv("DB_PATH", "./data/divacode.db"),
CompanionDB: getEnv("COMPANION_DB_PATH", "./data/companion.db"),
MatrixEnabled: getEnvBool("MATRIX_ENABLED", false),
MatrixHomeserver: getEnv("MATRIX_HOMESERVER", ""),
MatrixUser: getEnv("MATRIX_USER", ""),
MatrixToken: getEnv("MATRIX_TOKEN", ""),
SchedulerInterval: getEnvDuration("SCHEDULER_INTERVAL", 15*time.Minute),
AutoDiary: getEnvBool("AUTO_DIARY", true),
DiaryHour: getEnvInt("DIARY_HOUR", 23),
MemoryTopK: getEnvInt("MEMORY_TOP_K", 5),
MemoryMinScore: getEnvFloat("MEMORY_MIN_SCORE", 0.6),
EmbeddingModel: getEnv("EMBEDDING_MODEL", ""),
TraitChangeMaxDaily: getEnvFloat("TRAIT_CHANGE_MAX_DAILY", 0.005),
TraitChangeMaxMonthly: getEnvFloat("TRAIT_CHANGE_MAX_MONTHLY", 0.05),
LogLevel: getEnv("LOG_LEVEL", "INFO"),
APIEnabled: getEnvBool("API_ENABLED", false),
APIPort: getEnv("API_PORT", "8080"),
}
}
func (c *Config) Validate() error {
if c.LlamaCppURL == "" {
return fmt.Errorf("LLAMACPP_URL is required")
}
if c.DBPath == "" {
return fmt.Errorf("DB_PATH is required")
}
if c.CompanionDB == "" {
return fmt.Errorf("COMPANION_DB_PATH is required")
}
if c.SystemPrompt == "" {
return fmt.Errorf("SYSTEM_PROMPT is required")
}
if c.DiaryHour < 0 || c.DiaryHour > 23 {
return fmt.Errorf("DIARY_HOUR must be 0-23")
}
return nil
}
func getEnv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}
func getEnvInt(key string, fallback int) int {
if v := os.Getenv(key); v != "" {
if n, err := strconv.Atoi(v); err == nil {
return n
}
}
return fallback
}
func getEnvFloat(key string, fallback float64) float64 {
if v := os.Getenv(key); v != "" {
if f, err := strconv.ParseFloat(v, 64); err == nil {
return f
}
}
return fallback
}
func getEnvBool(key string, fallback bool) bool {
if v := os.Getenv(key); v != "" {
if b, err := strconv.ParseBool(v); err == nil {
return b
}
}
return fallback
}
func getEnvDuration(key string, fallback time.Duration) time.Duration {
if v := os.Getenv(key); v != "" {
if d, err := time.ParseDuration(v); err == nil {
return d
}
}
return fallback
}