fix(voice): răspuns în engleză pe voice turns când vocea activă e pocket-tts
Instrucțiunea „engleză pentru audio" nu ajungea la model: VOICE_MODE.md nu avea nicio regulă de limbă, iar condiția din TOOLS.md („când generez pentru o voce pockettts") era neevaluabilă — modelul nu știa ce voce e activă. Rezultat: mirroring pe română → filtrul de diacritice bloca sinteza → tăcere. - tools/tts.py: helper public engine_for_voice() (catalog → tts.default_engine) - src/router.py: injectează [tts-lang:en] în prefixul voice când vocea activă e pockettts (config citit fresh — vede swap-ul live /voice setvoice); anti-jailbreak strip extins la [tts-lang:...] - personality/VOICE_MODE.md: regulă de limbă gated pe marker - tests/test_router.py: 5 teste noi pentru marker + strip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,10 +32,11 @@ log = logging.getLogger(__name__)
|
||||
|
||||
APPROVED_TASKS_FILE = Path(__file__).parent.parent / "approved-tasks.json"
|
||||
|
||||
# Anti-jailbreak: strip user-controlled leading [voice] / [speaker:...]
|
||||
# tokens so they cannot impersonate the system-injected prefix on voice turns.
|
||||
# Anti-jailbreak: strip user-controlled leading [voice] / [speaker:...] /
|
||||
# [tts-lang:...] tokens so they cannot impersonate the system-injected
|
||||
# prefix on voice turns.
|
||||
_LEADING_VOICE_TOKEN_RE = re.compile(
|
||||
r'^\s*(?:\[voice\]|\[speaker:[^\]]*\])\s*', re.IGNORECASE
|
||||
r'^\s*(?:\[voice\]|\[speaker:[^\]]*\]|\[tts-lang:[^\]]*\])\s*', re.IGNORECASE
|
||||
)
|
||||
|
||||
|
||||
@@ -46,6 +47,24 @@ def _strip_leading_voice_tokens(text: str) -> str:
|
||||
return text
|
||||
text = stripped
|
||||
|
||||
|
||||
def _voice_turn_lang_marker() -> str:
|
||||
"""`'[tts-lang:en] '` dacă vocea activă de voice mode e pe un engine
|
||||
English-only (pocket-tts), altfel `''`.
|
||||
|
||||
Citește config fresh de pe disc (nu singleton-ul modulului) pentru că
|
||||
`/voice setvoice` și swap-ul in-band persistă `voice.default_voice` live,
|
||||
printr-o altă instanță Config.
|
||||
"""
|
||||
try:
|
||||
from tools.tts import engine_for_voice
|
||||
voice = Config().get("voice.default_voice", "M2") or "M2"
|
||||
if engine_for_voice(voice) == "pockettts":
|
||||
return "[tts-lang:en] "
|
||||
except Exception as e: # noqa: BLE001
|
||||
log.warning("voice lang marker lookup failed: %s", e)
|
||||
return ""
|
||||
|
||||
# Module-level config instance (lazy singleton)
|
||||
_config: Config | None = None
|
||||
|
||||
@@ -177,7 +196,7 @@ def route_message(
|
||||
voice_mode = adapter_name == "discord-voice"
|
||||
if voice_mode:
|
||||
user_name = _get_config().get("voice.user_name", "user") or "user"
|
||||
claude_text = f"[voice] [speaker:{user_name}] {text}"
|
||||
claude_text = f"[voice] [speaker:{user_name}] {_voice_turn_lang_marker()}{text}"
|
||||
session_key = channel_id
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user