From 76f2054cbc738c3ada2d2c897cf0f211a4ba623a Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 10 Jul 2025 03:19:04 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=9B=B4=E7=B2=BE=E5=87=86?= =?UTF-8?q?=E7=9A=84=E8=A1=A8=E6=83=85=E5=8C=85=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interested_rates.txt | 532 +++++++++++++++++++++ src/plugin_system/apis/emoji_api.py | 50 +- src/plugins/built_in/core_actions/emoji.py | 86 +++- 3 files changed, 640 insertions(+), 28 deletions(-) diff --git a/interested_rates.txt b/interested_rates.txt index 61a726d58..7d28a45b2 100644 --- a/interested_rates.txt +++ b/interested_rates.txt @@ -86,3 +86,535 @@ 8.65717782684436 8.65717782684436 0.020373848987042205 +2.593162350695633 +0.03203964454588806 +0.030243923387959913 +0.0416831084528021 +0.030906331331691177 +0.02988194581614903 +0.018026305204928966 +0.11700260384441222 +0.030906331331691177 +0.027344556981661584 +0.02126634371149695 +0.2834179621067139 +0.02388322700338219 +0.03203964454588806 +0.03507388656058557 +0.02789637960584667 +0.038092068217251376 +6.085021562321503 +6.257759651223436 +6.257759651223436 +6.261399141577353 +0.0233314043791971 +0.21168647349950526 +0.19712509049144 +5.316296238400273 +6.257759651223436 +6.087979117713658 +0.03203964454588806 +0.02949581907331921 +6.085021562321503 +0.030416764741305155 +0.11267641525791106 +0.12199466703464368 +0.1143420240782623 +0.19440388446077916 +0.2843589069495348 +5.99521828087802 +0.026403612138840668 +0.02203945780739345 +6.086687171141854 +0.2843589069495348 +0.018026305204928966 +0.043042772233490977 +0.018026305204928966 +0.027047581355656602 +0.19440388446077916 +6.093047867526432 +6.087979117713658 +2.594083296363619 +2.585705989429707 +2.585705989429707 +8.653593741270736 +2.826573104095818 +2.826573104095818 +0.03822619982285357 +0.019318251776732617 +0.019318251776732617 +0.02969210076377482 +0.027344556981661584 +0.014013152602464482 +0.0233314043791971 +0.020373848987042205 +1.5677584375174967 +1.5677584375174967 +0.024387001589506692 +0.03203964454588806 +0.02203945780739345 +0.03654584002545838 +0.027627040096074675 +0.028153744436359526 +0.025279496313961432 +0.024387001589506692 +0.03203964454588806 +0.025279496313961432 +0.02126634371149695 +0.024387001589506692 +0.020373848987042205 +0.027344556981661584 +0.0233314043791971 +0.02567894816131034 +0.018026305204928966 +0.027344556981661584 +0.19440388446077916 +0.02605261040985793 +1.6115788768356085 +1.4640532917116755 +0.5632634498831727 +1.610569413378218 +0.018026305204928966 +6.257759651223436 +0.03203964454588806 +0.56584734302678 +0.018026305204928966 +1.4672933302182436 +2.5897191420321715 +0.02203945780739345 +0.026403612138840668 +1.6115788768356085 +0.18909878528651103 +0.5588766350321606 +0.032987018878939844 +0.02567894816131034 +1.4784402933011822 +0.02988194581614903 +0.0366628087583942 +0.019318251776732617 +0.025279496313961432 +0.035988106471349056 +0.028400154191971172 +1.6131862966701032 +0.19273827564042792 +0.019318251776732617 +0.016360696384577725 +0.0339877364806524 +0.03203964454588806 +0.026734545371619928 +1.6124381923554625 +0.02203945780739345 +0.03203964454588806 +0.018026305204928966 +1.5959562832018463 +0.02203945780739345 +0.03551382637263636 +0.037267027716268906 +3.124491258589239 +0.610536110598576 +0.566399165650965 +0.018026305204928966 +0.03203964454588806 +0.5704647145871191 +0.02485042928512086 +0.03731895412135488 +0.037267027716268906 +0.026734545371619928 +0.019318251776732617 +3.825397466366432 +0.03203964454588806 +0.026403612138840668 +0.03229141270573031 +0.19827045314881617 +0.036365833132389225 +0.027627040096074675 +0.026734545371619928 +0.03624264220072675 +0.11700260384441222 +0.03507388656058557 +0.11700260384441222 +0.03229141270573031 +0.03605279714835254 +0.0361800496412885 +0.019318251776732617 +0.03507388656058557 +0.03514957071487914 +0.03241330679443565 +0.018026305204928966 +0.03795475533019785 +0.019318251776732617 +0.022721392769155448 +0.018026305204928966 +0.02388322700338219 +0.02126634371149695 +0.033201478780114806 +0.03203964454588806 +0.03897162493552239 +0.03705453578090416 +0.03624264220072675 +0.03605279714835254 +0.02605261040985793 +0.024387001589506692 +0.018026305204928966 +0.019318251776732617 +0.026403612138840668 +0.02789637960584667 +0.025279496313961432 +0.03203964454588806 +0.02203945780739345 +0.03203964454588806 +0.028153744436359526 +0.03121112566969858 +0.028400154191971172 +0.03203964454588806 +0.5695382791300162 +0.1937590804309808 +0.565933984965691 +0.03813712490657174 +0.5715465770356281 +0.03121112566969858 +0.020373848987042205 +0.025279496313961432 +0.019318251776732617 +0.018026305204928966 +0.03203964454588806 +0.02388322700338219 +0.26173176064750214 +0.03203964454588806 +0.025279496313961432 +0.5602977928297127 +0.19159146701500568 +0.02203945780739345 +0.11253719536395454 +0.21313854738561544 +0.028400154191971172 +0.02988194581614903 +0.018026305204928966 +0.6417882275234562 +0.02605261040985793 +5.977571304755818 +0.025279496313961432 +0.19325707583535692 +0.02126634371149695 +0.11534816684168195 +0.014013152602464482 +0.019318251776732617 +0.016360696384577725 +0.11655034796641901 +0.5509394882379124 +0.02567894816131034 +0.022721392769155448 +0.02388322700338219 +0.037908251021078 +0.020373848987042205 +0.027344556981661584 +0.03203964454588806 +0.022721392769155448 +0.036604619772537636 +0.022721392769155448 +0.024387001589506692 +0.19401122364832826 +0.02485042928512086 +1.3250588305259812 +0.02988194581614903 +0.016360696384577725 +0.028400154191971172 +2.693552043972918 +1.3895563870015402 +0.03578958112445851 +0.18870612447406013 +0.5708924583987018 +6.024690626754802 +0.0233314043791971 +0.19456304627251336 +0.02126634371149695 +0.8999568498738115 +0.0233314043791971 +0.02789637960584667 +0.03203964454588806 +0.018026305204928966 +0.03203964454588806 +0.018026305204928966 +0.03705453578090416 +0.019318251776732617 +0.019318251776732617 +0.019318251776732617 +0.02863650355346524 +0.02567894816131034 +0.2849203145574192 +0.02485042928512086 +0.02126634371149695 +0.0233314043791971 +0.024387001589506692 +0.026403612138840668 +0.020373848987042205 +0.19456304627251336 +0.030243923387959913 +0.02126634371149695 +0.02949581907331921 +0.026403612138840668 +0.03203964454588806 +0.022721392769155448 +0.014013152602464482 +0.03203964454588806 +6.1175478095986575 +0.02203945780739345 +0.0233314043791971 +0.027344556981661584 +0.020373848987042205 +0.03203964454588806 +0.02126634371149695 +0.02908208915373317 +0.014013152602464482 +0.19401122364832826 +0.018026305204928966 +0.02126634371149695 +0.019318251776732617 +0.020373848987042205 +0.02203945780739345 +0.02988194581614903 +0.03203964454588806 +0.7418853136518697 +0.02203945780739345 +1.3342940300608033 +0.1927893605828308 +0.02605261040985793 +7.413181479797994 +0.1899783891051034 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.03203964454588806 +0.03203964454588806 +0.014013152602464482 +6.2640940646555245 +2.328988930886535 +0.022721392769155448 +0.026734545371619928 +0.018026305204928966 +6.264094064655525 +5.1914900462266145 +0.12023955698857974 +0.9447480869881139 +0.02789637960584667 +6.107820928916661 +0.5743239036953584 +0.022721392769155448 +0.02789637960584667 +0.03642645939690014 +0.019318251776732617 +0.018026305204928966 +0.030065763012322416 +0.026403612138840668 +0.19528348827937153 +0.014013152602464482 +0.020373848987042205 +5.953352859746529 +0.02988194581614903 +0.03654584002545838 +6.093433927327155 +6.1081945911652085 +0.1273249173506878 +0.019318251776732617 +0.016360696384577725 +0.4644360345195811 +6.2640940646555245 +0.016360696384577725 +0.5000527117671028 +0.03203964454588806 +0.018026305204928966 +0.019318251776732617 +0.19528348827937153 +0.03705453578090416 +0.016360696384577725 +6.094489524537464 +0.022721392769155448 +0.02908208915373317 +6.096155133357815 +0.018026305204928966 +0.03425707599042439 +0.02126634371149695 +0.1264437639723824 +6.098502677139929 +1.0349194839341556 +6.1079166295311955 +0.0363045653081948 +6.099794623711732 +0.19528348827937153 +0.02388322700338219 +0.02388322700338219 +0.02388322700338219 +0.02388322700338219 +1.5937175408447852 +1.0238832270033822 +6.264094064655525 +0.18831278028475215 +0.18831278028475215 +0.18920527500920692 +0.18831278028475215 +0.18831278028475215 +6.264094064655525 +6.264094064655525 +6.264094064655525 +6.270918188735718 +6.270918188735718 +6.270918188735718 +0.1284929405276288 +0.024387001589506692 +0.03203964454588806 +0.014013152602464482 +0.018026305204928966 +0.1927893605828308 +0.02485042928512086 +0.03642645939690014 +0.016360696384577725 +0.03203964454588806 +0.03203964454588806 +0.19528348827937153 +0.028153744436359526 +0.02203945780739345 +0.022721392769155448 +0.03203964454588806 +0.024387001589506692 +0.036889887092514305 +0.03203964454588806 +0.02126634371149695 +0.016360696384577725 +0.024387001589506692 +0.027047581355656602 +0.02126634371149695 +0.026403612138840668 +0.03203964454588806 +0.03203964454588806 +0.020373848987042205 +0.02567894816131034 +0.02203945780739345 +0.020373848987042205 +0.03642645939690014 +0.12550917108780713 +0.022721392769155448 +0.02126634371149695 +0.020373848987042205 +0.02203945780739345 +0.02126634371149695 +0.032987018878939844 +0.020373848987042205 +0.02388322700338219 +0.019318251776732617 +0.02908208915373317 +0.03203964454588806 +0.02388322700338219 +0.0233314043791971 +0.022721392769155448 +0.019318251776732617 +0.02969210076377482 +0.016360696384577725 +0.022721392769155448 +0.03544278553831089 +0.018026305204928966 +0.018026305204928966 +0.022721392769155448 +0.02126634371149695 +0.019318251776732617 +0.19657532621243082 +0.034597748090694054 +0.03203964454588806 +0.03203964454588806 +0.02485042928512086 +0.03241330679443565 +0.02203945780739345 +0.014013152602464482 +0.020373848987042205 +0.027627040096074675 +1.4066375852507782 +0.02126634371149695 +0.03710839435866214 +0.11715812159281318 +0.024387001589506692 +0.014013152602464482 +0.028400154191971172 +0.03800088908311688 +0.022721392769155448 +0.02126634371149695 +0.016360696384577725 +0.018026305204928966 +0.03203964454588806 +0.018026305204928966 +1.4606587109145759 +0.027344556981661584 +0.027047581355656602 +0.19631537111376607 +0.03522427827216307 +0.019318251776732617 +0.03203964454588806 +0.019318251776732617 +0.03529803411491245 +0.02203945780739345 +0.024387001589506692 +0.19788719264057633 +0.019318251776732617 +0.025279496313961432 +0.19788719264057633 +0.03203964454588806 +0.037267027716268906 +1.9426549475864308 +0.02863650355346524 +0.19788719264057633 +0.025279496313961432 +0.040617772375002116 +0.014013152602464482 +0.042059810740987885 +0.03203964454588806 +0.022721392769155448 +0.19788719264057633 +0.04192140362354248 +0.02789637960584667 +0.02203945780739345 +0.033800953980773776 +2.5587523795311893 +0.036833946992045466 +0.19788719264057633 +6.05966908428223 +0.033800953980773776 +6.06239029031289 +6.05966908428223 +0.0363045653081948 +0.1953930649440356 +0.014013152602464482 +0.018026305204928966 +1.4384500897093555 +1.6635593742584274 +0.02203945780739345 +8.603668187263336 +0.02126634371149695 +6.05966908428223 +6.067398413861153 +1.0334082777402342 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +0.014013152602464482 +6.070042933269272 +0.0233314043791971 +0.8090676524802475 +6.069846651578816 +6.071411566463618 +0.025279496313961432 +0.19788719264057633 +0.016360696384577725 +1.0342570759904244 +0.026403612138840668 +0.016360696384577725 +0.019318251776732617 +0.014013152602464482 +0.03537086218659055 +0.018026305204928966 +6.234776695167793 +6.327799950981746 +6.234224872543608 diff --git a/src/plugin_system/apis/emoji_api.py b/src/plugin_system/apis/emoji_api.py index 33c0f23d7..69d7a7b1b 100644 --- a/src/plugin_system/apis/emoji_api.py +++ b/src/plugin_system/apis/emoji_api.py @@ -8,7 +8,7 @@ count = emoji_api.get_count() """ -from typing import Optional, Tuple +from typing import Optional, Tuple, List from src.common.logger import get_logger from src.chat.emoji_system.emoji_manager import get_emoji_manager from src.chat.utils.utils_image import image_path_to_base64 @@ -55,14 +55,20 @@ async def get_by_description(description: str) -> Optional[Tuple[str, str, str]] return None -async def get_random() -> Optional[Tuple[str, str, str]]: - """随机获取表情包 +async def get_random(count: int = 1) -> Optional[List[Tuple[str, str, str]]]: + """随机获取指定数量的表情包 + + Args: + count: 要获取的表情包数量,默认为1 Returns: - Optional[Tuple[str, str, str]]: (base64编码, 表情包描述, 随机情感标签) 或 None + Optional[List[Tuple[str, str, str]]]: 包含(base64编码, 表情包描述, 随机情感标签)的元组列表,如果失败则为None """ + if count <= 0: + return [] + try: - logger.info("[EmojiAPI] 随机获取表情包") + logger.info(f"[EmojiAPI] 随机获取 {count} 个表情包") emoji_manager = get_emoji_manager() all_emojis = emoji_manager.emoji_objects @@ -77,23 +83,35 @@ async def get_random() -> Optional[Tuple[str, str, str]]: logger.warning("[EmojiAPI] 没有有效的表情包") return None + if len(valid_emojis) < count: + logger.warning(f"[EmojiAPI] 有效表情包数量 ({len(valid_emojis)}) 少于请求的数量 ({count}),将返回所有有效表情包") + count = len(valid_emojis) + # 随机选择 import random - selected_emoji = random.choice(valid_emojis) - emoji_base64 = image_path_to_base64(selected_emoji.full_path) + selected_emojis = random.sample(valid_emojis, count) - if not emoji_base64: - logger.error(f"[EmojiAPI] 无法转换表情包为base64: {selected_emoji.full_path}") + results = [] + for selected_emoji in selected_emojis: + emoji_base64 = image_path_to_base64(selected_emoji.full_path) + + if not emoji_base64: + logger.error(f"[EmojiAPI] 无法转换表情包为base64: {selected_emoji.full_path}") + continue + + matched_emotion = random.choice(selected_emoji.emotion) if selected_emoji.emotion else "随机表情" + + # 记录使用次数 + emoji_manager.record_usage(selected_emoji.hash) + results.append((emoji_base64, selected_emoji.description, matched_emotion)) + + if not results and count > 0: + logger.warning("[EmojiAPI] 随机获取表情包失败,没有一个可以成功处理") return None - matched_emotion = random.choice(selected_emoji.emotion) if selected_emoji.emotion else "随机表情" - - # 记录使用次数 - emoji_manager.record_usage(selected_emoji.hash) - - logger.info(f"[EmojiAPI] 成功获取随机表情包: {selected_emoji.description}") - return emoji_base64, selected_emoji.description, matched_emotion + logger.info(f"[EmojiAPI] 成功获取 {len(results)} 个随机表情包") + return results except Exception as e: logger.error(f"[EmojiAPI] 获取随机表情包失败: {e}") diff --git a/src/plugins/built_in/core_actions/emoji.py b/src/plugins/built_in/core_actions/emoji.py index cb429dd4c..6303169d8 100644 --- a/src/plugins/built_in/core_actions/emoji.py +++ b/src/plugins/built_in/core_actions/emoji.py @@ -1,3 +1,4 @@ +import random from typing import Tuple # 导入新插件系统 @@ -7,7 +8,7 @@ from src.plugin_system import BaseAction, ActionActivationType, ChatMode from src.common.logger import get_logger # 导入API模块 - 标准Python包方式 -from src.plugin_system.apis import emoji_api +from src.plugin_system.apis import emoji_api, llm_api, message_api from src.plugins.built_in.core_actions.no_reply import NoReplyAction @@ -39,7 +40,7 @@ class EmojiAction(BaseAction): """ # 动作参数定义 - action_parameters = {"description": "文字描述你想要发送的表情包内容"} + action_parameters = {"reason": "文字描述你想要发送的表情包原因"} # 动作使用场景 action_require = [ @@ -56,18 +57,79 @@ class EmojiAction(BaseAction): logger.info(f"{self.log_prefix} 决定发送表情") try: - # 1. 根据描述选择表情包 - description = self.action_data.get("description", "") - emoji_result = await emoji_api.get_by_description(description) + # 1. 获取发送表情的原因 + reason = self.action_data.get("reason", "表达当前情绪") + logger.info(f"{self.log_prefix} 发送表情原因: {reason}") - if not emoji_result: - logger.warning(f"{self.log_prefix} 未找到匹配描述 '{description}' 的表情包") - return False, f"未找到匹配 '{description}' 的表情包" + # 2. 随机获取20个表情包 + sampled_emojis = await emoji_api.get_random(30) + if not sampled_emojis: + logger.warning(f"{self.log_prefix} 无法获取随机表情包") + return False, "无法获取随机表情包" - emoji_base64, emoji_description, matched_emotion = emoji_result - logger.info(f"{self.log_prefix} 找到表达{matched_emotion}的表情包") + # 3. 准备情感数据 + emotion_map = {} + for b64, desc, emo in sampled_emojis: + if emo not in emotion_map: + emotion_map[emo] = [] + emotion_map[emo].append((b64, desc)) - # 使用BaseAction的便捷方法发送表情包 + available_emotions = list(emotion_map.keys()) + + if not available_emotions: + logger.warning(f"{self.log_prefix} 获取到的表情包均无情感标签, 将随机发送") + emoji_base64, emoji_description, _ = random.choice(sampled_emojis) + else: + + # 获取最近的5条消息内容用于判断 + recent_messages = message_api.get_recent_messages(chat_id=self.chat_id, limit=5) + messages_text = "" + if recent_messages: + # 使用message_api构建可读的消息字符串 + messages_text = message_api.build_readable_messages( + messages=recent_messages, + timestamp_mode="normal_no_YMD", + truncate=False, + show_actions=False, + ) + + # 4. 构建prompt让LLM选择情感 + prompt = f""" + 你是一个正在进行聊天的网友,你需要根据一个理由和最近的聊天记录,从一个情感标签列表中选择最匹配的一个。 + 这是最近的聊天记录: + {messages_text} + + 这是理由:“{reason}” + 这里是可用的情感标签:{available_emotions} + 请直接返回最匹配的那个情感标签,不要进行任何解释或添加其他多余的文字。 + """ + logger.info(f"{self.log_prefix} 生成的LLM Prompt: {prompt}") + + # 5. 调用LLM + models = llm_api.get_available_models() + chat_model_config = getattr(models, "utils_small", None) # 默认使用chat模型 + if not chat_model_config: + logger.error(f"{self.log_prefix} 未找到'chat'模型配置,无法调用LLM") + return False, "未找到'chat'模型配置" + + success, chosen_emotion, _, _ = await llm_api.generate_with_model(prompt, model_config=chat_model_config, request_type="emoji") + + if not success: + logger.error(f"{self.log_prefix} LLM调用失败: {chosen_emotion}") + return False, f"LLM调用失败: {chosen_emotion}" + + chosen_emotion = chosen_emotion.strip().replace("\"", "").replace("'", "") + logger.info(f"{self.log_prefix} LLM选择的情感: {chosen_emotion}") + + # 6. 根据选择的情感匹配表情包 + if chosen_emotion in emotion_map: + emoji_base64, emoji_description = random.choice(emotion_map[chosen_emotion]) + logger.info(f"{self.log_prefix} 找到匹配情感 '{chosen_emotion}' 的表情包: {emoji_description}") + else: + logger.warning(f"{self.log_prefix} LLM选择的情感 '{chosen_emotion}' 不在可用列表中, 将随机选择一个表情包") + emoji_base64, emoji_description, _ = random.choice(sampled_emojis) + + # 7. 发送表情包 success = await self.send_emoji(emoji_base64) if not success: @@ -80,5 +142,5 @@ class EmojiAction(BaseAction): return True, f"发送表情包: {emoji_description}" except Exception as e: - logger.error(f"{self.log_prefix} 表情动作执行失败: {e}") + logger.error(f"{self.log_prefix} 表情动作执行失败: {e}", exc_info=True) return False, f"表情发送失败: {str(e)}"