fix: OpenRouter-STT auf JSON/base64 statt multipart (passend zur OpenRouter-API)

Live-Test gegen OpenRouter ergab: /audio/transcriptions erwartet JSON mit
input_audio:{data(base64),format} - NICHT multipart/form-data. Die fruehere
Umstellung auf multipart (OpenAI-Standard) war fuer OpenRouter falsch.

- STT-Provider zurueck auf JSON/base64 (mit robuster Fehlerbehandlung)
- verifiziert per TTS->WAV->STT Round-Trip: Text korrekt zurueck transkribiert
- LLM, TTS und STT funktionieren jetzt alle live gegen OpenRouter
- Doku-Referenz aktualisiert (multipart -> JSON/base64)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 09:31:34 +02:00
commit 1d338810b1
2 changed files with 18 additions and 9 deletions

View file

@ -1,3 +1,5 @@
import base64
import httpx
from app.providers.stt.base import STTProvider
@ -16,12 +18,17 @@ class OpenRouterSTTProvider(STTProvider):
if not audio_bytes:
raise ValueError("STT input audio is empty")
# OpenAI-kompatibler /audio/transcriptions-Endpunkt erwartet multipart/form-data
# mit binärem file-Feld, nicht JSON mit base64.
files = {"file": (f"audio.{fmt}", audio_bytes, f"audio/{fmt}")}
data: dict[str, str] = {"model": self.model}
# OpenRouter /audio/transcriptions erwartet JSON mit base64-Audio
# (NICHT multipart/form-data). Quelle: OpenRouter-Doku (STT).
payload = {
"model": self.model,
"input_audio": {
"data": base64.b64encode(audio_bytes).decode("utf-8"),
"format": fmt,
},
}
if language:
data["language"] = language
payload["language"] = language
timeout = httpx.Timeout(connect=10.0, read=120.0, write=30.0, pool=10.0)
@ -29,9 +36,11 @@ class OpenRouterSTTProvider(STTProvider):
try:
response = await client.post(
"https://openrouter.ai/api/v1/audio/transcriptions",
headers={"Authorization": f"Bearer {self.api_key}"},
files=files,
data=data,
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
},
json=payload,
)
response.raise_for_status()
except httpx.HTTPStatusError as exc: