Commit graph

6 commits

Author SHA1 Message Date
e814b5548d fix(tts): Geräte-TTS-Regression für Sprachen ohne Geschlechtsstimme beheben
Commit 5c63f7b hatte deviceGenderReady als harte Bedingung eingeführt: das
Gerät musste eine Stimme des WAHLgeschlechts haben, sonst Server-Fallback.
Die konservative Geschlechts-Heuristik liefert für viele Geräte-Stimmen null
(z.B. NL am iPhone: nur eine Stimme ohne erkennbares Geschlecht) -> der
Server-Fallback griff und lieferte eine schlechte/fremdsprachige Aussprache.
Für NL kam (im noch nicht neu gestarteten Prozess) die deutsche Default-
Stimme -> "deutscher Akzent".

Lösung: deviceGenderReady -> deviceVoiceReady. Eine sprachrichtige Stimme
reicht (pickVoice wählt cands[0] als Best-Effort-Fallback). Die m/f-Wahl
wirkt am Gerät nur für Sprachen mit mehreren Stimmen (DE, EN), sonst
folgenlos — aber eine falsche Sprache ist schlechter als ein folgenloser
Schalter.

+ Test: NL in test_piper_single_voice_languages_ignore_gender aufgenommen
(serverseitige Komplementär-Logik; sichert voice_for_route NL-Auflösung).
Der client-seitige app.js-Fix ist mangels JS-Test-Framework manuell
verifiziert (Geräte-TTS für NL spricht niederländisch, DE/EN behalten
Geschlechtswahl).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-28 16:15:04 +02:00
cc354938df feat(2a): Erlaubte Sprachen pro Nutzer (Admin-Vorgabe)
Der Admin schaltet pro Nutzer Sprachen frei (Toggle-Chips in der
Nutzerverwaltung). Die Haupt-App zeigt dann nur diese Sprachen; bei genau
einer erlaubten Sprache wird das Sprachmenü ausgeblendet (kein Stress).

- admin.py: PUT /admin/users/{id}/prefs (allowed_languages), list_users
  liefert allowed_languages mit.
- dependencies.py: resolve_route klemmt die Sprache auf eine erlaubte
  (Backend-Durchsetzung, nicht nur UI).
- app.js: applyAllowedLanguages (Haupt-UI-Filter) + Sprach-Chips je Nutzer
  im Admin. app.js v=44.
- Tests: Klemmung + Admin-Endpunkt. 213 passed.

Login-/nginx-Umbau (Ein-Klick-Link) folgt nach separater Design-Abstimmung.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 04:06:09 +02:00
be5206c7ed feat(1a): Flex-Sprachmodus vollständig entfernen
Sprache ist immer fest. Entfernt: language_mode aus Route/Schema/Config/
Runtime-Config, die Flex-Verzweigung in Orchestrator (effective_language =
language) und ws.py (immer normales transcribe), die "🔄 Flex"-Option im
Frontend samt zugehöriger app.js-Logik (langOverrides, loadMe, Turn-Sprache).

Die generische STT-Methode transcribe_detect bleibt als wiederverwendbare
Infrastruktur erhalten (nicht mehr aufgerufen). Test: Route trägt kein
language_mode mehr. 215 passed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 02:51:17 +02:00
3c549a05b1 test: Coverage für Gender-/Stimm-System + hermetische Suite
Schließt die Test-Lücken der Gender-/Stimm-Arbeit der letzten Tage:
- test_routing.py: voice_for_route über alle Sprachen × Geschlechter
  (inkl. ES Multi-Speaker #0/#1, "any"→weiblich, Gegengeschlecht-Fallback,
  AR/PT/ZH Einzelstimmen, unbekannte Sprache → None).
- test_piper_tts.py: _parse_speaker (#id) + Gender-Code-Auflösung in
  synthesize() + speaker_id-Durchreichung für Multi-Speaker.
- test_cartesia_tts.py (neu): Voice-Map-Parsing, _resolve_voice_id-Präzedenz,
  nicht unterstützte Sprachen, direkte-UUID-Durchreichung, Cartesia→Piper-Fallback.

Hermetik-Fix in conftest.py: Deployment-Fallback-Ketten (stt/llm/tts_fallback)
werden pro Test auf "" gesetzt. Vorher schlugen 3 WS-Streaming-Tests fehl, weil
llm_fallback="openrouter" aus der TOML durchsickerte und Stub-LLMs ohne stream()
auf den echten OpenRouter durchfielen ("OPENROUTER_API_KEY is empty").

Ergebnis: 213 passed (vorher 164 passed / 3 failed). DEPLOYMENT.md Teil 4.0
dokumentiert den Pflicht-Testlauf vor jedem Deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 00:32:47 +02:00
Dieter Schlüter
e0e69fdf15 feat: Cloud-Fundament - Auth, Persistenz und Mandanten-Trennung
- SQLite-Store (app/store.py) hinter Store-Interface: Nutzer + Sessions persistent
- Bearer-Token-Auth (app/auth.py); Nutzerverwaltung via Admin-Key (POST /api/admin/users)
- GET /api/me, PUT /api/me/prefs (dauerhafte Nutzer-Praeferenzen)
- chat/speak/transcribe/sessions auth-geschuetzt; Mandanten-Trennung (fremde Session -> 403)
- Route-Aufloesung: Defaults < Profil < ENV < Nutzer-Prefs < Session < Request
- SessionManager (in-memory) durch Store ersetzt
- AUTH_ENABLED-Schalter (prod an, dev/Tests aus); DB_PATH/ADMIN_API_KEY
- Doku aktualisiert (README, BEDIENUNGSANLEITUNG, Architektur, deploy-env); data/ gitignored
- Tests: 29 gruen (Auth, Mandanten, Persistenz, Routing)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 02:14:25 +02:00
Dieter Schlüter
293ed257db Initial commit: Voice Assistant Gateway mit Konfig-/Routing-Fundament
- FastAPI-Gateway mit REST-Endpunkten (chat/speak/transcribe/devices/sessions/config)
- Geschichtete Konfiguration mit Profilen (local-dev/hybrid/cloud) via TOML + ENV
- Registry-Pattern + einheitliche Route-Aufloesung (Default->Profil->ENV->Session->Request)
- Device Router (strikt, Singleton) und Output-Lifecycle im Orchestrator
- OpenRouter-Adapter (STT multipart/LLM/TTS) + lokale Provider-Stubs
- Regelbasierte Pipeline (Cleaner/Spoken-Adapter/TTS-Normalizer)
- 22 automatisierte Tests; Doku: README, BEDIENUNGSANLEITUNG, Architektur
- Secrets ausschliesslich ueber Umgebung; .env und lokale config gitignored

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 01:48:56 +02:00