114 lines
2.8 KiB
Go
114 lines
2.8 KiB
Go
package backend
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"strings"
|
|
|
|
"ollie/util"
|
|
)
|
|
|
|
// BackendConfig holds the per-backend configuration from backends.conf.
|
|
type BackendConfig struct {
|
|
Key string // API key / token
|
|
URL string // base URL override (empty = use backend's default)
|
|
Model string // default model override
|
|
CompactionModel string // model used for history compaction (empty = use Model)
|
|
Host string // for ollama: host address
|
|
}
|
|
|
|
// configFile is the parsed contents of backends.conf: section name → key/value pairs.
|
|
type configFile struct {
|
|
Default string // top-level "backend = ..." selects the default
|
|
Backends map[string]BackendConfig
|
|
}
|
|
|
|
// loadConfig reads ~/.config/ollie/backends.conf.
|
|
// Returns zero value if the file doesn't exist or is unreadable.
|
|
func loadConfig() configFile {
|
|
return parseConfigFile(util.CfgDir() + "/backends.conf")
|
|
}
|
|
|
|
// CompactionModel returns the configured compaction model for a backend.
|
|
// It falls back to that backend's configured default model when no dedicated
|
|
// compaction model is set.
|
|
func CompactionModel(name string) string {
|
|
cfg := loadConfig()
|
|
bc := cfg.Backends[name]
|
|
if bc.CompactionModel != "" {
|
|
return bc.CompactionModel
|
|
}
|
|
return bc.Model
|
|
}
|
|
|
|
// parseConfigFile parses an INI-style config file.
|
|
// Format:
|
|
//
|
|
// backend = openrouter (top-level: default backend selection)
|
|
//
|
|
// [section]
|
|
// key = value
|
|
//
|
|
// Lines starting with # are comments. Blank lines are ignored.
|
|
func parseConfigFile(path string) configFile {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return configFile{Backends: map[string]BackendConfig{}}
|
|
}
|
|
defer f.Close()
|
|
|
|
cfg := configFile{Backends: map[string]BackendConfig{}}
|
|
section := ""
|
|
|
|
sc := bufio.NewScanner(f)
|
|
for sc.Scan() {
|
|
line := strings.TrimSpace(sc.Text())
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
// Section header.
|
|
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
|
section = strings.TrimSpace(line[1 : len(line)-1])
|
|
if _, ok := cfg.Backends[section]; !ok {
|
|
cfg.Backends[section] = BackendConfig{}
|
|
}
|
|
continue
|
|
}
|
|
// Key = value.
|
|
k, v, ok := strings.Cut(line, "=")
|
|
if !ok {
|
|
continue
|
|
}
|
|
k = strings.TrimSpace(k)
|
|
v = strings.TrimSpace(v)
|
|
// Strip surrounding quotes.
|
|
if len(v) >= 2 && (v[0] == '"' && v[len(v)-1] == '"' || v[0] == '\'' && v[len(v)-1] == '\'') {
|
|
v = v[1 : len(v)-1]
|
|
}
|
|
|
|
// Top-level keys (before any section).
|
|
if section == "" {
|
|
if k == "backend" {
|
|
cfg.Default = v
|
|
}
|
|
continue
|
|
}
|
|
|
|
bc := cfg.Backends[section]
|
|
switch k {
|
|
case "key":
|
|
bc.Key = v
|
|
case "url":
|
|
bc.URL = v
|
|
case "model":
|
|
bc.Model = v
|
|
case "compactionModel", "compaction_model", "compaction-model":
|
|
bc.CompactionModel = v
|
|
case "host":
|
|
bc.Host = v
|
|
}
|
|
cfg.Backends[section] = bc
|
|
}
|
|
return cfg
|
|
}
|