nub/internal/config/resolve.go
Tom a97013d876 initial commit
- v 0.1.0 siehe CHANGELOG.md
2026-07-25 11:08:01 +02:00

62 lines
1.5 KiB
Go

package config
import (
"fmt"
"os"
"strings"
"nub/internal/llm"
"nub/internal/llm/registry"
)
// Resolved ist alles, was der OpenAI-Adapter zum Verbindungsaufbau braucht.
type Resolved struct {
Model string
BaseURL string
APIKey string
Caps llm.Caps
}
// Resolve löst den in Model.Endpoint referenzierten Endpoint auf, ermittelt
// den API-Key (inkl. "env:VAR"-Indirektion) und merged Caps aus der
// Modell-Registry (E-10) mit den Endpoint-Overrides.
func Resolve(cfg Config) (Resolved, error) {
var ep *Endpoint
for i := range cfg.Endpoints {
if cfg.Endpoints[i].Name == cfg.Model.Endpoint {
ep = &cfg.Endpoints[i]
break
}
}
if ep == nil {
return Resolved{}, fmt.Errorf("config: model.endpoint %q referenziert keinen konfigurierten [[endpoint]]", cfg.Model.Endpoint)
}
key := resolveAPIKey(ep.APIKey)
if key == "" && !isLocalEndpoint(ep.BaseURL) {
return Resolved{}, fmt.Errorf("config: kein API-Key für Endpoint %q — in der Config setzen oder NUB_API_KEY/OPENAI_API_KEY exportieren", ep.Name)
}
caps := registry.Apply(registry.DefaultCaps(cfg.Model.Default), ep.Caps)
return Resolved{
Model: cfg.Model.Default,
BaseURL: ep.BaseURL,
APIKey: key,
Caps: caps,
}, nil
}
func resolveAPIKey(v string) string {
if rest, ok := strings.CutPrefix(v, "env:"); ok {
return os.Getenv(rest)
}
if v == "none" {
return ""
}
return v
}
func isLocalEndpoint(baseURL string) bool {
return strings.HasPrefix(baseURL, "http://")
}