fix(bridge): leeres <voice></voice> macht TTS nicht mehr stumm

Claude haengt manchmal reflexartig ein leeres <voice></voice> an (v.a. bei
Spotify-Antworten). clean_text_for_tts nahm dann group(1)='' → text='' → gar
keine Sprachausgabe. Das erklaerte, warum Playlist-Wechsel 'Fliegen' vorgelesen
wurde (Claude schrieb Inhalt ins Tag), 'Prodigy' aber stumm blieb (leeres Tag)
— reiner Claude-Output-Zufall, nicht Skill/Playlist-Name.

Fix: leeres/whitespace <voice> ignorieren und den normalen Anzeigetext lesen.
Deterministisch, unabhaengig von Claudes Tag-Reflex.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 00:45:43 +02:00
co-authored by Claude Opus 4.8
parent 44220edbd1
commit becc83d9e3
+9 -2
View File
@@ -295,10 +295,17 @@ def clean_text_for_tts(text: str) -> str:
if not text: if not text:
return "" return ""
# <voice>...</voice> wenn vorhanden → nur das nehmen # <voice>...</voice> wenn vorhanden → nur diesen Inhalt lesen. ABER: ein
# LEERES <voice></voice> darf die Sprachausgabe nicht verstummen lassen.
# Claude haengt reflexartig manchmal ein leeres Tag an (v.a. bei Spotify-
# Antworten) — frueher wurde daraus text="" → gar keine TTS (Playlist-Wechsel
# 'Prodigy' stumm, 'Fliegen' gesprochen, rein je nachdem ob Claude Inhalt ins
# Tag schrieb). Leeres/whitespace-Tag → ignorieren und den normalen Text lesen.
voice_match = _re_tts.search(r'<voice>([\s\S]*?)</voice>', text, _re_tts.IGNORECASE) voice_match = _re_tts.search(r'<voice>([\s\S]*?)</voice>', text, _re_tts.IGNORECASE)
if voice_match: if voice_match and voice_match.group(1).strip():
text = voice_match.group(1) text = voice_match.group(1)
else:
text = _re_tts.sub(r'<voice>[\s\S]*?</voice>', ' ', text, flags=_re_tts.IGNORECASE)
t = text t = text