feat(voice): per-account choice between Whisper and the browser; STT_ALLOW_BROWSER
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m40s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-01 15:19:20 +01:00
1 parent 55112b940c
commit a927a94a95
21 files changed
+288 -15

No files matched your search

+4
View File
@@ -86,6 +86,7 @@ type SpeechConfig struct {
Language string
APIKey string
Disabled bool // STT_DISABLED=true hides voice input everywhere
NoBrowser bool // STT_ALLOW_BROWSER=false forbids the browser's recognition (it sends audio to Google/Microsoft)
MaxSeconds int // recordings stop after this long (enforced in the browser)
MaxUploadMB int
MaxParallel int // transcriptions running at the same time; more wait in line
@@ -102,6 +103,8 @@ func (s SpeechConfig) Mode(demo bool) string {
return "off"
case s.URL != "" && !demo:
return "server"
case s.NoBrowser:
return "off"
default:
return "browser"
}
@@ -266,6 +269,7 @@ func Load() *Config {
Language: getEnv("STT_LANGUAGE", "de"),
APIKey: getEnv("STT_API_KEY", ""),
Disabled: strings.ToLower(getEnv("STT_DISABLED", "false")) == "true",
NoBrowser: strings.ToLower(getEnv("STT_ALLOW_BROWSER", "true")) == "false",
MaxSeconds: envInt("STT_MAX_SECONDS", 600, 5, 3600),
MaxUploadMB: envInt("STT_MAX_UPLOAD_MB", 25, 1, 500),
MaxParallel: envInt("STT_MAX_PARALLEL", 1, 1, 32),
+21
View File
@@ -120,3 +120,24 @@ func TestCustomLinkValidation(t *testing.T) {
t.Errorf("expected empty custom link when url is empty, got url=%q label=%q", cfg.Legal.CustomLinkURL, cfg.Legal.CustomLinkLabel)
}
}
// STT_ALLOW_BROWSER=false: without a Whisper server (or in the demo) there is no voice input at all
func TestSpeechModeWithoutBrowser(t *testing.T) {
cases := []struct {
cfg SpeechConfig
demo bool
want string
}{
{SpeechConfig{URL: "http://whisper:8000"}, false, "server"},
{SpeechConfig{URL: "http://whisper:8000", NoBrowser: true}, false, "server"},
{SpeechConfig{}, false, "browser"},
{SpeechConfig{NoBrowser: true}, false, "off"},
{SpeechConfig{URL: "http://whisper:8000", NoBrowser: true}, true, "off"},
{SpeechConfig{URL: "http://whisper:8000", Disabled: true}, false, "off"},
}
for _, c := range cases {
if got := c.cfg.Mode(c.demo); got != c.want {
t.Errorf("%+v demo=%v: got %q, want %q", c.cfg, c.demo, got, c.want)
}
}
}