feat: Audio-Eingang über WebSocket (/ws/voice) - Sprach-zu-Sprach (#4 Ausbau)

- /ws/voice: binaere Audio-Frames puffern, {"type":"end"} -> STT-Transkription
  -> transcript-Event -> bestehende Antwort-Pipeline (ack/token/audio/semantic/done)
- ws.py refaktoriert: gemeinsame _resolve + _run_turn fuer /ws/chat und /ws/voice
- stream/audio_stream auch fuer Sprach-Turns nutzbar; mehrere Utterances pro Verbindung
- Tests: 47 gruen (+2: Transkript->Antwort, leerer Puffer)
- Doku aktualisiert (README, BEDIENUNGSANLEITUNG, Architektur)

Hinweis: STT pro Aeusserung (gepuffert); partielle Live-Transkripte (Streaming-STT
mit VAD) bleiben naechster Increment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 04:51:49 +02:00
commit 9340d3f998
5 changed files with 233 additions and 98 deletions

View file

@ -171,7 +171,8 @@ ein No-op; `LoopbackOutput` sammelt die Chunks (testbar ohne Hardware).
| `POST /api/admin/users` | Nutzer anlegen (Admin-Key) → Token einmalig |
| `GET /api/me` · `PUT /api/me/prefs` | aktueller Nutzer + dauerhafte Präferenzen |
| `GET/POST/DELETE /api/me/memories` | Langzeit-Erinnerungen des Nutzers |
| `WS /ws/chat` | Echtzeit-Chat (Streaming-Events über WebSocket) |
| `WS /ws/chat` | Echtzeit-Chat (Text rein, Streaming-Events) |
| `WS /ws/voice` | Echtzeit-Sprache (Audio rein → STT → Antwort) |
Endpunkt-/Provider-Auswahl ist über **Request-Body** (pro Aufruf), **Session**
(`?session_id=…`) und **Defaults/Profil** steuerbar. Verwendete Route erscheint als
@ -187,8 +188,8 @@ Device Router (strikt, Singleton); Output-Lifecycle; **Authentifizierung
+ dauerhafte Nutzer-Präferenzen**; **Gesprächsgedächtnis pro Session (Verlauf im
Store, fließt ins LLM)**; **Langzeit-Erinnerungen pro Nutzer (als LLM-Kontext)**;
**WebSocket-Streaming-Chat (`/ws/chat`) inkl. Token-Level-LLM-Streaming (SSE,
`stream:true`) und satzweisem Audio-Streaming (chunked TTS, `audio_stream:true`)**;
automatisierte Tests.
`stream:true`) und satzweisem Audio-Streaming (chunked TTS, `audio_stream:true`)**; **Sprach-Eingang
über WebSocket (`/ws/voice`: Audio rein → STT → Antwort-Pipeline)**; automatisierte Tests.
**Platzhalter (Gerüst):** Audio-Endpunkte (`local-default`, `bluetooth`,
`mobile-ws`, `mobile-webrtc`) liefern leere Chunks — nur Auswahl/Lifecycle sind
@ -203,7 +204,7 @@ Reihenfolge der Weiterentwicklung:
1. **(erledigt)** Konfig- & Routing-Fundament: Profile, Device Router, Registry, Pro-Request-Override.
2. **(erledigt)** Cloud-Fundament: Bearer-Token-Auth, Mehrbenutzer, persistenter SQLite-Store, Mandanten-Trennung, dauerhafte Nutzer-Präferenzen. Offen: Skalierung auf gemeinsamen Store (Postgres/Redis) für mehrere Instanzen.
3. **(erledigt)** Konversationsgedächtnis: Kurzzeit-Gesprächsverlauf pro Session + Langzeit-Erinnerungen pro Nutzer (manuell gepflegt, als LLM-Kontext). Offen: **automatische** Extraktion/Zusammenfassung von Erinnerungen aus Gesprächen.
4. **(teilweise erledigt)** Echtzeit: WebSocket-Streaming-Chat (`/ws/chat`), **Token-Level-LLM-Streaming (SSE, `stream:true`)** und **Audio-Streaming (chunked TTS satzweise, `audio_stream:true`)** sind umgesetzt. Offen: **Audio-Eingang/Streaming-STT**, **Barge-in/Turn-Manager**, **WebRTC**.
4. **(teilweise erledigt)** Echtzeit: WebSocket-Streaming-Chat (`/ws/chat`), **Token-Level-LLM-Streaming (SSE, `stream:true`)**, **Audio-Streaming (chunked TTS satzweise, `audio_stream:true`)** und **Audio-Eingang (`/ws/voice`: binaere Chunks -> STT -> Antwort-Pipeline)** sind umgesetzt. Offen: **partielle Live-Transkripte (Streaming-STT mit VAD)**, **Barge-in/Turn-Manager**, **WebRTC**.
5. **Resilienz:** Fallback-Policy (remote KI fällt aus → lokaler/alternativer Provider), Metriken/Tracing.
6. **Betrieb:** Kosten-/Quota-Kontrolle pro Nutzer; Notfall-/Eskalationskonzept (Senioren-Kontext).
7. **TransportRouter** als eigene lokal/remote-Achse aktivieren.