Summary
Add OpenRouter as a first-class provider for TTS (text-to-speech) and STT (speech-to-text). OpenRouter is already first-class for LLM and embedding; it now exposes dedicated, OpenAI-compatible audio endpoints, so we can add the two remaining modalities.
Feasibility (verified)
OpenRouter ships OpenAI-compatible audio APIs:
- TTS →
POST https://openrouter.ai/api/v1/audio/speech (compatible with OpenAI's Audio Speech API; returns a raw audio byte stream).
- STT →
POST https://openrouter.ai/api/v1/audio/transcriptions (compatible with OpenAI's transcription API; returns JSON with text + usage).
Docs:
Auth is the same OPENROUTER_API_KEY / https://openrouter.ai/api/v1 base URL already used by the existing OpenRouter LLM and embedding providers.
Implementation pointers
Because the endpoints are OpenAI-compatible, mirror the existing OpenAI audio providers rather than writing anything from scratch:
- TTS: add
src/esperanto/providers/tts/openrouter.py following providers/tts/openai.py (or subclass/configure providers/tts/openai_compatible.py) with base URL https://openrouter.ai/api/v1 and OPENROUTER_API_KEY.
- STT: add
src/esperanto/providers/stt/openrouter.py following providers/stt/openai.py (or providers/stt/openai_compatible.py) with the same base URL / key.
- Register in the factory (
src/esperanto/factory.py): add "openrouter" entries under the stt and tts maps, alongside the existing openrouter LLM and embedding entries.
- Exports/
__init__.py: export the new classes to match the pattern used by the other providers.
Acceptance criteria
AIFactory.create_tts("openrouter", model_name=...) returns a working TTS model that synthesizes audio via OpenRouter.
AIFactory.create_stt("openrouter", model_name=...) returns a working STT model that transcribes audio via OpenRouter.
- Both resolve credentials from
OPENROUTER_API_KEY and the OpenRouter base URL, consistent with the existing OpenRouter LLM/embedding providers.
- Real-API integration coverage added in line with the existing STT/TTS release tests.
Downstream
Requested in Open Notebook: lfnovo/open-notebook#987. Once released here, Open Notebook only needs to add text_to_speech / speech_to_text to the OpenRouter modality mapping.
Summary
Add OpenRouter as a first-class provider for TTS (text-to-speech) and STT (speech-to-text). OpenRouter is already first-class for LLM and embedding; it now exposes dedicated, OpenAI-compatible audio endpoints, so we can add the two remaining modalities.
Feasibility (verified)
OpenRouter ships OpenAI-compatible audio APIs:
POST https://openrouter.ai/api/v1/audio/speech(compatible with OpenAI's Audio Speech API; returns a raw audio byte stream).POST https://openrouter.ai/api/v1/audio/transcriptions(compatible with OpenAI's transcription API; returns JSON with text + usage).Docs:
Auth is the same
OPENROUTER_API_KEY/https://openrouter.ai/api/v1base URL already used by the existing OpenRouter LLM and embedding providers.Implementation pointers
Because the endpoints are OpenAI-compatible, mirror the existing OpenAI audio providers rather than writing anything from scratch:
src/esperanto/providers/tts/openrouter.pyfollowingproviders/tts/openai.py(or subclass/configureproviders/tts/openai_compatible.py) with base URLhttps://openrouter.ai/api/v1andOPENROUTER_API_KEY.src/esperanto/providers/stt/openrouter.pyfollowingproviders/stt/openai.py(orproviders/stt/openai_compatible.py) with the same base URL / key.src/esperanto/factory.py): add"openrouter"entries under thesttandttsmaps, alongside the existingopenrouterLLM and embedding entries.__init__.py: export the new classes to match the pattern used by the other providers.Acceptance criteria
AIFactory.create_tts("openrouter", model_name=...)returns a working TTS model that synthesizes audio via OpenRouter.AIFactory.create_stt("openrouter", model_name=...)returns a working STT model that transcribes audio via OpenRouter.OPENROUTER_API_KEYand the OpenRouter base URL, consistent with the existing OpenRouter LLM/embedding providers.Downstream
Requested in Open Notebook: lfnovo/open-notebook#987. Once released here, Open Notebook only needs to add
text_to_speech/speech_to_textto the OpenRouter modality mapping.