feat: Resilienz (Fallback-Ketten) und Metriken (#5)

- Fallback-Provider (app/providers/fallback.py) fuer STT/LLM/TTS: Provider-Kette
  der Reihe nach; Config *_FALLBACK; build_orchestrator baut Ketten (dedupliziert)
- LLM-Stream-Fallback nur solange kein Token gesendet wurde
- Metriken (app/metrics.py): In-Memory Counter/Timer, keine externe Dependency
- HTTP-Middleware (Requests/Latenz/Status je Pfad); Pipeline-Stufen-Timing stt/llm/tts;
  Fallback-/Fehlerzaehler; GET /api/metrics (JSON + Prometheus)
- Tests: 58 gruen (+6); Doku aktualisiert (README, BEDIENUNGSANLEITUNG, Architektur, .env.example)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 05:19:07 +02:00
commit 6422444017
13 changed files with 452 additions and 23 deletions

View file

@ -171,6 +171,7 @@ 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 |
| `GET /api/metrics` | Metriken (JSON / Prometheus) |
| `WS /ws/chat` | Echtzeit-Chat (Text rein, Streaming-Events) |
| `WS /ws/voice` | Echtzeit-Sprache (Audio rein → STT → Antwort) |
@ -206,7 +207,7 @@ Reihenfolge der Weiterentwicklung:
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. **(weitgehend erledigt)** Echtzeit: WebSocket-Streaming-Chat (`/ws/chat`), **Token-Level-LLM-Streaming (SSE, `stream:true`)**, **Audio-Streaming (chunked TTS satzweise, `audio_stream:true`)**, **Audio-Eingang (`/ws/voice`)**, **Barge-in/Turn-Manager (`interrupt` bricht laufende Antwort ab)** und **VAD-Aeusserungserkennung (energie-basiert, opt-in)** sind umgesetzt. Offen: **echte partielle Live-Transkripte (Streaming-STT-Dienst, wortweise)** und **WebRTC (aiortc)** — beide brauchen schwere Abhaengigkeiten/Dienste. Heute laeuft STT pro Aeusserung.
5. **Resilienz:** Fallback-Policy (remote KI fällt aus → lokaler/alternativer Provider), Metriken/Tracing.
5. **(weitgehend erledigt)** Resilienz: Fallback-Ketten je Modul (`*_FALLBACK`, Provider faellt aus → naechster) und In-Memory-Metriken (`/api/metrics`: Request/Latenz, Pipeline-Stufen, Fallback/Fehler; JSON + Prometheus). Offen: verteiltes Tracing, Alerting.
6. **Betrieb:** Kosten-/Quota-Kontrolle pro Nutzer; Notfall-/Eskalationskonzept (Senioren-Kontext).
7. **TransportRouter** als eigene lokal/remote-Achse aktivieren.
@ -224,13 +225,14 @@ voice-assistant-scaffold/
│ ├── dependencies.py # Registries, ResolvedRoute, resolve_route, Store-/Router-Singleton
│ ├── store.py # Persistenz: Store-Interface + SQLiteStore (Nutzer/Sessions/Verlauf)
│ ├── auth.py # Bearer-Token-Auth (require_user) + Admin-Schutz
│ ├── metrics.py # In-Memory-Metriken (Counter/Timer, JSON + Prometheus)
│ ├── errors.py # RoutingError -> HTTP 422
│ ├── schemas.py # Pydantic-Modelle
│ ├── api/ # health, chat, speak, transcribe, devices, sessions, config, admin, me, ws
│ ├── core/ # orchestrator
│ ├── audio/ # router, transport_router, vad, endpoints/input|output/*
│ ├── pipeline/ # input_cleaner, spoken_response_adapter, tts_normalizer, sentence_chunker
│ └── providers/ # stt/ llm/ tts/ (openrouter + lokale Stubs)
│ └── providers/ # stt/ llm/ tts/ (openrouter + lokale Stubs) + fallback.py
├── config/ # voice-assistant.example.toml (+ lokale .toml, gitignored)
├── data/ # SQLite-DB (gitignored)
├── deploy/ # systemd unit + env-Beispiel