117 lines
2.4 KiB
Go
117 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
type ProviderConfig struct {
|
|
Name string `json:"name,omitempty"`
|
|
BaseURL string `json:"base_url"`
|
|
APIKey string `json:"api_key,omitempty"`
|
|
Type string `json:"type,omitempty"`
|
|
}
|
|
|
|
type Config struct {
|
|
Theme string `json:"theme,omitempty"`
|
|
DefaultProvider string `json:"default_provider,omitempty"`
|
|
Providers map[string]ProviderConfig `json:"providers,omitempty"`
|
|
}
|
|
|
|
func configDir() string {
|
|
dir := os.Getenv("XDG_CONFIG_HOME")
|
|
if dir == "" {
|
|
home, _ := os.UserHomeDir()
|
|
dir = filepath.Join(home, ".config")
|
|
}
|
|
return filepath.Join(dir, "ludmila-ai-tui")
|
|
}
|
|
|
|
func configPath() string {
|
|
return filepath.Join(configDir(), "config.json")
|
|
}
|
|
|
|
func themesDir() string {
|
|
return filepath.Join(configDir(), "themes")
|
|
}
|
|
|
|
var defaultProviders = map[string]ProviderConfig{
|
|
"Mathink": {
|
|
Name: "Mathink (FLM)",
|
|
BaseURL: "http://localhost:52625",
|
|
Type: "openai-compat",
|
|
},
|
|
}
|
|
|
|
func ensureConfigDir() error {
|
|
dir := configDir()
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return fmt.Errorf("create config dir %s: %w", dir, err)
|
|
}
|
|
if err := os.MkdirAll(themesDir(), 0o755); err != nil {
|
|
return fmt.Errorf("create themes dir: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func LoadConfig() (*Config, error) {
|
|
cfg := &Config{
|
|
Theme: "system",
|
|
Providers: defaultProviders,
|
|
}
|
|
|
|
path := configPath()
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
if mkErr := ensureConfigDir(); mkErr != nil {
|
|
return cfg, fmt.Errorf("ensure config dir: %w", mkErr)
|
|
}
|
|
defaultJSON, _ := json.MarshalIndent(cfg, "", " ")
|
|
_ = os.WriteFile(path, defaultJSON, 0o644)
|
|
return cfg, nil
|
|
}
|
|
return cfg, fmt.Errorf("read config %s: %w", path, err)
|
|
}
|
|
|
|
if err := json.Unmarshal(data, cfg); err != nil {
|
|
return cfg, fmt.Errorf("parse config %s: %w", path, err)
|
|
}
|
|
|
|
if cfg.Theme == "" {
|
|
cfg.Theme = "system"
|
|
}
|
|
|
|
if cfg.Providers == nil || len(cfg.Providers) == 0 {
|
|
cfg.Providers = defaultProviders
|
|
}
|
|
|
|
for id, p := range cfg.Providers {
|
|
p.APIKey = os.ExpandEnv(p.APIKey)
|
|
if p.Type == "" {
|
|
p.Type = "openai-compat"
|
|
}
|
|
cfg.Providers[id] = p
|
|
}
|
|
|
|
var found bool
|
|
if cfg.DefaultProvider != "" {
|
|
for id := range cfg.Providers {
|
|
if id == cfg.DefaultProvider {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
for id := range cfg.Providers {
|
|
cfg.DefaultProvider = id
|
|
break
|
|
}
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|