feat(stt): default global stt.language to 'en'

Whisper auto-detection frequently misidentifies short/accented clips,
which users experience as voice notes transcribed in the wrong language
(Teknium + CTO both hit this). The unified resolver from #73067 made a
global hint possible; this makes it the DEFAULT so stock installs stop
guessing. Non-English users set stt.language once; '' restores
auto-detect for multilingual use.

Deep-merge gives existing configs the new default automatically (no
_config_version bump needed); any explicit per-provider or global
language setting still wins.
This commit is contained in:
Teknium 2026-07-27 20:41:10 -07:00
parent 3af7b867fd
commit bc997a36a8
4 changed files with 41 additions and 5 deletions

View file

@ -1128,7 +1128,7 @@ stt:
model: "base" # tiny | base | small | medium | large-v3 | turbo
# language: "" # auto-detect; set to "en", "es", "fr", etc. to force
# initial_prompt: "" # Optional faster-whisper prompt, e.g. bias Chinese output to simplified Chinese
# language: "" # GLOBAL language hint for every STT provider (per-provider language wins)
language: "en" # GLOBAL language hint for every STT provider (per-provider language wins). Set "" for auto-detect.
# groq:
# model: "whisper-large-v3-turbo"
# language: "" # blank = stt.language > HERMES_LOCAL_STT_LANGUAGE > auto-detect

View file

@ -2323,8 +2323,11 @@ DEFAULT_CONFIG = {
"echo_transcripts": True,
"provider": "local", # "local" (free, faster-whisper) | "groq" | "openai" (Whisper API) | "mistral" (Voxtral Transcribe) | "elevenlabs" (Scribe) | "deepinfra"
# Global language hint applied to EVERY provider unless a per-provider
# language overrides it. Empty = auto-detect. ISO-639-1 ("en", "es", ...).
"language": "",
# language overrides it. Defaults to "en" — Whisper auto-detection
# frequently misidentifies short/accented clips, which reads as
# "STT transcribed the wrong language". Set to "" to restore
# auto-detect, or to your language code ("es", "zh", "uk", ...).
"language": "en",
"local": {
"model": "base", # tiny, base, small, medium, large-v3
"language": "", # auto-detect by default; set to "en", "es", "fr", etc. to force

View file

@ -0,0 +1,33 @@
"""Default STT language contract.
Teknium (July 2026): the global ``stt.language`` DEFAULTS to "en" because
Whisper auto-detection frequently misidentifies short/accented clips
("STT transcribed the wrong language" class). Users opt back into
auto-detect with ``stt.language: ""``.
"""
from hermes_cli.config import DEFAULT_CONFIG
from tools.transcription_tools import _resolve_stt_language
class TestDefaultSttLanguage:
def test_default_config_pins_english(self):
assert DEFAULT_CONFIG["stt"]["language"] == "en"
def test_default_config_resolves_en_for_every_provider(self, monkeypatch):
monkeypatch.delenv("HERMES_LOCAL_STT_LANGUAGE", raising=False)
stt = DEFAULT_CONFIG["stt"]
for provider in ("local", "groq", "openai", "mistral", "xai", "elevenlabs", "deepinfra"):
assert _resolve_stt_language(provider, stt) == "en", provider
def test_blank_global_restores_auto_detect(self, monkeypatch):
monkeypatch.delenv("HERMES_LOCAL_STT_LANGUAGE", raising=False)
stt = dict(DEFAULT_CONFIG["stt"])
stt["language"] = ""
assert _resolve_stt_language("groq", stt) is None
def test_per_provider_still_wins_over_default(self, monkeypatch):
monkeypatch.delenv("HERMES_LOCAL_STT_LANGUAGE", raising=False)
stt = dict(DEFAULT_CONFIG["stt"])
stt["groq"] = {"language": "he"}
assert _resolve_stt_language("groq", stt) == "he"

View file

@ -1713,7 +1713,7 @@ stt:
enabled: true # Auto-transcribe inbound voice messages (default: true)
echo_transcripts: true # Post raw transcripts back to the chat as 🎙️ "..." (default: true)
provider: "local" # "local" | "groq" | "openai" | "mistral"
language: "" # GLOBAL language hint for every provider (ISO-639-1, e.g. "en", "he", "uk"); blank = auto-detect
language: "en" # GLOBAL language hint for every provider (per-provider language wins); set "" for auto-detect
local:
model: "base" # tiny, base, small, medium, large-v3
language: "" # per-provider override of stt.language
@ -1726,7 +1726,7 @@ stt:
# model: "whisper-1" # Legacy fallback key still respected
```
Language resolution is the same for **every** STT provider (local, groq, openai, mistral, xai, elevenlabs, deepinfra, command providers, and plugins): `stt.<provider>.language``stt.language``HERMES_LOCAL_STT_LANGUAGE` env var → provider auto-detect. Setting `stt.language` once fixes the common "my voice notes get transcribed in the wrong language" problem regardless of which provider is active.
Language resolution is the same for **every** STT provider (local, groq, openai, mistral, xai, elevenlabs, deepinfra, command providers, and plugins): `stt.<provider>.language``stt.language``HERMES_LOCAL_STT_LANGUAGE` env var → provider auto-detect. **The default is `stt.language: "en"`** — Whisper auto-detection frequently misidentifies short or accented clips, which shows up as voice notes transcribed in the wrong language. Non-English speakers should set `stt.language` to their language code once (e.g. `"es"`, `"zh"`, `"uk"`); set it to `""` to restore auto-detection for multilingual use.
Set `stt.echo_transcripts: false` when the gateway should transcribe voice notes for the agent but must not post the raw transcript back to the chat (for example, customer-facing WhatsApp bots).