fix(voice): instrucțiune de limbă inline + fallback Supertonic pe română

Markerul opac [tts-lang:en] depindea de regula din VOICE_MODE.md, aflată
la ~30k caractere distanță în system prompt — modelul o rata pe ~1 din 5
turnuri. Răspunsul în română era apoi respins integral de pocket-tts
(English-only) și turnul rămânea fără audio.

- src/router.py: markerul poartă instrucțiunea inline (un singur token,
  acoperit în continuare de strip-ul anti-jailbreak); 5/5 EN la repro
- src/voice/tts_stream.py: dacă modelul tot scapă română pe o voce
  pockettts, blocul cade pe Supertonic (M2, ro) în loc de tăcere;
  coada TTS transportă (clause, voice, lang) per clauză
- tools/tts.py: looks_romanian public (folosit de tts_stream)
- personality/VOICE_MODE.md: regula gated pe prefixul [tts-lang:en
- tests: 4 teste noi fallback + expectații marker actualizate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 19:20:28 +00:00
parent 61d667ec65
commit 80eb8034b3
6 changed files with 113 additions and 15 deletions

View File

@@ -58,7 +58,7 @@ class _PocketTTSUnavailable(Exception):
_RO_DIACRITICS = set("ăâîșțĂÂÎȘȚşţŞŢ")
def _looks_romanian(text: str) -> bool:
def looks_romanian(text: str) -> bool:
return any(ch in _RO_DIACRITICS for ch in text)
@@ -202,7 +202,7 @@ def _synthesize_pockettts(text: str, entry: dict) -> dict:
Raises:
_PocketTTSUnavailable: eșec tehnic (connect error/timeout/5xx) — caller-ul face fallback.
"""
if _looks_romanian(text):
if looks_romanian(text):
return {
"ok": False,
"error": "pocket-tts nu suportă română — textul trebuie să fie în engleză.",