fix: silently cache images in group rooms without mention

Same pattern as files: download and cache in _recent_images without
responding. When user next @mentions the bot, the cached image is
available as context. Applied to both plain and encrypted image handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-03-20 15:42:13 +00:00
parent cb5f057006
commit dcee2d30d5

23
bot.py
View File

@@ -2187,23 +2187,20 @@ class Bot:
await self._load_room_settings(room.room_id) await self._load_room_settings(room.room_id)
# In DMs respond to all images; in groups only if bot was recently @mentioned # In DMs respond to all images; in groups, silently cache (respond only if mentioned)
is_dm = room.member_count == 2 is_dm = room.member_count == 2
group_mentioned = False
if not is_dm: if not is_dm:
# Check if bot was @mentioned in the image body (caption) or skip
body = (event.body or "").strip() body = (event.body or "").strip()
bot_display = self.client.user_id.split(":")[0].lstrip("@") bot_display = self.client.user_id.split(":")[0].lstrip("@")
# Also match display name (e.g. 'Claude') since Element uses it in mentions
bot_displayname = (getattr(self, '_display_name', '') or bot_display).lower() bot_displayname = (getattr(self, '_display_name', '') or bot_display).lower()
body_lower = body.lower() body_lower = body.lower()
mentioned = ( group_mentioned = (
BOT_USER in body BOT_USER in body
or f"@{bot_display}" in body_lower or f"@{bot_display}" in body_lower
or bot_display.lower() in body_lower or bot_display.lower() in body_lower
or bot_displayname in body_lower or bot_displayname in body_lower
) )
if not mentioned:
return
if not self.llm: if not self.llm:
await self._send_text(room.room_id, "LLM not configured (LITELLM_BASE_URL not set).") await self._send_text(room.room_id, "LLM not configured (LITELLM_BASE_URL not set).")
@@ -2235,6 +2232,11 @@ class Bot:
# Cache image for follow-up text messages # Cache image for follow-up text messages
self._recent_images[room.room_id] = (b64_data, mime_type, time.time()) self._recent_images[room.room_id] = (b64_data, mime_type, time.time())
# In group rooms without mention, silently cache — respond on next @mention
if not is_dm and not group_mentioned:
logger.info("Silently cached image in group room %s", room.room_id)
return
await self.client.room_typing(room.room_id, typing_state=True) await self.client.room_typing(room.room_id, typing_state=True)
try: try:
reply = await self._respond_with_ai(room, text, sender=event.sender, image_data=(b64_data, mime_type)) reply = await self._respond_with_ai(room, text, sender=event.sender, image_data=(b64_data, mime_type))
@@ -2266,14 +2268,12 @@ class Bot:
# Also match display name (e.g. 'Claude') since Element uses it in mentions # Also match display name (e.g. 'Claude') since Element uses it in mentions
bot_displayname = (getattr(self, '_display_name', '') or bot_display).lower() bot_displayname = (getattr(self, '_display_name', '') or bot_display).lower()
body_lower = body.lower() body_lower = body.lower()
mentioned = ( group_mentioned = (
BOT_USER in body BOT_USER in body
or f"@{bot_display}" in body_lower or f"@{bot_display}" in body_lower
or bot_display.lower() in body_lower or bot_display.lower() in body_lower
or bot_displayname in body_lower or bot_displayname in body_lower
) )
if not mentioned:
return
if not self.llm: if not self.llm:
await self._send_text(room.room_id, "LLM not configured (LITELLM_BASE_URL not set).") await self._send_text(room.room_id, "LLM not configured (LITELLM_BASE_URL not set).")
@@ -2303,6 +2303,11 @@ class Bot:
# Cache image for follow-up text messages # Cache image for follow-up text messages
self._recent_images[room.room_id] = (b64_data, mime_type, time.time()) self._recent_images[room.room_id] = (b64_data, mime_type, time.time())
# In group rooms without mention, silently cache — respond on next @mention
if not is_dm and not group_mentioned:
logger.info("Silently cached encrypted image in group room %s", room.room_id)
return
await self.client.room_typing(room.room_id, typing_state=True) await self.client.room_typing(room.room_id, typing_state=True)
try: try:
reply = await self._respond_with_ai(room, text, sender=event.sender, image_data=(b64_data, mime_type)) reply = await self._respond_with_ai(room, text, sender=event.sender, image_data=(b64_data, mime_type))