diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 84e3e53..22bab02 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -51,12 +51,18 @@ export JARVIS_CONFIG_PATH=/app/config/jarvis.json # the env-rendered config, so changes survive container recreate. if [ -f /data/jarvis-settings.json ]; then python3 - <<'PY' || true -import json +import json, os try: base = json.load(open("/app/config/jarvis.json")) ov = json.load(open("/data/jarvis-settings.json")) if isinstance(base, dict) and isinstance(ov, dict): base.update(ov) + # A stale persisted tts_engine from an earlier voice (melo/xtts, no + # longer built into the image) would override the configured engine and + # leave the bot silent. Reset those to the env-configured engine. + if base.get("tts_engine") in ("melo", "xtts"): + base["tts_engine"] = os.environ.get("TTS_ENGINE", "edge") + print(f"[entrypoint] reset stale tts_engine -> {base['tts_engine']}") json.dump(base, open("/app/config/jarvis.json", "w"), ensure_ascii=False, indent=2) print("[entrypoint] merged persistent settings overrides") except Exception as e: diff --git a/src/jarvis/config.py b/src/jarvis/config.py index cbc61f1..854861f 100644 --- a/src/jarvis/config.py +++ b/src/jarvis/config.py @@ -608,7 +608,11 @@ def load_settings() -> Settings: active_profiles = _ensure_list(merged.get("active_profiles")) tts_enabled = bool(merged.get("tts_enabled", True)) tts_engine = str(merged.get("tts_engine", "piper")).lower() - if tts_engine not in ("piper", "chatterbox"): + # "edge" (Microsoft Edge TTS) is the containerized bridge's Korean voice; + # "melo" is the legacy warm-worker voice. Both are multilingual, so they must + # be preserved here — coercing them to "piper" would mislabel the engine as + # English-only in reply_language_directive(). + if tts_engine not in ("piper", "chatterbox", "edge", "melo"): tts_engine = "piper" # Default to piper if invalid value tts_voice_val = merged.get("tts_voice") tts_voice = None if tts_voice_val in (None, "", "null") else str(tts_voice_val) diff --git a/tests/test_system_prompt.py b/tests/test_system_prompt.py index 3134989..0b497c4 100644 --- a/tests/test_system_prompt.py +++ b/tests/test_system_prompt.py @@ -110,6 +110,14 @@ class TestReplyLanguageDirective: directive = reply_language_directive("Korean", "melo") assert directive is not None and "Korean" in directive + def test_edge_is_multilingual(self): + # Edge TTS (the default Korean voice) is not English-only: no lock → the + # user's own language, and a lock is honoured (not forced to English). + assert reply_language_directive(None, "edge") is None + directive = reply_language_directive("Korean", "edge") + assert directive is not None and "Korean" in directive + assert directive != ENGLISH_ONLY_DIRECTIVE + class TestLoadAgentInstructions: """Operator can extend the reply LLM's system prompt by dropping *.md files