feat(config): add environment-based configuration with std lib
This commit is contained in:
151
internal/config/config.go
Normal file
151
internal/config/config.go
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user