Skip to content

STT Provider Selection Logic: Placeholder API keys treated as valid credentials #1774

@AxDSan

Description

@AxDSan

Bug Description

The _get_provider() function in transcription_tools.py incorrectly treats placeholder/dummy API keys as valid credentials, causing it to select the OpenAI provider instead of falling back to local STT when provider: local is configured.

Root Cause

In _resolve_openai_api_key() (line ~218), the function returns any non-empty string as a "valid" API key. This means:

  • disabled-use-local-whisper (a placeholder value) is treated as valid
  • _get_provider() at line ~187 checks if _HAS_OPENAI and _resolve_openai_api_key(): - returns truthy
  • Even though the key is invalid, the provider logic selects OpenAI
  • This bypasses the intended local STT fallback

Steps to Reproduce

  1. Set OPENAI_API_KEY=disabled-use-local-whisper (or any non-empty placeholder) in environment
  2. Set stt: provider: local in config.yaml
  3. Ensure faster-whisper is NOT installed (_HAS_FASTER_WHISPER = False)
  4. Try to transcribe a voice message
  5. Observe 401 error from OpenAI API instead of graceful fallback or error

Expected Behavior

When provider: local is configured, the system should:

  1. Attempt to use local STT (faster-whisper) if available
  2. If faster-whisper is not available, fail gracefully with a clear error message
  3. Never use a placeholder/non-standard API key value as valid credentials

Actual Behavior

The system sends requests to OpenAI with the placeholder key, resulting in 401 authentication errors.

Environment

  • File: hermes_agent/tools/transcription_tools.py
  • Key function: _get_provider() (lines ~164-236)
  • Related: _resolve_openai_api_key() (line ~218)

Proposed Solutions

Option A: Validate API key format

Check that the key starts with sk- (OpenAI standard) before treating it as valid:

def _resolve_openai_api_key():
    key = _config.get("openai_api_key") or os.environ.get("OPENAI_API_KEY")
    if key and key.startswith("sk-"):
        return key
    return None

Option B: Respect explicit config provider setting

When provider: local is explicitly set, never fall back to OpenAI regardless of what API keys are present. The current logic only checks faster_whisper availability, not the user's explicit preference.

Option C: Whitelist valid provider configs

Only consider a provider available if both:

  1. The library is installed (e.g., _HAS_OPENAI)
  2. A valid API key format is detected (starts with sk-)

Additional Context

  • The _HAS_FASTER_WHISPER flag determines if local STT is available
  • When False, the code falls through to check cloud providers (Groq, then OpenAI)
  • This creates a dependency on OpenAI even when the user explicitly configured local STT
  • The logic assumes any non-empty string is a valid API key, which breaks intentional "disable" patterns like disabled-use-local-whisper

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions