feat(stt): Geräte-STT auf Mobilgeräten (Web Speech API) — getrennt, Datenschutz-Linie C

- Geräte-STT erkennt Sprache lokal und sendet nur Text über den Text-Turn; spart
  Audio-Upload + Server-STT. Getrennter Schalter (STT ▾) unabhängig vom TTS.
- Linie C: nur bei nachweislich lokaler Erkennung (iOS / Chrome on-device); Cloud
  (z. B. Chrome-Desktop -> Google) nur mit Admin-Flag ALLOW_CLOUD_STT.
  -> config.allow_cloud_stt, RUNTIME_SETTABLE, /api/me, Admin-Toggle.
- Fix-only (SpeechRecognition braucht Sprach-Hint); Flex -> Server-STT-Fallback.
  Kein/instabiles SpeechRecognition (z. B. Firefox) -> Server-STT. Live-Interim im
  Eingabefeld. Terminal/Desktop/Laptop unverändert serverseitig (Option nur sichtbar,
  wenn das Gerät lokale Erkennung bietet).
- Tests: /api/me-Flag + runtime-setzbar (169 grün). Doku §5.1.2 + §6.3.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-20 20:08:10 +02:00
commit ab9c4f4938
7 changed files with 150 additions and 4 deletions

View file

@ -792,7 +792,8 @@ https://va.beispiel.de/ ← remote über Reverse-Proxy (alles, inkl. Mikr
| **Texteingabe + Senden** | Text tippen, dann Enter oder „Senden" |
| **🎤 Mikrofon-Button** | **Idle (grün 🎤):** Tippen → Aufnahme startet · **Aufnahme (rot pulsierend 🎤):** Tippen → Aufnahme stoppt und wird gesendet · **KI antwortet (amber ⏹):** Tippen → Antwort sofort unterbrechen (Barge-in) |
| **Sprache ▾** | Antwortsprache wählen (→ § 6.6): `🔄 Flex` = folgt automatisch der gesprochenen Sprache · feste Sprache (🇩🇪/🇬🇧/…) = Eingabe wird in diese Sprache übersetzt. Die vorlesende Stimme folgt der Auswahl. |
| **Qualität ▾** | Vorlese-Quelle wählen: `📱 Gerät` = das Handy/der Browser liest selbst vor (Web Speech API, kein Server-Audio → spart Daten/Kosten) · `Schnell` = piper (lokal) · `Hoch` = chatterbox (neuronal) · `Cloud` = openrouter |
| **Qualität ▾** (Ausgabe/TTS) | Vorlese-Quelle: `📱 Gerät` = das Handy/der Browser liest selbst vor (Web Speech API, kein Server-Audio → spart Daten/Kosten) · `Schnell` = piper (lokal) · `Hoch` = chatterbox (neuronal) · `Cloud` = openrouter |
| **STT ▾** (Eingabe) | *Nur sichtbar auf Geräten mit lokaler Spracherkennung* (iOS/Android): `🎙 Gerät` = Spracherkennung im Gerät (nur Text wird gesendet) · `☁ Server` = Audio-Upload + Whisper (wie am PC/Laptop). Getrennt von der Ausgabe wählbar (→ § 6.3.1). |
| **☀️ / 🌙** | Tag-/Nacht-Modus; folgt sonst automatisch dem Betriebssystem |
| **⚙️** (Admin) | Öffnet das Admin-Panel — nur für Admin-Nutzer sichtbar (→ § 7.5) |
| **Angemeldet als …** | SSO-Identität; „Gast" wenn AUTH deaktiviert oder kein SSO-Cookie |
@ -1012,6 +1013,27 @@ FASTER_WHISPER_DEVICE=cuda
FASTER_WHISPER_COMPUTE_TYPE=float16
```
#### 6.3.1 Geräte-STT (Web Speech API) — „🎙 Gerät"
Auf **Mobilgeräten** (iOS/Android) kann die Spracherkennung **im Gerät** laufen: Das
Handy wandelt Sprache in Text um und sendet nur den **Text** an den Server — kein
Audio-Upload, keine Server-STT-Last. Gegenstück zum Geräte-TTS (§ 6.5.0), aber
**getrennt** wählbar (STT-Dropdown in der Kopfzeile).
- **Erscheint nur**, wenn das Gerät lokale Spracherkennung bietet. **Terminal, Desktop-
Browser und Laptop** zeigen die Option nicht — dort läuft STT wie bisher über den
Server (Whisper).
- **Datenschutz (Linie C):** Standardmäßig nur bei **nachweislich lokaler** Erkennung
(iOS-Safari; Chrome mit On-Device-Modus). **Chrome am Desktop** würde das Audio zur
Erkennung an Google schicken — das ist nur erlaubt, wenn ein Admin
`ALLOW_CLOUD_STT=true` setzt (Admin → Einstellungen → „Geräte-STT (mobil)").
- **Nur Fix-Sprache:** Geräte-STT braucht einen Sprach-Hint → es nutzt die im
Sprach-Dropdown gewählte feste Sprache. Im **Flex-Modus** fällt es automatisch auf
Server-STT (Whisper-Auto-Erkennung) zurück.
- **Fallback:** Ohne Unterstützung (z. B. Firefox) oder bei Erkennungsfehlern wird der
Server-STT-Pfad genutzt. Während der Erkennung erscheint der Text **live** im
Eingabefeld; erneutes Tippen aufs Mikrofon beendet und sendet.
---
### 6.4 LLM-Einstellungen (Sprachmodell, lokal)