Skip to content

feat(stt): make decode language a first-class config.toml key - #22

Merged
vr000m merged 5 commits into
mainfrom
feat/stt-language-config
Jun 13, 2026
Merged

feat(stt): make decode language a first-class config.toml key#22
vr000m merged 5 commits into
mainfrom
feat/stt-language-config

Conversation

@vr000m

@vr000m vr000m commented Jun 12, 2026

Copy link
Copy Markdown
Owner

What

[stt] language in config.toml is now the source of truth for the STT decode language, resolved through the shared ConfigStore (env STT_LANGUAGE (legacy alias STT_WS_LANGUAGE) > [stt].language > "en"), so every launch path — CLI, menu-bar app, onoats init — picks it up. Previously the websocket branch read os.environ directly and the local whisper/MLX branches hardcoded "en".

How

  • OnoatsConfig.stt_language: new property, same env-over-file-over-default precedence as the other [stt] keys; strip-then-default so a whitespace-only file value falls back to en rather than reaching a backend as language="".
  • runtime._resolve_stt_language(cfg): maps auto (any case) to None at the backend boundary — whisper/mlx rejects a literal "auto" and uses None for built-in detection; nemotron maps client-None to its own auto language-ID. Resolved once so the websocket and local whisper branches cannot drift.
  • All three STT branches consume it: websocket (update_session), whisper-MLX, whisper-CPU. Deepgram does not (not wired; documented).
  • onoats init prompts for the language in the local-STT branch and writes the key. Non-interactive re-runs carry an existing language forward (like service/model/ws_socket), and switching to Deepgram in the wizard preserves it for a later switch back.
  • Startup banner logs the effective language for the local branches.

Review fixes (second commit)

In-session review found and fixed three issues:

  1. whitespace-only [stt].language resolved to "" (dropped the old inline or "en" guard) — restored, test-pinned.
  2. non-interactive onoats init re-runs silently erased a configured language from the rebuilt [stt] table — now carried like the other keys, pinned by the idempotent-rerun test.
  3. interactive switch to Deepgram dropped the key — now carried forward.

Verification

  • 265 tests pass (uv run pytest); ruff format + check clean.
  • Tests pin: default en, toml value, env-over-toml, whitespace fallback, autoNone (case-insensitive), Settings(language=None) accepted by pinned pipecat, init writes language = "auto", re-run preservation.
  • Invariant checked across call sites: rg 'language="en"|STT_WS_LANGUAGE' src/onoats shows only the single resolution point in the config property.

Known gap (deliberate): no --stt-language flag for non-interactive onoats init — config.toml or env covers automation; add the flag only if a driver needs it.

Full pre-merge battery complete: in-session review + Codex adversarial (converged, fixes in 5a44097), /update-docs (changelog synced in a53dd11), /security-review (no findings), /deep-review (env-var rename in 4723bbd; two Minor architecture notes triaged as wont-fix candidates).

vr000m added 5 commits June 12, 2026 14:42
[stt] language (env STT_WS_LANGUAGE > config.toml > "en") now feeds all
three launch paths through the shared ConfigStore instead of a raw
os.environ read in the websocket branch only. "auto" maps to None at
the backend boundary (_resolve_stt_language) — whisper/mlx rejects the
literal string. The local whisper/MLX branches honour it too (previously
hardcoded "en"); Deepgram does not consume it. onoats init prompts for
the language in the local STT branch and writes the key.
Review findings on the language-config feature:
- whitespace-only [stt].language fell through as language="" — restore
  the strip-then-default guard the old inline code had (env values were
  already strip-guarded inside _env_or).
- non-interactive init re-runs rebuilt the [stt] table without language,
  silently erasing a configured value (service/model/ws_socket carried,
  language did not). Carry it like the others; idempotent-rerun test now
  pins it.
- switching to Deepgram in the wizard dropped the key — carry it forward
  so switching backends and back keeps the preference.
… alias

Deep-review architecture finding: the env var now governs every STT
backend, not just the websocket one, so the bare name matches the other
cross-backend vars (STT_SERVICE / STT_MODEL). STT_WS_LANGUAGE stays as
a lower-precedence alias for backward compatibility. Resolution:
STT_LANGUAGE > STT_WS_LANGUAGE > [stt].language > "en".
@vr000m
vr000m merged commit 69f0868 into main Jun 13, 2026
1 check passed
@vr000m
vr000m deleted the feat/stt-language-config branch June 13, 2026 01:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant