feat(config): Daemon-Port server.port mit Env-Override TALK_PORT (Default 7800)
This commit is contained in:
1 parent
3b44605234
commit
716f6b2fc9
2 files changed
+94
-3
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
@@ -16,13 +17,21 @@ const (
|
||||
SinkNull = "null"
|
||||
)
|
||||
|
||||
// DefaultServerPort ist der Default-Port des Daemon-HTTP-Servers auf
|
||||
// 127.0.0.1 (Task-04-Brief: „Port Default 7800").
|
||||
const DefaultServerPort = 7800
|
||||
|
||||
// Config ist der effektiv geladene Konfigurations-Stand von talk. Task 02
|
||||
// führt audio.sink; Task 03 ergänzt den Provider-Pin, Provider-Endpunkte
|
||||
// und das Voice-Mapping; spätere Tasks ergänzen weitere Felder (server,
|
||||
// queue …), ohne die Auflösungsreihenfolge zu ändern.
|
||||
// und das Voice-Mapping; Task 04 den Daemon-Port (server.port, TALK_PORT);
|
||||
// spätere Tasks ergänzen weitere Felder (queue …), ohne die Auflösungs-
|
||||
// reihenfolge zu ändern.
|
||||
type Config struct {
|
||||
Audio Audio `toml:"audio"`
|
||||
|
||||
// Server steuert den Daemon-HTTP-Server (talkd) auf 127.0.0.1.
|
||||
Server Server `toml:"server"`
|
||||
|
||||
// Provider pinnt die Kette auf genau einen Provider (z. B.
|
||||
// `provider = "elevenlabs"`); leer = komplette Default-Kette
|
||||
// (elevenlabs → openai → edge → osbuiltin). Das CLI-Flag --provider
|
||||
@@ -48,6 +57,14 @@ type Audio struct {
|
||||
Sink string `toml:"sink"`
|
||||
}
|
||||
|
||||
// Server sind die Netz-Einstellungen des Daemons (nur Loopback; Binding
|
||||
// auf 127.0.0.1 macht cmd/talkd, die Config liefert nur den Port).
|
||||
type Server struct {
|
||||
// Port des Daemon-HTTP-Servers auf 127.0.0.1 — config
|
||||
// `[server] port = 7800`, Env-Override TALK_PORT, Default 7800.
|
||||
Port int `toml:"port"`
|
||||
}
|
||||
|
||||
// ProviderSettings sind die per Provider konfigurierbaren Endpunkte und
|
||||
// Modelle (TOML `[providers.<name>]`). Leer = eingebaute Defaults; die
|
||||
// Env-Overrides TALK_ELEVENLABS_ENDPOINT / TALK_OPENAI_ENDPOINT /
|
||||
@@ -62,7 +79,10 @@ type ProviderSettings struct {
|
||||
// Defaults liefert die eingebaute Default-Konfiguration (unterste Schicht
|
||||
// der Auflösung).
|
||||
func Defaults() Config {
|
||||
return Config{Audio: Audio{Sink: SinkOto}}
|
||||
return Config{
|
||||
Audio: Audio{Sink: SinkOto},
|
||||
Server: Server{Port: DefaultServerPort},
|
||||
}
|
||||
}
|
||||
|
||||
// Options steuert Load. Alle Felder sind injizierbar, damit die Unit-Tests
|
||||
@@ -116,6 +136,13 @@ func applyEnv(cfg Config, getenv func(string) string) (Config, error) {
|
||||
if v := getenv("TALK_PROVIDER"); v != "" {
|
||||
cfg.Provider = v
|
||||
}
|
||||
if v := getenv("TALK_PORT"); v != "" {
|
||||
port, err := strconv.Atoi(v)
|
||||
if err != nil || port < 1 || port > 65535 {
|
||||
return cfg, fmt.Errorf("TALK_PORT: ungültiger Wert %q (1–65535)", v)
|
||||
}
|
||||
cfg.Server.Port = port
|
||||
}
|
||||
switch cfg.Audio.Sink {
|
||||
case SinkOto, SinkNull:
|
||||
return cfg, nil
|
||||
|
||||
@@ -288,3 +288,67 @@ de = "de-DE-KatjaNeural"
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestLoadServerPort deckt die Task-04-Felder ab: Daemon-Port per Defaults
|
||||
// (7800), TOML [server] port, Env-Override TALK_PORT samt Validierung.
|
||||
func TestLoadServerPort(t *testing.T) {
|
||||
writeTOML := func(t *testing.T, content string) string {
|
||||
t.Helper()
|
||||
path := filepath.Join(t.TempDir(), "config.toml")
|
||||
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
t.Run("Default 7800", func(t *testing.T) {
|
||||
cfg, err := Load(Options{
|
||||
File: filepath.Join(t.TempDir(), "gibt-es-nicht.toml"),
|
||||
Getenv: env(nil),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
if cfg.Server.Port != DefaultServerPort {
|
||||
t.Errorf("Server.Port = %d, want Default %d", cfg.Server.Port, DefaultServerPort)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TOML überschreibt Default", func(t *testing.T) {
|
||||
cfg, err := Load(Options{
|
||||
File: writeTOML(t, "[server]\nport = 7999\n"),
|
||||
Getenv: env(nil),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
if cfg.Server.Port != 7999 {
|
||||
t.Errorf("Server.Port = %d, want 7999 aus TOML", cfg.Server.Port)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TALK_PORT schlägt Datei", func(t *testing.T) {
|
||||
cfg, err := Load(Options{
|
||||
File: writeTOML(t, "[server]\nport = 7999\n"),
|
||||
Getenv: env(map[string]string{"TALK_PORT": "7912"}),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
if cfg.Server.Port != 7912 {
|
||||
t.Errorf("Server.Port = %d, want Env-Override 7912", cfg.Server.Port)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ungültiger TALK_PORT-Wert ist klarer Fehler", func(t *testing.T) {
|
||||
for _, bad := range []string{"null", "0", "-1", "70000"} {
|
||||
_, err := Load(Options{
|
||||
File: filepath.Join(t.TempDir(), "gibt-es-nicht.toml"),
|
||||
Getenv: env(map[string]string{"TALK_PORT": bad}),
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "TALK_PORT") {
|
||||
t.Fatalf("TALK_PORT=%q: Fehler = %v, will klaren TALK_PORT-Fehler", bad, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user