diff --git a/src/jarvis/reply/engine.py b/src/jarvis/reply/engine.py index 2ddfe99..d04c41c 100644 --- a/src/jarvis/reply/engine.py +++ b/src/jarvis/reply/engine.py @@ -1704,6 +1704,12 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any], # else: tools are passed via the native tools API parameter — do not include tools_desc # here as well, since that confuses the model and causes it to not use tools properly. + # Recency reinforcement: repeat the language lock at the very END too. + # In a ~5k-token prompt the front-placed rule gets "lost in the middle"; + # bigger models (qwen2.5:7b) otherwise leak Chinese/Cyrillic mid-reply. + if _lang_directive: + guidance.append(_lang_directive) + return "\n".join(guidance) messages = [] # type: ignore[var-annotated] diff --git a/src/jarvis/system_prompt.py b/src/jarvis/system_prompt.py index c68b8aa..15e90cb 100644 --- a/src/jarvis/system_prompt.py +++ b/src/jarvis/system_prompt.py @@ -133,8 +133,12 @@ def output_language_directive(language: Optional[str]) -> Optional[str]: f"CRITICAL OUTPUT RULE: write your ENTIRE reply only in {lang}. Even if " f"the user writes in English or any other language, you must still reply " f"only in {lang}. This rule overrides every other instruction about " - f"matching or using the user's language. Never mix in words, characters, " - f"or punctuation from any other language or script." + f"matching or using the user's language. Do NOT output a single Chinese/" + f"Hanja character, Japanese kana, Cyrillic letter, Arabic letter, or any " + f"other non-{lang} script anywhere in the reply — not even one word or " + f"clause. If a {lang} word exists, use it; never substitute or append a " + f"foreign-language equivalent. (Numerals and unavoidable proper-noun " + f"brand names are fine.)" )