Dieter Schlüter
aa64ccf585
feat(memory): automatische Erinnerungs-Extraktion aus Gespraechen
...
- app/core/memory_extractor.py: LLM destilliert nach je N Turns dauerhafte
Fakten/Vorlieben aus dem Verlauf, dedupliziert gegen vorhandene Erinnerungen
und legt sie ab - best-effort, nicht-blockierend (Hintergrund-Task), eigener
Extraktions-Prompt (JSON, Reasoning aus), Cap-Begrenzung
- Trigger in /api/chat und /ws/voice nach dem Persistieren des Turns
- Konfig: MEMORY_EXTRACTION_ENABLED/_EVERY_N_TURNS/_MAX/_PROVIDER
- Tests: Extraktion, Dedup, kaputtes JSON, Cap, leeres Gespraech, Scheduling
- Doku: README + Architektur-Roadmap (Punkt 3 erledigt)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 03:15:08 +02:00
Dieter Schlüter
28c729f1d4
feat(llm): lokales llama.cpp-Modell (va_llm) als zentrale, sprachoptimierte KI
...
- scripts/llm-server/: start/stop/status fuer llama.cpp-Server (Port 8001, GPU 1,
Modell Qwen3.6-35B-A3B-Uncensored, Alias va_llm) - alles per ENV ueberschreibbar
- Defaults auf den lokalen Server umgestellt (config.py, .example-Configs, .env.example)
- Provider local-openai-compatible sprachoptimiert: Reasoning aus
(chat_template_kwargs.enable_thinking=false) + knapper Sprach-System-Prompt,
optional max_tokens/temperature - Antwort ~9x schneller, kurze vorlesbare Texte
- Makefile-Targets llm-up/llm-down/llm-status
- Doku (README, BEDIENUNGSANLEITUNG) auf llama.cpp statt Ollama aktualisiert
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 02:57:57 +02:00
Dieter Schlüter
a40ae75c5f
docs: Cloud-TTS-Stimmen (OpenRouter) dokumentieren + Umstellen
...
BEDIENUNGSANLEITUNG (B1): neuer Abschnitt 'Stimme des Cloud-TTS (OpenRouter) waehlen'
-- Gateway pflegt keine eigene Liste, reicht OPENROUTER_TTS_VOICE durch; Stimmen
haengen vom Modell ab (Gemini-Familie ~30 Stimmen, OpenAI gpt-4o-mini-tts), Umstellen
global (.env) und pro Aufruf (voice-Feld in /api/speak,/api/chat), Hinweis auf
fehlende --voice-Option in voice_loop. .env.example: Verweis bei OPENROUTER_TTS_VOICE.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:36:13 +02:00
Dieter Schlüter
d4de9ba5b0
docs: installierte Piper-Stimmen auflisten + download-Hinweis korrigieren
...
BEDIENUNGSANLEITUNG: Tabelle der aktuell installierten Stimmen (DE/EN/ES/FR,
Qualitaet, Default thorsten-high), Hinweis auf fehlende weibliche DE-high-Stimme
und dass chatterbox noch Stub ist. .env.example: nicht funktionierenden
'python -m piper.download_voices'-Befehl durch ls + huggingface-Hinweis ersetzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:31:58 +02:00
Dieter Schlüter
c9d8552ec7
feat(tts): Aussprache-Normalisierung vor Piper (Ordinalia/Einheiten/Abk./Lexikon)
...
In-Process-Layer ausgebaut statt neuer Lib/CLI. Leitprinzip: nicht duplizieren,
was espeak-ng schon kann (Kardinal-/Dezimalzahlen bleiben unangetastet) -- nur die
belegten Luecken fuellen.
- german_numbers.py: deutsche Ordinalzahlen 1.-31. (attributiv/adverbial)
- tts_normalizer.py: Ordinalia (Datum '1. Mai'->'erster Mai', Folgen '1. 2. 3.'->
'erstens, zweitens, ...'), Einheiten nach Zahl (kg/km/km-h/...), Abkuerzungen
(Dr./z.B./usw.), optionales YAML-Lexikon (config/pronunciation.<lang>.yaml).
Provider-abhaengige Stufen auto|full|light|off (TTS_NORMALIZE_LEVEL): piper=full,
Cloud=light (laesst Zahlen/Abk. fuer das Cloud-Modell in Ruhe).
- spoken_response_adapter.py: nummerierte Listen -> Ordinalwoerter statt Loeschen.
- sentence_chunker.py: trennt nicht mehr nach Ziffer+Punkt, Einzelbuchstabe+Punkt
('z. B.', Initialen) oder bekannten Abkuerzungen -> behebt das Streaming-Symptom
('1.' wurde als eigener 'Satz' zu 'eins').
- orchestrator/dependencies: normalize_level durchgereicht (auto: piper->full).
- Tests: tests/test_tts_normalizer.py + Chunker-Faelle (85 gruen).
- Doku: BEDIENUNGSANLEITUNG (Aussprache verbessern), .env.example.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:01:41 +02:00
Dieter Schlüter
cca423dac3
feat(tts): echtes lokales TTS via piper (kein Stub mehr)
...
PiperTTSProvider ruft das piper-Binary (--output-raw) async auf, liest die native
Sample-Rate aus der .onnx.json und resampelt per ffmpeg auf 24000 Hz (Gateway-Norm).
Nicht passende Stimmen (z. B. Cloud-Stimme 'Zephyr' aus der Route) fallen auf die
konfigurierte Default-Stimme zurueck. Damit ist eine voll-lokale Konstellation
(faster-whisper + Ollama + piper) moeglich -> keine API-Kosten, max. Datenschutz.
- config: PIPER_BIN/PIPER_VOICES_DIR/PIPER_VOICE/TTS_SAMPLE_RATE (+ .env.example)
- dependencies: piper-Factory mit Settings verdrahtet
- tests: tests/test_piper_tts.py (offline, Fake-Binary; Resample-Test skippt ohne ffmpeg);
e2e/auth-Tests nutzen jetzt einen Stub-TTS statt 'piper' als Pseudo-Stub
- docs: README, BEDIENUNGSANLEITUNG (voll-lokal-Beispiel), Architektur-Roadmap
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:11:20 +02:00
Dieter Schlüter
7c1f00662c
feat: Audio-Streaming als Default (Admin abschaltbar via AUDIO_STREAM_DEFAULT)
...
- Config audio_stream_default=True; _run_turn nutzt es, wenn die Anfrage audio_stream
nicht explizit setzt (explizite Anfrage gewinnt)
- voice_loop: immer durchgehender Player (spielt 1 oder N Haeppchen luekenlos);
--stream-audio / --no-stream-audio als Tri-State (sonst entscheidet der Server-Default)
- conftest: audio_stream_default=False fuer deterministische Tests; neuer Test fuer
Default-an-Streaming ueber /ws/voice; 67 Tests gruen
- Doku + .env.example aktualisiert (AUDIO_STREAM_DEFAULT, --no-stream-audio)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 18:07:36 +02:00
Dieter Schlüter
c25f081f9f
feat(stt): echtes lokales STT via faster-whisper (optional .[local])
...
- FasterWhisperProvider implementiert (CTranslate2): Modell prozessweit gecacht
(lru_cache), Transkription in asyncio.to_thread; robuster CPU-Fallback wenn
GPU/compute_type nicht verfuegbar
- Config: FASTER_WHISPER_MODEL/DEVICE/COMPUTE_TYPE (Defaults base/auto/default)
- pyproject: optionales Extra [local] = faster-whisper
- Test: transcribe-Endpunkt nutzt jetzt einen Stub-STT (kein Platzhalter mehr)
- Doku: Voraussetzungen, Hybrid-Beispiel (STT+LLM lokal, TTS remote), Architektur/README
Live verifiziert: TTS->WAV->faster-whisper transkribiert korrekt (de); voller Hybrid
ueber /ws/voice (faster-whisper + Ollama llama3.2 + OpenRouter-TTS) funktioniert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 11:28:20 +02:00
Dieter Schlüter
1eb79c1f09
feat: Tageskontingent und Notfall-Eskalation ( #6 )
...
- Quota (app/quota.py): Anfragen pro Nutzer/Tag (usage-Tabelle), DAILY_REQUEST_LIMIT,
pro Nutzer via prefs uebersteuerbar; 429 (REST) bzw. error-Event (WS); Metrik
- Notfall (app/safety/emergency.py): heuristische Erkennung (de/en); Log im Store
(emergency_events) + optionaler Webhook (best-effort) + X-Emergency/emergency-Event;
Metrik emergency_total; Notfaelle umgehen das Kontingent
- verdrahtet in chat/speak/transcribe + WS-Turns
- Tests: 64 gruen (+6); Doku aktualisiert (README, BEDIENUNGSANLEITUNG, Architektur, .env.example)
Hinweis: Notfall-Erkennung ist eine Heuristik (kein Lebensretter); erkannte Texte
sind sensibel -> DSGVO beachten.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 05:29:30 +02:00
Dieter Schlüter
6422444017
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>
2026-06-17 05:19:07 +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