Commit graph

11 commits

Author SHA1 Message Date
Dieter Schlüter
b38992cf28 feat(admin): vollständiges Admin-Panel in der Web-UI (Phase 1)
Ersetzt das rudimentäre Nutzer-Dropdown durch ein vollwertiges
Admin-Panel-Overlay mit 5 Tabs:

Nutzer:      Anlegen (Token einmalig), Umbenennen, Token-Reset,
             Löschen, Erinnerungen verwalten (anzeigen/add/delete)
Gespräche:   Nutzer → Sessions → Transkript (Chat-Bubble-Ansicht)
Notfälle:    Tabelle aller emergency_events mit Zeitstempel/Kategorie
Status:      Gateway-Status, Provider-Config, Laufzeit-Metriken
Metriken:    Nutzungsstatistik pro Nutzer + Gesamtsumme

Backend: 7 neue Admin-Endpunkte in admin.py, 5 neue Store-Methoden.
Design: Tailwind CSS, Tag/Nacht-Modus, responsiv.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 01:04:20 +02:00
Dieter Schlüter
613b18055b fix(barge-in): interrupted-Event schliesst WS -> busy-Reset + Button zurueck auf gruen
Server sendet nach Interrupt {'type':'interrupted'}, aber der Client-Handler
fehlte: WS blieb offen, runTurn loeste nie auf, Button blieb dauerhaft gelb.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 19:03:03 +02:00
Dieter Schlüter
0d907a1886 feat(barge-in): Unterbrechen der KI-Antwort per Mikrofon-Button und Enter
Web-Interface (app.js):
- Mic-Button hat jetzt 3 Zustände: idle (grün 🎤) / Aufnahme (rot pulsierend) /
  KI antwortet (amber ⏹, klicken = Barge-in)
- Barge-in sendet {"type":"interrupt"} auf der aktiven WS-Verbindung (activeWs)
  und stoppt alle laufenden AudioBufferSourceNodes sofort (stopAudio)
- busy + Button-Reset erfolgen automatisch wenn die WS schliesst

Terminal (voice_loop.py):
- _stdin_watcher(): polling via select.select (nicht-blockierend, kein Thread-Leak)
  wartet auf Enter-Tastendruck waehrend Server antwortet
- _send_and_play() raced one_turn gegen _stdin_watcher mit asyncio.wait;
  bei Barge-in: interrupt-Frame an Server, Player.terminate(), feeder beenden
- Feedback: "↩ Unterbrochen — drücke [Enter] für neue Aufnahme …"

Server-Seite war bereits vollstaendig implementiert (ws.py, kein Handlungsbedarf).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 18:38:33 +02:00
Dieter Schlüter
d87ebdf457 fix(web): robuster Mikrofon-Pfad fuer iOS-Safari + mp4-Format
- getUserMedia/MediaRecorder-Support pruefen, klare Fehlermeldung mit error.name
  (In-App-Browser/Privat-Modus/Permission) statt pauschalem "HTTPS noetig?"
- Safari liefert audio/mp4 (nicht webm): tatsaechlichen mimeType verwenden und als
  format mitschicken; Server (faster-whisper) erkennt das Format am Inhalt (mp4/AAC
  verifiziert). Asset-Version v7

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 10:39:02 +02:00
Dieter Schlüter
7ebba4e755 feat(web): Tailwind-Redesign-UI + Doku (Nachtrag zu 3470c0e)
Eigentliche UI-Dateien: neues Tailwind-Layout (index.html), Theme-Umschalter +
Bubble-Stile + Mic-Status (app.js); README-Abschnitt aktualisiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 10:20:24 +02:00
Dieter Schlüter
3470c0e262 feat(web): Tailwind-Redesign, Tag/Nacht-Umschalter, Mobile-Fixes
- responsives, modernes Layout mit Tailwind (CDN, kein Build); aufgeraeumter Header
  (einheitliche Groessen/Farben, neutrale Palette, ein Akzent)
- Tag-/Nacht-Umschalter: manuell + folgt automatisch dem System (kein Flackern)
- Mobile: App-Shell h-[100dvh] mit fixem Eingabe-Footer + safe-area-Padding
  -> kein grosser Abstand mehr zum unteren Bildschirmrand
- "Metriken"-Link entfernt (fuer Endnutzer irrelevant); Admin-Nutzerliste als Toggle
- style.css entfernt (komplett Tailwind), Asset-Version v6

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 10:19:34 +02:00
Dieter Schlüter
b7c59d8c85 feat(web): Stimmen-Umschalter (piper/chatterbox/cloud) in der UI
Dropdown im Menue setzt tts_provider als Request-Override fuer Text- und Sprach-Turns
-> live umschaltbar zwischen schnellem piper, hochwertigem chatterbox und Cloud.
Asset-Version v5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 09:49:25 +02:00
Dieter Schlüter
6073ba1133 fix(web): Session-ID pro Nutzer statt globalem web-main
Die feste Session "web-main" gehoerte dem ersten Nutzer (lokal: anonymous) ->
SSO-Nutzer bekam "Session gehoert einem anderen Nutzer" (403). Die Web-UI leitet
die Session jetzt aus /api/me ab (web-<user_id>); ensureSession() wartet vor dem
ersten Turn auf /api/me. Asset-Version v4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 08:50:30 +02:00
Dieter Schlüter
b3c8114469 fix(web): kein Caching der UI + versionierte Assets
Safari cachte CSS/JS aggressiv -> Aenderungen wurden nicht sichtbar. StaticFiles
liefert die UI nun mit Cache-Control: no-cache aus; Asset-Links zusaetzlich
versioniert (?v=3), damit die neue Version sicher geladen wird.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 07:49:55 +02:00
Dieter Schlüter
a62c49d6b1 fix(web): responsives Layout + zuverlaessiges Auto-Scrollen (mobil)
- Layout auf echte Viewport-Hoehe (100dvh, vh-Fallback); nur der Nachrichten-
  bereich scrollt (min-height:0), Eingabe + Mic-Button bleiben immer sichtbar
- Mobile: Menue als kompakte Kopfleiste, Chat fuellt den Rest
- Auto-Scroll zentralisiert (scrollToBottom via rAF) und bei token/semantic/done/
  neuer Nachricht ausgeloest; reagiert auf Tastatur (visualViewport) + Resize/Focus
  -> die neueste Antwort ist immer vollstaendig sichtbar

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 07:39:40 +02:00
Dieter Schlüter
76df695111 feat(web): Remote-Web-UI mit Mikrofon + Forward-Auth (YunoHost-SSO)
- Minimale Web-UI (app/web/, vanilla, same-origin -> kein CORS): Text-Prompt +
  Mikrofon-Button (Aufnahme im Browser -> /ws/voice -> Antwort wird vorgelesen),
  Token-Streaming, PCM-Wiedergabe, Identitaet/Logout/Admin im Menue
- Forward-/Trusted-Header-Auth (app/auth.py): Identitaet aus SSO-Header, nur von
  TRUSTED_PROXY_IPS akzeptiert; sonst Token/Anonymous-Fallback. Auto-Provisioning
  via store.get_or_create_user_by_external_id (+ external_id-Spalte/Migration)
- /api/me um is_admin + sso_logout_url erweitert; GET /api/admin/users (Liste) und
  GET /api/admin/request-headers (SSO-Header-Discovery), Admin-gated
- StaticFiles-Mount; Config: TRUSTED_AUTH_HEADER/_PROXY_IPS, ADMIN_USERS, SSO_LOGOUT_URL
- WS-Auth liest Identitaet aus dem Handshake-Header
- Deploy: nginx-Vorlage (WS-Upgrade!) + deploy/README.md (HTTPS/SSO/Firewall/Discovery)
- Tests: Forward-Auth (Provisioning, Admin-Flag, Proxy-IP-Trust, 401/403, Static)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 04:37:16 +02:00