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
- Set
OPENAI_API_KEY=disabled-use-local-whisper (or any non-empty placeholder) in environment
- Set
stt: provider: local in config.yaml
- Ensure
faster-whisper is NOT installed (_HAS_FASTER_WHISPER = False)
- Try to transcribe a voice message
- Observe 401 error from OpenAI API instead of graceful fallback or error
Expected Behavior
When provider: local is configured, the system should:
- Attempt to use local STT (faster-whisper) if available
- If faster-whisper is not available, fail gracefully with a clear error message
- 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:
- The library is installed (e.g.,
_HAS_OPENAI)
- 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
Bug Description
The
_get_provider()function intranscription_tools.pyincorrectly treats placeholder/dummy API keys as valid credentials, causing it to select the OpenAI provider instead of falling back to local STT whenprovider: localis 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 checksif _HAS_OPENAI and _resolve_openai_api_key():- returns truthySteps to Reproduce
OPENAI_API_KEY=disabled-use-local-whisper(or any non-empty placeholder) in environmentstt: provider: localin config.yamlfaster-whisperis NOT installed (_HAS_FASTER_WHISPER = False)Expected Behavior
When
provider: localis configured, the system should:Actual Behavior
The system sends requests to OpenAI with the placeholder key, resulting in 401 authentication errors.
Environment
hermes_agent/tools/transcription_tools.py_get_provider()(lines ~164-236)_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:Option B: Respect explicit config provider setting
When
provider: localis explicitly set, never fall back to OpenAI regardless of what API keys are present. The current logic only checksfaster_whisperavailability, not the user's explicit preference.Option C: Whitelist valid provider configs
Only consider a provider available if both:
_HAS_OPENAI)sk-)Additional Context
_HAS_FASTER_WHISPERflag determines if local STT is availabledisabled-use-local-whisper