From a0d33dffdc8e9ca424ccf548cbfe53b87a76338b Mon Sep 17 00:00:00 2001 From: tt-P607 <68868379+tt-P607@users.noreply.github.com> Date: Mon, 15 Sep 2025 03:04:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(emoji):=20=E9=81=BF=E5=85=8D=E5=8F=91?= =?UTF-8?q?=E9=80=81=E8=BF=91=E6=9C=9F=E4=BD=BF=E7=94=A8=E8=BF=87=E7=9A=84?= =?UTF-8?q?=E8=A1=A8=E6=83=85=E5=8C=85=E4=BB=A5=E5=87=8F=E5=B0=91=E9=87=8D?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为了提升表情包发送的自然度和多样性,引入了表情包历史记录机制。 该功能通过以下方式工作: - 在选择表情包之前,系统会获取当前会话最近发送过的表情包记录。 - 从候选表情包池中过滤掉这些近期已使用过的表情,从而鼓励使用更多不同的表情。 - 当一个表情包成功发送后,其描述会被添加到历史记录中,用于未来的筛选。 --- src/chat/emoji_system/emoji_history.py | 59 ++++++++++++++++++++++ src/plugins/built_in/core_actions/emoji.py | 27 ++++++++-- 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/chat/emoji_system/emoji_history.py diff --git a/src/chat/emoji_system/emoji_history.py b/src/chat/emoji_system/emoji_history.py new file mode 100644 index 000000000..a25063f52 --- /dev/null +++ b/src/chat/emoji_system/emoji_history.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" +表情包发送历史记录模块 +""" +import os +from typing import List, Dict +from collections import deque + +from src.common.logger import get_logger + +logger = get_logger("EmojiHistory") + +MAX_HISTORY_SIZE = 5 # 每个聊天会话最多保留最近5条表情历史 + +# 使用一个全局字典在内存中存储历史记录 +# 键是 chat_id,值是一个 deque 对象 +_history_cache: Dict[str, deque] = {} + + +def add_emoji_to_history(chat_id: str, emoji_description: str): + """ + 将发送的表情包添加到内存历史记录中。 + + :param chat_id: 聊天会话ID (例如 "private_12345" 或 "group_67890") + :param emoji_description: 发送的表情包的描述 + """ + if not chat_id or not emoji_description: + return + + # 如果当前聊天还没有历史记录,则创建一个新的 deque + if chat_id not in _history_cache: + _history_cache[chat_id] = deque(maxlen=MAX_HISTORY_SIZE) + + # 添加新表情到历史记录 + history = _history_cache[chat_id] + history.append(emoji_description) + + logger.debug(f"已将表情 '{emoji_description}' 添加到聊天 {chat_id} 的内存历史中") + + +def get_recent_emojis(chat_id: str, limit: int = 5) -> List[str]: + """ + 从内存中获取最近发送的表情包描述列表。 + + :param chat_id: 聊天会话ID + :param limit: 获取的表情数量上限 + :return: 最近发送的表情包描述列表 + """ + if not chat_id or chat_id not in _history_cache: + return [] + + history = _history_cache[chat_id] + + # 从 deque 的右侧(即最近添加的)开始取 + num_to_get = min(limit, len(history)) + recent_emojis = [history[-i] for i in range(1, num_to_get + 1)] + + logger.debug(f"为聊天 {chat_id} 从内存中获取到最近 {len(recent_emojis)} 个表情: {recent_emojis}") + return recent_emojis diff --git a/src/plugins/built_in/core_actions/emoji.py b/src/plugins/built_in/core_actions/emoji.py index c29a9394b..4375ae1a2 100644 --- a/src/plugins/built_in/core_actions/emoji.py +++ b/src/plugins/built_in/core_actions/emoji.py @@ -12,6 +12,7 @@ from src.plugin_system.apis import llm_api, message_api from src.chat.emoji_system.emoji_manager import get_emoji_manager, MaiEmoji from src.chat.utils.utils_image import image_path_to_base64 from src.config.config import global_config +from src.chat.emoji_system.emoji_history import get_recent_emojis, add_emoji_to_history logger = get_logger("emoji") @@ -74,9 +75,22 @@ class EmojiAction(BaseAction): logger.warning(f"{self.log_prefix} 无法获取任何带有描述的有效表情包") return False, "无法获取任何带有描述的有效表情包" - # 3. 准备情感数据和后备列表 + # 3. 根据历史记录筛选表情 + try: + recent_emojis_desc = get_recent_emojis(self.chat_id, limit=10) + if recent_emojis_desc: + filtered_emojis = [emoji for emoji in all_emojis_obj if emoji.description not in recent_emojis_desc] + if filtered_emojis: + all_emojis_obj = filtered_emojis + logger.info(f"{self.log_prefix} 根据历史记录过滤后,剩余 {len(all_emojis_obj)} 个表情可用") + else: + logger.warning(f"{self.log_prefix} 过滤后没有可用的表情包,将使用所有表情包") + except Exception as e: + logger.error(f"{self.log_prefix} 获取或处理表情发送历史时出错: {e}") + + # 4. 准备情感数据和后备列表 emotion_map = {} - all_emojis_data = [] + all_emojis_data = [] for emoji in all_emojis_obj: b64 = image_path_to_base64(emoji.full_path) @@ -236,13 +250,20 @@ class EmojiAction(BaseAction): logger.error(f"{self.log_prefix} 无效的表情选择模式: {global_config.emoji.emoji_selection_mode}") return False, "无效的表情选择模式" - # 7. 发送表情包 + # 7. 发送表情包并记录历史 success = await self.send_emoji(emoji_base64) if not success: logger.error(f"{self.log_prefix} 表情包发送失败") await self.store_action_info(action_build_into_prompt = True,action_prompt_display =f"发送了一个表情包,但失败了",action_done= False) return False, "表情包发送失败" + + # 发送成功后,记录到历史 + try: + add_emoji_to_history(self.chat_id, emoji_description) + except Exception as e: + logger.error(f"{self.log_prefix} 添加表情到历史记录时出错: {e}") + await self.store_action_info(action_build_into_prompt = True,action_prompt_display =f"发送了一个表情包",action_done= True) return True, f"发送表情包: {emoji_description}"