fix: persona uses settings output_language, matching the reply directive
The persona prompt was built from the raw OUTPUT_LANGUAGE env while the reply-language directive read the settings-web UI value (config JSON), so changing the language in the settings page was honoured by the directive but ignored by the persona, leaving them contradicting each other. Add _resolve_output_language() as the single source of truth (config wins over env) and feed the same resolved value to both build_system_prompt() and reply_language_directive(). Update docs/llm_contexts.md to match. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
74
tests/test_output_language_resolution.py
Normal file
74
tests/test_output_language_resolution.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""The locked reply language must have a single source of truth.
|
||||
|
||||
Regression: the persona prompt was built from the raw ``OUTPUT_LANGUAGE`` env
|
||||
while the reply-language directive read the settings-UI value (config JSON).
|
||||
Changing the language in the settings page rewrote the directive but left the
|
||||
persona contradicting it. ``_resolve_output_language`` is now the one resolver
|
||||
both call sites use, so they cannot diverge.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_settings_value_wins_over_env(monkeypatch, tmp_path):
|
||||
from jarvis.reply.engine import _resolve_output_language
|
||||
|
||||
cfg_path = tmp_path / "config.json"
|
||||
cfg_path.write_text('{"output_language": "Korean"}', encoding="utf-8")
|
||||
monkeypatch.setenv("JARVIS_CONFIG_PATH", str(cfg_path))
|
||||
monkeypatch.setenv("OUTPUT_LANGUAGE", "English")
|
||||
|
||||
# The settings page value must take effect over the compose env default.
|
||||
assert _resolve_output_language() == "Korean"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_env_used_when_settings_absent(monkeypatch, tmp_path):
|
||||
from jarvis.reply.engine import _resolve_output_language
|
||||
|
||||
cfg_path = tmp_path / "config.json"
|
||||
cfg_path.write_text("{}", encoding="utf-8")
|
||||
monkeypatch.setenv("JARVIS_CONFIG_PATH", str(cfg_path))
|
||||
monkeypatch.setenv("OUTPUT_LANGUAGE", "English")
|
||||
|
||||
assert _resolve_output_language() == "English"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_unset_when_neither_configured(monkeypatch, tmp_path):
|
||||
from jarvis.reply.engine import _resolve_output_language
|
||||
|
||||
cfg_path = tmp_path / "config.json"
|
||||
cfg_path.write_text("{}", encoding="utf-8")
|
||||
monkeypatch.setenv("JARVIS_CONFIG_PATH", str(cfg_path))
|
||||
monkeypatch.delenv("OUTPUT_LANGUAGE", raising=False)
|
||||
|
||||
# Empty string or None both mean "no lock" downstream; normalise the check.
|
||||
assert not _resolve_output_language()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_persona_and_directive_agree_on_settings_value(monkeypatch, tmp_path):
|
||||
"""End-to-end: the same resolved value feeds the persona and the directive,
|
||||
so a settings-UI language can't be honoured by one and ignored by the other.
|
||||
"""
|
||||
from jarvis.reply.engine import _resolve_output_language
|
||||
from jarvis.system_prompt import build_system_prompt, reply_language_directive
|
||||
|
||||
cfg_path = tmp_path / "config.json"
|
||||
cfg_path.write_text('{"output_language": "Korean"}', encoding="utf-8")
|
||||
monkeypatch.setenv("JARVIS_CONFIG_PATH", str(cfg_path))
|
||||
monkeypatch.setenv("OUTPUT_LANGUAGE", "English")
|
||||
|
||||
lang = _resolve_output_language()
|
||||
persona = build_system_prompt("Jarvis", lang)
|
||||
directive = reply_language_directive(lang, "melo")
|
||||
|
||||
# Persona's user-language clause is rewritten to Korean, not English...
|
||||
assert "in Korean" in persona
|
||||
assert "in English" not in persona
|
||||
# ...and the directive locks to the same Korean. (The directive may name
|
||||
# English as a counter-example - "even if the user writes in English" - so
|
||||
# we assert the lock target, not the mere absence of the word "English".)
|
||||
assert directive is not None and "Korean" in directive
|
||||
Reference in New Issue
Block a user