Skip to content

fix(stt): honor gateway preference over direct credentials - #84817

Closed
bgrablin wants to merge 2 commits into
NousResearch:mainfrom
bgrablin:fix/stt-respect-gateway-preference
Closed

bgrablin wants to merge 2 commits into
NousResearch:mainfrom
bgrablin:fix/stt-respect-gateway-preference

Conversation

@bgrablin

Copy link
Copy Markdown
Contributor

Summary

stt.use_gateway: true now selects the managed OpenAI audio gateway before every direct credential source. A configured OpenAI key, a local keyless endpoint, or an environment/credential-pool key can no longer silently bypass an explicit Nous Subscription selection.

Problem

Selecting Nous Subscription for Speech-to-Text writes:

stt:
  provider: openai
  use_gateway: true

The repository contract says this flag routes through Nous regardless of direct keys, and the STT provider picker declares VOICE_TOOLS_OPENAI_KEY and OPENAI_API_KEY as overridden. The runtime resolver did the opposite: it returned the first direct config, local endpoint, or key before attempting the gateway. Users could therefore select managed STT but still send transcription requests to, and be billed by, direct OpenAI.

Root cause

_resolve_openai_audio_client_config() used this order:

  1. stt.openai.api_key
  2. keyless local OpenAI-compatible endpoint
  3. scoped/environment/credential-pool key
  4. managed gateway fallback

It never consulted stt.use_gateway before accepting the direct paths.

Fix

  • Read the STT gateway preference before resolving credentials.
  • When enabled, skip all direct credential and local-endpoint paths.
  • Resolve openai-audio through the managed gateway first.
  • Fail closed with gateway-specific guidance when the selected gateway is unavailable; do not silently spend against a direct key.
  • Preserve the legacy direct-first order when use_gateway is false or absent.

This is separate from #79754: that PR covers permissive fallback for other tools when a gateway is unavailable and does not modify STT. This change enforces the existing explicit-routing contract for STT.

Validation

  • Added 5 regression cases covering:
    • config key present
    • keyless local endpoint present
    • environment/direct key present
    • real HERMES_HOME config propagation
    • gateway unavailable with direct credentials present
  • Affected suite: 42 passed.
  • Independent final-diff review: APPROVE; focused checks 9 passed; Ruff clean.
  • Live resolver probe with stt.use_gateway: true selected https://openai-audio-gateway.nousresearch.com/v1 while direct credentials remained configured.
  • Full repository suite: an earlier complete run reported unrelated environment/timing/dependency failures outside the changed files; the current-main replay is running in the Herdr verification pane. The observed 100 ms idle-timeout flake reproduces on unmodified main (1 failure in 5 baseline runs).
  • Platform: Linux, project venv.

Compatibility and risk

The behavior change is limited to an explicit stt.use_gateway: true opt-in. False/absent configurations retain the previous resolution order. No model-inference routing or non-STT provider behavior changes.

Infographic

STT gateway preference now wins over direct credentials, with fail-closed behavior when unavailable

Copilot AI lite review requested due to automatic review settings August 12, 2026 20:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes STT OpenAI audio client resolution so an explicit stt.use_gateway: true preference reliably routes transcription through the managed Nous OpenAI audio gateway rather than being bypassed by any direct credential source.

Changes:

  • Updates _resolve_openai_audio_client_config() to prioritize the managed openai-audio gateway when stt.use_gateway is enabled and to fail closed if the gateway cannot be resolved.
  • Preserves the legacy direct-first resolution order when stt.use_gateway is false/absent.
  • Adds regression tests covering gateway preference vs config key, local keyless endpoint, env/direct key, real config propagation, and gateway-unavailable behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tools/transcription_tools.py Reorders OpenAI audio config resolution to honor stt.use_gateway and fail closed when gateway is unavailable.
tests/tools/test_transcription_tools.py Adds regression coverage for gateway preference overriding direct STT credential paths and config propagation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tools/transcription_tools.py
@alt-glitch alt-glitch added type/bug Something isn't working tool/tts Text-to-speech and transcription provider/openai OpenAI / Codex Responses API area/billing Account usage, credit usage, billing (cross-cutting) area/config Config system, migrations, profiles P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 12, 2026
@Enough1122

Copy link
Copy Markdown
Contributor

AI code review — automated review for reference, author can ignore or act on any point.

fix(stt): honor gateway preference over direct credentials

  1. tools/transcription_tools.py _resolve_openai_audio_client_config — this is a behavior change for existing configs with stt.use_gateway: true that previously fell back to direct credentials when the managed gateway was unreachable; they now get a hard ValueError. That is the stated intent and it is consistent with the other gateway-enabled media tools, but since it can break working setups, consider checking whether a config migration/notice is warranted, or at least confirm the error message surfaces somewhere the user will see it (it currently includes the gateway-unavailable text, which is good).
  2. The prefer_managed gate now also suppresses the local/private base_url shortcut ("not-needed", cfg_base_url). A user with a local OpenAI-compatible server plus a stale use_gateway: true will now error instead of using the local endpoint — same intentionality question as above, but worth calling out explicitly since the local path is the common self-hosted case.
  3. is_truthy_value(..., default=False) — confirm the loader treats a bare use_gateway: true at the stt level the same way the other gateway tools resolve it (e.g. if stt.provider is openai but use_gateway lives under a per-provider key elsewhere, this may not match). The third test covers the real-config path, which is good; a test for the local-endpoint + use_gateway: true combination would pin the new behavior.

@teknium1

Copy link
Copy Markdown
Collaborator

Thanks @bgrablin — you diagnosed this exactly right, and a week before we got to it. Selecting Nous Subscription STT and then being silently billed against a direct OpenAI key was a real contract violation, and your root-cause analysis (the resolver never consulting the stored gateway intent) was spot on.

This landed on main in #90317 (commit 099258e, "route TTS/STT OpenAI audio on the stored selection, not credentials"), which rebuilt both audio resolvers — STT and the TTS twin — around a strict read_selection() switch: use_gateway: true maps to the managed selection, managed-only, fail-closed when unentitled, with no silent fallback to direct credentials in either direction. Your regression cases are covered by the tests that shipped with it.

Closing as implemented on main. Appreciate the careful report and fix — sorry the timing overlapped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/billing Account usage, credit usage, billing (cross-cutting) area/config Config system, migrations, profiles P2 Medium — degraded but workaround exists provider/openai OpenAI / Codex Responses API sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/tts Text-to-speech and transcription type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants