Skip to content

[Feature]: Add OpenRouter as an STT provider #24415

@Dev-Time

Description

@Dev-Time

Problem or Use Case

Hermes today supports five STT providers: local (faster-whisper), Groq, OpenAI, Mistral (Voxtral), and xAI (Grok). Users who already have OPENROUTER_API_KEY set up for LLM access cannot use the same key & auth for speech-to-text — they'd need a separate Groq, OpenAI, or xAI account to transcribe voice messages.

OpenRouter offers an OpenAI-compatible /api/v1/audio/transcriptions endpoint that routes to Whisper-family models (openai/whisper-1, openai/gpt-4o-mini-transcribe, etc.), billed through the same OpenRouter credit pool. Adding openrouter as an STT provider means users with an OpenRouter key get voice transcription with zero extra accounts, keys, or billing setup.

Proposed Solution

Add openrouter as a native STT provider alongside the existing ones. The configuration follows the same pattern as other providers:

stt:
  enabled: true
  provider: openrouter
  openrouter:
    model: openai/whisper-1               # OpenRouter model ID
    api_key: ${OPENROUTER_API_KEY}         # auto-detected from env var

The implementation would:

  1. Provider detection — Add openrouter to _get_provider() in tools/transcription_tools.py. Accept stt.provider: openrouter in config or auto-detect when OPENROUTER_API_KEY is set (similar to how xai uses XAI_API_KEY).

  2. Client routing_transcribe_openai() already does OpenAI-compatible transcription. The OpenRouter provider reuses this path with:

    • base_url: https://openrouter.ai/api/v1
    • api_key: $OPENROUTER_API_KEY
    • No extra HTTP headers needed (OpenRouter's attribution headers are optional for STT)
  3. Model selection — Let users pick any Whisper-compatible model available on OpenRouter. Default to openai/whisper-1. Common options:

    • openai/whisper-1
    • openai/gpt-4o-mini-transcribe
    • openai/gpt-4o-transcribe
  4. Auth — Use the existing OPENROUTER_API_KEY env var, no new env vars needed.

  5. Auto-detection priorityopenrouter should be checked after openai and xai in the auto-detect chain, since it's a catch-all that many users already have configured.

No new Python SDK dependency required — the existing openai SDK with a custom base_url handles OpenRouter's API natively.

Alternatives Considered

  1. Use OpenRouter as a custom OpenAI endpoint — Set stt.provider: openai with stt.openai.base_url: https://openrouter.ai/api/v1 and stt.openai.api_key: $OPENROUTER_API_KEY. This would work in theory but is blocked by existing bug bug(tools): stt.openai.api_key and base_url from config are ignored — STT provider always MISSING for local endpoints #4102 (config values for stt.openai.api_key and base_url are ignored — only env vars are read). So users can't do this today without setting VOICE_TOOLS_OPENAI_KEY to their OpenRouter key, which creates confusing env var semantics.

  2. Environment variable workaround — Users could set VOICE_TOOLS_OPENAI_KEY=$OPENROUTER_API_KEY and STT_OPENAI_BASE_URL=https://openrouter.ai/api/v1, but this is undocumented, confusing, and loses the model routing flexibility OpenRouter provides.

  3. Wait for bug(tools): stt.openai.api_key and base_url from config are ignored — STT provider always MISSING for local endpoints #4102 fix — Bug bug(tools): stt.openai.api_key and base_url from config are ignored — STT provider always MISSING for local endpoints #4102 fixing the config plumbing would unblock the workaround, but a first-class openrouter provider is cleaner: dedicated model config, documented model options, consistent pattern with the existing OpenRouter TTS provider ([Feature]: Add OpenRouter as a TTS provider #15726).

Related Issues

Feature Type: New tool (STT provider)

Scope: Medium (few files, < 300 lines — primarily tools/transcription_tools.py changes + config schema)

  • I'd like to implement this myself and submit a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to haveprovider/openrouterOpenRouter aggregatortool/ttsText-to-speech and transcriptiontype/featureNew feature or request

    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