Folgt der "keine neuen Settings in .env" Regel.
f5tts/bridge.py:
- F5TTS_MODEL/CKPT_FILE/VOCAB_FILE/CFG_STRENGTH/NFE_STEP ENV-Vars raus
- Hard-coded Defaults im Code (DEFAULT_F5TTS_*)
- F5Runner besitzt Live-Settings als Instance-Vars + update_config()
- config-Broadcast triggert Modell-Reload nur wenn Modell-relevantes
sich aendert (cfg_strength/nfe_step ohne Reload)
- F5TTS_DEVICE bleibt ENV (Hardware-Bootstrap)
xtts/docker-compose.yml: F5TTS_* ENV-Vars rausgenommen, Kommentar
verweist auf Diagnostic-Config.
aria-bridge: nimmt f5tts*-Felder im config-Handler entgegen, persistiert
sie in voice_config.json. Beim RVS-Connect broadcastet die Bridge die
persistierte Config einmalig — damit die f5tts-bridge nach Container-
Restart automatisch die zuletzt gewaehlten Settings bekommt, ohne dass
der User in Diagnostic was klicken muss.
Diagnostic UI:
- Neuer aufklappbarer "F5-TTS Modell-Tuning (advanced)" Bereich
- Felder: Modell-ID, Custom-Checkpoint, Vocab, cfg_strength, nfe_step
- voice_config beim Laden: Felder werden zurueck in die UI gesetzt
- sendVoiceConfig schickt die neuen Felder mit
- Server: send_voice_config persistiert die Felder, leere Strings
werden geloescht damit die Hard-Defaults greifen
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bug-Root: voice_upload schrieb "Das ist ein Referenz Audio." als Platzhalter
wenn die whisper-bridge nicht erreichbar war. F5-TTS bekam dann diesen Text
als Sprach-Anker, sah aber im WAV ganz andere Worte → verwirrtes Modell,
halluziniert in beliebiger Sprache (z.B. Spanisch).
Fixes:
- handle_voice_upload: schreibt KEINE Platzhalter-.txt mehr. Bei Failure
bleibt die .txt weg → naechste TTS-Nutzung zieht via on-the-fly retry
nach.
- _do_tts: Legacy-Platzhalter wird beim Render erkannt und geloescht,
Transkription on-the-fly neu angezogen. Bestehende kaputte voices
reparieren sich automatisch beim ersten Render.
UI-Aufraeumung: F5-TTS hat keine "Standard"-Stimme — der Eintrag ist raus
in App SettingsScreen + Diagnostic. Diagnostic-Dropdown hat jetzt einen
disabled-Hinweis "(keine Stimme gewaehlt)".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XTTS-Bridge:
- empfaengt neuen voice_preload Type, rendert stumm "ja." fuer die Stimme
via TTS-Queue (damit kein Konflikt mit echtem TTS)
- horcht zusaetzlich auf config-Broadcasts: wenn Diagnostic global die
Stimme wechselt, wird auto-preloaded
- broadcastet voice_ready mit Dauer (loadMs) oder error
RVS: voice_preload + voice_ready zur ALLOWED_TYPES-Liste.
App (SettingsScreen): beim Wechsel senden wir voice_preload, zeigen einen
Spinner in der Voice-Row und einen Toast mit "Stimme X bereit (Ns)".
App (ChatScreen): Toast auch hier — falls User gerade nicht in Settings ist.
Diagnostic (server+UI): voice_ready wird an Browser durchgereicht, ein
Status-Text unter dem Voice-Dropdown zeigt "wird geladen" → "bereit".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Safe-Variante (Default):
docker builder prune -a -f && docker image prune -a -f
→ Build-Cache + ungenutzte Images, KEINE Volumes angefasst.
→ 90% des Platzproblems geloest, Null Datenverlust-Risiko.
Aggressive Variante (nur auf Wunsch, hinter 'Mehr'-Button):
docker system prune -a --volumes -f
→ Zusaetzlich ungenutzte Volumes.
→ Nur sicher wenn alle ARIA-Container LAUFEN (sonst werden
openclaw-config/claude-config/aria-shared als "ungenutzt"
behandelt und zerstoert — Sessions weg).
→ Hinweistext orange hervorgehoben mit Warnung.
Banner-Button 'Sicher aufraeumen' kopiert die sichere Variante.
'Mehr' klappt die Erklaerung der aggressiven Variante aus.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Server:
- checkDiskSpace() prueft alle 30s 'df -B1 /shared' (zeigt Host-Disk
da /shared ein Volume auf dem Docker-FS ist)
- 4 Stufen: ok (<70%), info (70%), warn (85%), critical (95%)
- Broadcastet disk_status nur bei Aenderung (Level oder Prozent)
- currentDiskStatus wird gecached → neu verbundene Clients bekommen
den aktuellen Stand sofort beim 'init'
UI:
- Sticky Banner ganz oben, versteckt wenn Disk ok
- Farbe nach Level: gelb (info), orange (warn), rot (critical)
- Zeigt Prozent, Used/Total/Avail in GB, konkrete Situation
- Cleanup-Command als monospace Code mit Copy-Button ('docker system
prune -a --volumes -f') — Click auf Code oder Button kopiert ins
Clipboard, Fallback auf Range-Selektion
- 'Schliessen' Button fuer temporaeres Ausblenden (kommt aber wieder
bei naechster Aenderung)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vorher: Diagnostic's setMode sendete einen faked chat mit der
Aktivierungsphrase ('ARIA, Hangar-Modus') — das wurde erst in
_process_core_response auf dem ARIA-Antwort-Text detected, war
unzuverlaessig und nutzte nicht den sauberen mode-Message-Path.
Nachher: sauberer set_mode-Pfad mit Live-Sync.
diagnostic/server.js:
- Neue action 'set_mode' → sendet type=mode an RVS direkt
- RVS-Message-Handler: type=mode Broadcast von Bridge wird an
Browser-Clients durchgereicht
diagnostic/index.html:
- setMode() nutzt jetzt action=set_mode (keine Phrase mehr)
- updateModeUI separat — wird bei Broadcast auch aufgerufen
- Mode-Broadcast vom Server syncs UI live (andere Diagnostic/App
hat gewechselt → unser UI aktualisiert sofort)
- Button data-mode + MODE_LABELS auf kanonische IDs umgestellt
(nicht_stoeren, fluester statt dnd, whisper)
bridge/modes.py:
- canonical_id() liefert die IDs die App + Diagnostic kennen
(nicht_stoeren, fluester, ...) — damit Broadcast-ID zur UI-ID passt
bridge/aria_bridge.py:
- _broadcast_current_mode nutzt canonical_id statt enum.name.lower()
Flow jetzt:
Diagnostic wechselt Mode → set_mode → Bridge → persist + broadcast
→ alle Apps + alle Diagnostic-Browser-Tabs aktualisieren sofort
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bug-Fix: Voice-Auswahl verschwand nach Page-Load
- xtts_voices_list Handler rebuildet das Dropdown — vorheriger select.value
ging dabei verloren. Jetzt wird der Wert gemerkt und nach Rebuild
wiederhergestellt (falls die Stimme noch existiert).
Feature: Stimmen loeschen (Diagnostic)
- XTTS-Bridge: neuer handleDeleteVoice — entfernt /voices/<name>.wav
und schickt aktualisierte Liste per xtts_voices_list
- RVS: xtts_delete_voice in ALLOWED_TYPES
- Diagnostic Server: Action xtts_delete_voice forwarded via RVS
- Diagnostic UI: renderVoiceList zeigt alle Custom-Voices mit X-Button
Bei Loeschen der gerade aktiven Stimme: auf Default zuruecksetzen
Feature: Voice-per-Request in Bridge
- App kann mit jedem Chat ein voice-Feld mitschicken
- Bridge merkt sich _next_voice_override, nutzt es fuer die NAECHSTE
ARIA-Antwort (einmalig, dann reset)
- tts_request (Play-Button) akzeptiert voice im Payload als Override
- Fallback: globale xtts_voice aus voice_config.json
- So kann jedes Geraet seine eigene Stimme haben ohne den globalen
Default zu aendern
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Breaking Change: wenn XTTS-Bridge (Gaming-PC) offline ist, bleibt ARIA
stumm. Chat-Antworten kommen weiter an, aber kein Audio. Das ist
bewusst akzeptiert — XTTS klingt einfach grauenhaft viel besser.
Bridge (aria_bridge.py):
- from piper import ... raus
- VoiceEngine-Klasse komplett entfernt (synthesize, speak, select_voice)
- EPIC_TRIGGERS + load_epic_triggers raus (Highlight-Voice-Feature
ohne Piper sinnlos)
- self.voice_engine, voice_name, requested_voice Aufrufe weg
- _process_core_response: immer XTTS, kein Fallback
- tts_request Handler: immer XTTS
- config Handler: nur ttsEnabled + xttsVoice + whisperModel
- import wave raus
bridge/requirements.txt: piper-tts raus
bridge/Dockerfile: Kommentar aktualisiert
docker-compose.yml: ./aria-data/voices Mount raus
aria-data/config/aria.env.example: PIPER_RAMONA/PIPER_THORSTEN raus
get-voices.sh: komplett geloescht (war nur Piper-Downloader)
Diagnostic UI (index.html):
- Piper Panel (Standard-Stimme / Highlight-Stimme / Speed-Sliders) weg
- TTS Engine Dropdown weg (immer XTTS)
- TTS Diagnose Tab zeigt nur noch XTTS-Status + Test-Button
- sendVoiceConfig sendet nur noch ttsEnabled/xttsVoice/whisperModel
- toggleXTTSPanel als no-op Legacy-Stub (JS-Calls bleiben safe)
Diagnostic Server (server.js):
- handleSendVoiceConfig: nur noch ttsEnabled + xttsVoice + whisperModel
- handleTestTTS: via xtts_request (nicht mehr Piper subprocess)
- handleCheckTTS: via xtts_list_voices ueber RVS
- handleGetVoiceConfig/Defaults bereinigt
- Highlight-Trigger UI bleibt, wird aber von Bridge nicht mehr
ausgewertet (dead-code im UI, spaeter ggf. fuer XTTS-Voice-Switch)
README + issue.md aktualisiert.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
TTS-Cleanup erweitert:
- Zeitbereiche: '8:00-9:00 Uhr' / '8-9 Uhr' → 'acht bis neun Uhr'
- Uhrzeiten: '8:30 Uhr' → 'acht Uhr dreissig', '15 Uhr' → 'fuenfzehn Uhr'
- Kleine Zahlen-Bereiche: '5-6' → 'fuenf bis sechs' (nur ≤24)
- Zahlen 0-59 als deutsche Woerter (inkl. 'einundzwanzig', 'fuenfundvierzig')
Diagnostic: TTS-Debug Einblenden
- Checkbox 'TTS-Text einblenden' in der Chat-Test Kopfzeile
- Unter ARIA-Nachrichten erscheint die aufbereitete Variante
(blauer Border + Label 'TTS:')
- Nur in Diagnostic, nicht in der App
- LocalStorage persistiert den Toggle-Zustand
- Minimaler JS-Port von clean_text_for_tts als Fallback
Play-Button respektiert Engine:
- Bridge: tts_request nutzt jetzt die aktive TTS-Engine (Piper/XTTS),
Text wird durch clean_text_for_tts aufbereitet
- messageId wird vom Play-Button mitgeschickt → Bridge verknuepft
generiertes Audio mit der urspruenglichen Message
- XTTS-Chunks: requestId → messageId Map (LRU 100 Eintraege),
beim xtts_response wird die Basis-UUID extrahiert und die
messageId dem audio-Frame angehaengt
- App cached auch XTTS-Audio jetzt (letzter Satz pro Message —
echte Chunk-Konkatenation bleibt TODO)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Der QR wurde mit createImgTag() als fester Pixel-IMG gerendert und
ueberlappte den Warnhinweis + Button rechts daneben. Fix:
- createSvgTag mit cellSize=4 + scalable=true
- SVG skaliert auf width:100%/height:100% der 220x220 Box
- Container: flex-shrink:0 (damit Flex ihn nicht weiter schrumpft)
- overflow:hidden als Sicherheit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Eingabefelder haben jetzt width:100% + box-sizing:border-box,
keine Ueberlappung mehr im Grid
- Token-Felder haben einen Augen-Button daneben (👁/👀) zum
Anzeigen/Verbergen des Inhalts
- Kleineres Label-Grid (140px statt 150px), grosszuegigerer Gap
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Framework fuer zentrale Runtime-Konfiguration:
- /api/runtime-config (GET/POST) persistiert in /shared/config/runtime.json
- Werte haben Vorrang ueber die ENV-Variablen aus aria.env
- Feldliste: RVS_HOST/PORT/TLS/TOKEN, ARIA_AUTH_TOKEN, WHISPER_MODEL/LANGUAGE
- Atomic write (tmp + rename) fuer Konsistenz
Bridge:
- load_config() liest nach aria.env noch runtime.json und ueberschreibt
die Werte. Aenderungen werden beim Neustart der Bridge uebernommen.
Diagnostic UI:
- Neue Sektion "Runtime-Konfiguration" in Einstellungen
- Formular fuer RVS-Credentials + Aria-Auth-Token
- "Speichern" persistiert, triggert auch QR-Code-Regenerierung
- Hinweis: Diagnostic-Container selbst bleibt auf ENV (erstmal)
issue.md konsolidiert — 6 groessere Tasks dieser Session als erledigt.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
QR-Code Onboarding
- Diagnostic: GET /api/onboarding gibt RVS-Credentials zurueck
- Einstellungen-UI: neue Sektion mit QR-Code (qrcode-generator via CDN)
- Format kompatibel mit bestehendem QRScanner.parseQRData (host/port/tls/token)
- App-SettingsScreen hatte QR-Scanner bereits — funktioniert out of the box
- Warnhinweis zu Token im Klartext
TTS-Audio-Cache
- Bridge: jede ARIA-Chat-Nachricht bekommt eine messageId (UUID)
Audio-Payload wird mit messageId verknuepft (Piper-Pfade)
- ChatScreen: messageId + audioPath in ChatMessage Interface
- audioService.cacheAudio(): speichert Base64 in DocumentDirectory/tts_cache/<id>.wav
- audioService.playFromPath(): spielt aus Cache ohne Regenerierung
- Play-Button: wenn audioPath gesetzt → aus Cache, sonst tts_request
- cleanupOldTTSCache(): alte unreferenzierte WAVs (>30 Tage) weg
- Persistiert via AsyncStorage — ueberlebt App-Restart
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1) NO_REPLY Token wird in Bridge und Diagnostic erkannt und still
verworfen. Toleranz fuer Variationen (Whitespace, Punkt, Quotes).
Kein Chat-Eintrag, kein TTS.
2) AudioFocusModule (Kotlin) mit requestDuck / requestExclusive /
release. AudioService ruft:
- requestExclusive() bei Aufnahme-Start → andere Apps pausieren
- requestDuck() bei TTS-Playback-Start → andere Apps leiser
- release() bei Stop/Queue-Ende
MainApplication registriert AudioFocusPackage.
3) clean_text_for_tts() in Bridge — zentrale Aufbereitung:
- <voice>...</voice> Tag wird bevorzugt (falls ARIA es schreibt)
- Code-Bloecke (``` und `) komplett raus
- Markdown (Fett/Kursiv/Links/Headings/Listen) geschleift
- Einheiten ausgeschrieben: 22GB → 22 Gigabyte, 85% → 85 Prozent
- Abkuerzungen buchstabiert: CPU → C P U, API → A P I
- URLs durch "ein Link" ersetzt
Genutzt in VoiceEngine.synthesize und im XTTS-Request — Chat-Text
an die App bleibt unveraendert (original Markdown), nur TTS kriegt
die aufbereitete Version.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Die OpenClaw Reset-Files heissen <uuid>.jsonl.reset.<iso>Z
(nicht <uuid>.jsonl.reset.<iso>.Z). Der falsche Regex matchte
nie, alle Archive wurden als "verwaist" angezeigt statt als "archiv".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OpenClaw resettet Sessions beim ersten chat.send nach Container-Restart
(wenn abortedLastRun / systemSent Inkonsistenz erkannt wurde) und
benennt die alte .jsonl in .jsonl.reset.<timestamp>.Z um. Der Inhalt
war also gar nicht verloren, nur unsichtbar.
Diagnostic:
- handleListSessions scannt jetzt auch *.jsonl.reset.* Files
- Reset-Files bekommen archived:true + resetAt-Timestamp
- Neue UI-Sektion "Archivierte Versionen" (collapsible <details>)
mit Export-Button, zeigt aufklappbar alle gesicherten alten Sessions
- Aktivieren ist fuer Archive deaktiviert (zerstoert aktive Session)
- Loeschen + Export stehen zur Verfuegung
tools/export-jsonl-to-md.js:
- Standalone Node-Script zum Konvertieren beliebiger .jsonl (auch reset-Files)
- Nutzbar via stdin, exakt gleiche Export-Logik wie Diagnostic
- Fuer Rettungsaktionen direkt auf der VM
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vorher: wc -l auf der .jsonl — zaehlt auch Tool-Calls, Run-Events,
Metadata-Eintraege mit. Diagnostic zeigte z.B. "10 Msgs" fuer eine
Session mit 6 echten User/Assistant-Nachrichten.
Jetzt: grep -cE '"role":"(user|assistant)"' — zaehlt nur echte
Konversations-Messages. Matcht wie der Export und die Chat-History
das interpretieren.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Zwei display:-Deklarationen im inline-style der Diagnostic-Chat-Leiste
haben sich gegenseitig ueberschrieben — 'display:flex' war die zweite
und hat 'display:none' aushebelt. Indicator war so beim Seitenaufbau
sichtbar bis JS ein idle-Event empfing.
- HTML: 'display:flex' aus inline-style entfernt
- JS: beim Anzeigen explizit display='flex' setzen (statt 'block')
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nach chat:final kommen oft noch agent-Events rein (Core raeumt nach),
die den Thinking-Indicator wieder anspringen liessen.
- Diagnostic: 3s-Settled-Window nach chat:final, agent_activity-Broadcasts
werden in dem Fenster unterdrueckt (idle kommt weiter durch).
- Bridge: Gleiches Fenster in _emit_activity() — App bekommt keine
trailing thinking/tool-Events mehr nach dem finalen Antwort.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- App: AudioSamplingRateAndroid 16000 + AudioChannelsAndroid 1
→ Whisper bekommt direkt sein Ziel-Format, kein Resample mehr
- Bridge: STTEngine.reload() laedt Modell zur Laufzeit neu
(tiny/base/small/medium/large-v3)
- Bridge: Config-Message triggert Hot-Reload wenn whisperModel sich aendert
- Bridge: Default auf 'medium' (besser als 'small' bei aehnlicher Latenz)
- Diagnostic: Neue Sektion "Whisper (Spracherkennung)" mit Dropdown,
auto-save bei Auswahl, beim Laden wird der gespeicherte Wert gesetzt
- Diagnostic/Server: send_voice_config merged whisperModel in voice_config.json
- aria.env.example: WHISPER_MODEL + WHISPER_LANGUAGE dokumentiert
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Bridge: _emit_activity() spiegelt OpenClaw agent events als agent_activity
an RVS, dedupliziert State-Wechsel. chat:final/error senden idle.
- Bridge: Neuer cancel_request-Handler ruft Diagnostic /api/cancel per HTTP.
- Diagnostic: Neuer POST /api/cancel Endpoint (gleiche Logik wie WS-Cancel).
- RVS: agent_activity + cancel_request in ALLOWED_TYPES.
- App: Gelber Indicator ueber der Input-Bar mit Text je nach Activity,
roter Abbrechen-Button. Cancel sendet cancel_request via RVS.
- issue.md: Erledigte Bugfixes + Features konsolidiert.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ⬇ Button per Session-Zeile — exportiert auch inaktive Sessions
- Server parst JSONL, extrahiert User/Assistant-Nachrichten mit Timestamp
- Metadata-Prefix wird entfernt, Markdown mit # Session-Header generiert
- Browser-Download via Blob + download-Attribut
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- pipelineEnd() now broadcasts agent_activity: idle unconditionally
- chat:error and chat:final paths broadcast idle outside of active pipeline
- Gateway close event ends active pipeline + broadcasts idle
- Prevents indicator from hanging after timeout/error/disconnect
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- sessionFromFile flag prevents auto-pick after first start
- Atomic write (temp + rename) with loud error logging
- Auto-pick filters out aria-bridge/aria-diagnostic when user sessions exist
- handleSetActiveSession reports persistence failures to client
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
App:
- Multiple pending attachments (horizontal scroll preview)
- Individual remove (X) or clear all
- Send button shows when any attachment pending
- All files sent before text message
Diagnostic:
- Clip icon for file selection (multiple)
- Paste images/files from clipboard (Ctrl+V)
- Pending preview with thumbnails
- Files sent via RVS before text message
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>