From 94bf6214902ec46e308d1763f08d998c16071672 Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Thu, 19 Feb 2026 09:06:07 +0200 Subject: [PATCH] fix: memory persistence + language auto-detection for translation workflow - Upgrade memory/translation debug logs from debug to warning level - Auto-detect language preference from extracted memory facts - Persist language prefs to separate JSON file for reliability - Add translation detection logging - Use single linebreaks in translation menu Co-Authored-By: Claude Opus 4.6 --- bot.py | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/bot.py b/bot.py index 61a3cd2..d56794b 100644 --- a/bot.py +++ b/bot.py @@ -61,6 +61,7 @@ WILDFILES_BASE_URL = os.environ.get("WILDFILES_BASE_URL", "") WILDFILES_ORG = os.environ.get("WILDFILES_ORG", "") USER_KEYS_FILE = os.environ.get("USER_KEYS_FILE", "/data/user_keys.json") MEMORIES_DIR = os.environ.get("MEMORIES_DIR", "/data/memories") +LANGUAGE_PREFS_FILE = os.environ.get("LANGUAGE_PREFS_FILE", "/data/language_prefs.json") MAX_MEMORIES_PER_USER = 50 SYSTEM_PROMPT = """You are a helpful AI assistant in a Matrix chat room. @@ -220,6 +221,7 @@ class Bot: self._pending_connects: dict[str, str] = {} # matrix_user_id -> device_code self._pending_translate: dict[str, dict] = {} # sender -> {text, detected_lang, room_id} self._pending_reply: dict[str, dict] = {} # sender -> {target_lang} + self.language_prefs: dict[str, str] = self._load_language_prefs() # user_id -> language @staticmethod def _load_user_keys() -> dict[str, str]: @@ -239,6 +241,23 @@ class Bot: except Exception: logger.exception("Failed to save user keys") + @staticmethod + def _load_language_prefs() -> dict[str, str]: + if os.path.exists(LANGUAGE_PREFS_FILE): + try: + with open(LANGUAGE_PREFS_FILE) as f: + return json.load(f) + except Exception: + logger.warning("Failed to load language prefs, starting fresh") + return {} + + def _save_language_prefs(self): + try: + with open(LANGUAGE_PREFS_FILE, "w") as f: + json.dump(self.language_prefs, f) + except Exception: + logger.exception("Failed to save language prefs") + async def start(self): # Restore existing session or create new one if os.path.exists(CREDS_FILE): @@ -488,10 +507,21 @@ class Bot: for fact in new_facts: if isinstance(fact, str) and fact.strip(): existing.append({"fact": fact.strip(), "created": now, "source_room": room_id}) + # Auto-detect language preference from new facts + fl = fact.lower() + if "language" in fl or "speaks" in fl or "prefers" in fl: + for lang in ["English", "German", "French", "Spanish", "Italian", + "Portuguese", "Dutch", "Russian", "Chinese", "Japanese", + "Korean", "Arabic", "Turkish", "Greek", "Hebrew"]: + if lang.lower() in fl: + self.language_prefs[sender] = lang + self._save_language_prefs() + logger.info("Auto-detected language preference: %s for %s", lang, sender) + break return existing except Exception: - logger.debug("Memory extraction failed", exc_info=True) + logger.warning("Memory extraction failed", exc_info=True) return existing async def _detect_language(self, text: str) -> str: @@ -531,7 +561,11 @@ class Bot: return f"[Translation failed] {text}" def _get_preferred_language(self, user_id: str) -> str: - """Extract user's preferred language from memories, default English.""" + """Get user's preferred language from explicit prefs, then memories, default English.""" + # Check explicit language preference first + if user_id in self.language_prefs: + return self.language_prefs[user_id] + # Fallback: scan memories memories = self._load_memories(user_id) known_langs = [ "English", "German", "French", "Spanish", "Italian", "Portuguese", @@ -639,6 +673,7 @@ class Bot: if is_dm and not body.startswith("!ai") and not image_data: preferred_lang = self._get_preferred_language(sender) detected_lang = await self._detect_language(body) + logger.info("Translation check: detected=%s, preferred=%s, len=%d", detected_lang, preferred_lang, len(body)) if ( detected_lang != "Unknown" and detected_lang.lower() != preferred_lang.lower() @@ -650,7 +685,7 @@ class Bot: "room_id": room.room_id, } menu = ( - f"This looks like **{detected_lang}**. What would you like?\n\n" + f"This looks like **{detected_lang}**. What would you like?\n" f"1️⃣ **Translate to {preferred_lang}**\n" f"2️⃣ **Help me reply in {detected_lang}** (type your response, I'll translate)\n" f"3️⃣ **Just respond normally**" @@ -1181,8 +1216,10 @@ class Bot: self._save_memories(sender, updated) logger.info("Saved %d new memories for %s (total: %d)", len(updated) - len(memories), sender, len(updated)) + else: + logger.info("No new memories extracted for %s", sender) except Exception: - logger.debug("Memory save failed", exc_info=True) + logger.warning("Memory save failed", exc_info=True) # Auto-rename: only for group rooms with explicit opt-in (not DMs) if room.room_id in self.auto_rename_rooms: