diff --git a/src/chat/chat_loop/heartFC_chat.py b/src/chat/chat_loop/heartFC_chat.py index 3970697db..db42dfac8 100644 --- a/src/chat/chat_loop/heartFC_chat.py +++ b/src/chat/chat_loop/heartFC_chat.py @@ -392,8 +392,7 @@ class HeartFChatting: if self.chat_stream.group_info and getattr(self.chat_stream.group_info, "group_id", None): await self.group_relationship_manager.build_relation( chat_id=self.stream_id, - platform=self.chat_stream.platform, - group_number=self.chat_stream.group_info.group_id + platform=self.chat_stream.platform ) @@ -712,7 +711,7 @@ class HeartFChatting: await send_api.text_to_stream( text=data, stream_id=self.chat_stream.stream_id, - reply_to_message = message_data, + reply_message = message_data, set_reply=need_reply, typing=False, ) @@ -721,7 +720,7 @@ class HeartFChatting: await send_api.text_to_stream( text=data, stream_id=self.chat_stream.stream_id, - reply_to_message = message_data, + reply_message = message_data, set_reply=False, typing=True, ) diff --git a/src/chat/express/expression_learner.py b/src/chat/express/expression_learner.py index 4b32b2a9e..197cc29c3 100644 --- a/src/chat/express/expression_learner.py +++ b/src/chat/express/expression_learner.py @@ -48,7 +48,6 @@ def init_prompt() -> None: 例如: 当"对某件事表示十分惊叹,有些意外"时,使用"我嘞个xxxx" 当"表示讽刺的赞同,不想讲道理"时,使用"对对对" -当"表达观点较复杂"时,使用"使用省略主语(3-6个字)"的句法 当"想说明某个具体的事实观点,但懒得明说,或者不便明说,或表达一种默契",使用"懂的都懂" 当"当涉及游戏相关时,表示意外的夸赞,略带戏谑意味"时,使用"这么强!" diff --git a/src/person_info/group_info.py b/src/person_info/group_info.py index 58b05f626..af1df7ecf 100644 --- a/src/person_info/group_info.py +++ b/src/person_info/group_info.py @@ -27,7 +27,7 @@ GroupInfoManager 类方法功能摘要: logger = get_logger("group_info") -JSON_SERIALIZED_FIELDS = ["member_list", "group_info"] +JSON_SERIALIZED_FIELDS = ["member_list", "topic"] group_info_default = { "group_id": None, @@ -37,7 +37,7 @@ group_info_default = { "group_impression": None, "short_impression": None, "member_list": [], - "group_info": {}, + "topic":[], "create_time": None, "last_active": None, "member_count": 0, diff --git a/src/person_info/group_relationship_manager.py b/src/person_info/group_relationship_manager.py index deb0880f5..5a6f99950 100644 --- a/src/person_info/group_relationship_manager.py +++ b/src/person_info/group_relationship_manager.py @@ -12,7 +12,7 @@ from src.chat.utils.chat_message_builder import ( build_readable_messages, ) from src.person_info.group_info import get_group_info_manager -from src.plugin_system.apis.message_api import get_message_api +from src.plugin_system.apis import message_api from json_repair import repair_json @@ -27,7 +27,7 @@ class GroupRelationshipManager: self.last_group_impression_time = 0.0 self.last_group_impression_message_count = 0 - async def build_relation(self, chat_id: str, platform: str, group_number: str | int) -> None: + async def build_relation(self, chat_id: str, platform: str) -> None: """构建群关系,类似 relationship_builder.build_relation() 的调用方式""" current_time = time.time() talk_frequency = global_config.chat.get_current_talk_frequency(chat_id) @@ -36,14 +36,15 @@ class GroupRelationshipManager: interval_seconds = max(600, int(1800 / max(0.5, talk_frequency))) # 统计新消息数量 - message_api = get_message_api() - new_messages_since_last_impression = message_api.count_new_messages( + # 先获取所有新消息,然后过滤掉麦麦的消息和命令消息 + all_new_messages = message_api.get_messages_by_time_in_chat( chat_id=chat_id, start_time=self.last_group_impression_time, end_time=current_time, filter_mai=True, filter_command=True, ) + new_messages_since_last_impression = len(all_new_messages) # 触发条件:时间间隔 OR 消息数量阈值 if (current_time - self.last_group_impression_time >= interval_seconds) or \ @@ -55,7 +56,6 @@ class GroupRelationshipManager: self.build_group_impression( chat_id=chat_id, platform=platform, - group_number=group_number, lookback_hours=12, max_messages=300 ) @@ -72,7 +72,6 @@ class GroupRelationshipManager: self, chat_id: str, platform: str, - group_number: str | int, lookback_hours: int = 24, max_messages: int = 300, ) -> Optional[str]: @@ -101,9 +100,9 @@ class GroupRelationshipManager: # 确保群存在 group_info_manager = get_group_info_manager() - group_id = await group_info_manager.get_or_create_group(platform, group_number) + group_id = await group_info_manager.get_or_create_group(platform, chat_id) - group_name = await group_info_manager.get_value(group_id, "group_name") or str(group_number) + group_name = await group_info_manager.get_value(group_id, "group_name") or chat_id alias_str = ", ".join(global_config.bot.alias_names) prompt = f""" @@ -118,8 +117,7 @@ class GroupRelationshipManager: - 请严格按照json格式输出,不要有其他多余内容: {{ "impression": "不超过200字的群印象长描述,白话、自然", - "topic": "一句话概括群主要聊什么,白话", - "style": "一句话描述大家的说话风格,白话" + "topic": "一句话概括群主要聊什么,白话" }} 群内聊天(节选): @@ -141,7 +139,6 @@ class GroupRelationshipManager: long_impression: str = "" topic_val: Any = "" - style_val: Any = "" # 参考关系模块:先repair_json再loads,兼容返回列表/字典/字符串 try: @@ -152,40 +149,27 @@ class GroupRelationshipManager: if isinstance(data, dict): long_impression = str(data.get("impression") or "").strip() topic_val = data.get("topic", "") - style_val = data.get("style", "") else: # 不是字典,直接作为文本 text_fallback = str(data) long_impression = text_fallback[:400].strip() topic_val = "" - style_val = "" except Exception: long_impression = parsed_text[:400].strip() topic_val = "" - style_val = "" # 兜底 - if not long_impression and not topic_val and not style_val: + if not long_impression and not topic_val: logger.info(f"[{chat_id}] LLM未产生有效群印象,跳过") return None # 写入数据库 await group_info_manager.update_one_field(group_id, "group_impression", long_impression) - # 将 topic/style 写入 group_info JSON - try: - current_group_info = await group_info_manager.get_value(group_id, "group_info") or {} - if not isinstance(current_group_info, dict): - current_group_info = {} - except Exception: - current_group_info = {} - if topic_val != "": - current_group_info["topic"] = topic_val - if style_val != "": - current_group_info["style"] = style_val - await group_info_manager.update_one_field(group_id, "group_info", current_group_info) + if topic_val: + await group_info_manager.update_one_field(group_id, "topic", topic_val) await group_info_manager.update_one_field(group_id, "last_active", now) - logger.info(f"[{chat_id}] 群印象更新完成: topic={topic_val} style={style_val}") + logger.info(f"[{chat_id}] 群印象更新完成: topic={topic_val}") return str(topic_val) if topic_val else "" diff --git a/src/plugin_system/apis/generator_api.py b/src/plugin_system/apis/generator_api.py index 703da5966..2fc931a30 100644 --- a/src/plugin_system/apis/generator_api.py +++ b/src/plugin_system/apis/generator_api.py @@ -74,7 +74,6 @@ async def generate_reply( chat_stream: Optional[ChatStream] = None, chat_id: Optional[str] = None, action_data: Optional[Dict[str, Any]] = None, - reply_to: str = "", reply_message: Optional[Dict[str, Any]] = None, extra_info: str = "", reply_reason: str = "", @@ -92,8 +91,7 @@ async def generate_reply( chat_stream: 聊天流对象(优先) chat_id: 聊天ID(备用) action_data: 动作数据(向下兼容,包含reply_to和extra_info) - reply_to: 回复对象,格式为 "发送者:消息内容" - reply_message: 回复消息 + reply_message: 回复的消息对象 extra_info: 额外信息,用于补充上下文 reply_reason: 回复原因 available_actions: 可用动作 @@ -109,6 +107,7 @@ async def generate_reply( """ try: # 获取回复器 + logger.debug("[GeneratorAPI] 开始生成回复") replyer = get_replyer( chat_stream, chat_id, request_type=request_type ) @@ -116,11 +115,6 @@ async def generate_reply( logger.error("[GeneratorAPI] 无法获取回复器") return False, [], None - logger.debug("[GeneratorAPI] 开始生成回复") - - if reply_to: - logger.warning("[GeneratorAPI] 在0.10.0, reply_to 参数已弃用,请使用 reply_message 参数") - if not extra_info and action_data: extra_info = action_data.get("extra_info", "") diff --git a/src/plugin_system/apis/send_api.py b/src/plugin_system/apis/send_api.py index 77256c564..c96679f30 100644 --- a/src/plugin_system/apis/send_api.py +++ b/src/plugin_system/apis/send_api.py @@ -21,7 +21,6 @@ import traceback import time -import difflib from typing import Optional, Union, Dict, Any from src.common.logger import get_logger @@ -29,8 +28,6 @@ from src.common.logger import get_logger from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.uni_message_sender import HeartFCSender from src.chat.message_receive.message import MessageSending, MessageRecv -from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat, replace_user_references_async -from src.person_info.person_info import get_person_info_manager from maim_message import Seg, UserInfo from src.config.config import global_config @@ -48,9 +45,8 @@ async def _send_to_target( stream_id: str, display_message: str = "", typing: bool = False, - reply_to: str = "", set_reply: bool = False, - reply_to_message: Optional[Dict[str, Any]] = None, + reply_message: Optional[Dict[str, Any]] = None, storage_message: bool = True, show_log: bool = True, ) -> bool: @@ -70,8 +66,9 @@ async def _send_to_target( bool: 是否发送成功 """ try: - if reply_to: - logger.warning("[SendAPI] 在0.10.0, reply_to 参数已弃用,请使用 reply_to_message 参数") + if set_reply and not reply_message: + logger.warning("[SendAPI] 使用引用回复,但未提供回复消息") + return False if show_log: logger.debug(f"[SendAPI] 发送{message_type}消息到 {stream_id}") @@ -99,13 +96,14 @@ async def _send_to_target( # 创建消息段 message_segment = Seg(type=message_type, data=content) # type: ignore - if reply_to_message: - anchor_message = message_dict_to_message_recv(reply_to_message) + if reply_message: + anchor_message = message_dict_to_message_recv(reply_message) anchor_message.update_chat_stream(target_stream) reply_to_platform_id = ( f"{anchor_message.message_info.platform}:{anchor_message.message_info.user_info.user_id}" ) else: + reply_to_platform_id = "" anchor_message = None # 构建发送消息对象 @@ -146,8 +144,7 @@ async def _send_to_target( def message_dict_to_message_recv(message_dict: Dict[str, Any]) -> Optional[MessageRecv]: - """查找要回复的消息 - + """将数据库dict重建为MessageRecv对象 Args: message_dict: 消息字典 @@ -184,13 +181,13 @@ def message_dict_to_message_recv(message_dict: Dict[str, Any]) -> Optional[Messa "template_info": template_info, } - message_dict = { + message_dict_recv = { "message_info": message_info, "raw_message": message_dict.get("processed_plain_text"), "processed_plain_text": message_dict.get("processed_plain_text"), } - message_recv = MessageRecv(message_dict) + message_recv = MessageRecv(message_dict_recv) logger.info(f"[SendAPI] 找到匹配的回复消息,发送者: {message_dict.get('user_nickname', '')}") return message_recv @@ -206,9 +203,8 @@ async def text_to_stream( text: str, stream_id: str, typing: bool = False, - reply_to: str = "", - reply_to_message: Optional[Dict[str, Any]] = None, set_reply: bool = False, + reply_message: Optional[Dict[str, Any]] = None, storage_message: bool = True, ) -> bool: """向指定流发送文本消息 @@ -229,14 +225,13 @@ async def text_to_stream( stream_id, "", typing, - reply_to, set_reply=set_reply, - reply_to_message=reply_to_message, + reply_message=reply_message, storage_message=storage_message, ) -async def emoji_to_stream(emoji_base64: str, stream_id: str, storage_message: bool = True, set_reply: bool = False,reply_to_message: Optional[Dict[str, Any]] = None) -> bool: +async def emoji_to_stream(emoji_base64: str, stream_id: str, storage_message: bool = True, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """向指定流发送表情包 Args: @@ -247,10 +242,10 @@ async def emoji_to_stream(emoji_base64: str, stream_id: str, storage_message: bo Returns: bool: 是否发送成功 """ - return await _send_to_target("emoji", emoji_base64, stream_id, "", typing=False, storage_message=storage_message, set_reply=set_reply,reply_to_message=reply_to_message) + return await _send_to_target("emoji", emoji_base64, stream_id, "", typing=False, storage_message=storage_message, set_reply=set_reply,reply_message=reply_message) -async def image_to_stream(image_base64: str, stream_id: str, storage_message: bool = True, set_reply: bool = False,reply_to_message: Optional[Dict[str, Any]] = None) -> bool: +async def image_to_stream(image_base64: str, stream_id: str, storage_message: bool = True, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """向指定流发送图片 Args: @@ -261,11 +256,11 @@ async def image_to_stream(image_base64: str, stream_id: str, storage_message: bo Returns: bool: 是否发送成功 """ - return await _send_to_target("image", image_base64, stream_id, "", typing=False, storage_message=storage_message, set_reply=set_reply,reply_to_message=reply_to_message) + return await _send_to_target("image", image_base64, stream_id, "", typing=False, storage_message=storage_message, set_reply=set_reply,reply_message=reply_message) async def command_to_stream( - command: Union[str, dict], stream_id: str, storage_message: bool = True, display_message: str = "", set_reply: bool = False,reply_to_message: Optional[Dict[str, Any]] = None + command: Union[str, dict], stream_id: str, storage_message: bool = True, display_message: str = "", set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None ) -> bool: """向指定流发送命令 @@ -278,7 +273,7 @@ async def command_to_stream( bool: 是否发送成功 """ return await _send_to_target( - "command", command, stream_id, display_message, typing=False, storage_message=storage_message, set_reply=set_reply,reply_to_message=reply_to_message + "command", command, stream_id, display_message, typing=False, storage_message=storage_message, set_reply=set_reply,reply_message=reply_message ) @@ -288,8 +283,7 @@ async def custom_to_stream( stream_id: str, display_message: str = "", typing: bool = False, - reply_to: str = "", - reply_to_message: Optional[Dict[str, Any]] = None, + reply_message: Optional[Dict[str, Any]] = None, set_reply: bool = False, storage_message: bool = True, show_log: bool = True, @@ -314,8 +308,7 @@ async def custom_to_stream( stream_id=stream_id, display_message=display_message, typing=typing, - reply_to=reply_to, - reply_to_message=reply_to_message, + reply_message=reply_message, set_reply=set_reply, storage_message=storage_message, show_log=show_log, diff --git a/src/plugin_system/base/base_action.py b/src/plugin_system/base/base_action.py index a4a2ba115..80732f28c 100644 --- a/src/plugin_system/base/base_action.py +++ b/src/plugin_system/base/base_action.py @@ -2,7 +2,7 @@ import time import asyncio from abc import ABC, abstractmethod -from typing import Tuple, Optional +from typing import Tuple, Optional, Dict, Any from src.common.logger import get_logger from src.chat.message_receive.chat_stream import ChatStream @@ -208,7 +208,7 @@ class BaseAction(ABC): return False, f"等待新消息失败: {str(e)}" async def send_text( - self, content: str, reply_to: str = "", typing: bool = False + self, content: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None, typing: bool = False ) -> bool: """发送文本消息 @@ -226,12 +226,12 @@ class BaseAction(ABC): return await send_api.text_to_stream( text=content, stream_id=self.chat_id, - reply_to=reply_to, + set_reply=set_reply, + reply_message=reply_message, typing=typing, - reply_to_message=self.action_message, ) - async def send_emoji(self, emoji_base64: str) -> bool: + async def send_emoji(self, emoji_base64: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送表情包 Args: @@ -244,9 +244,9 @@ class BaseAction(ABC): logger.error(f"{self.log_prefix} 缺少聊天ID") return False - return await send_api.emoji_to_stream(emoji_base64, self.chat_id,reply_to_message=self.action_message) + return await send_api.emoji_to_stream(emoji_base64, self.chat_id,set_reply=set_reply,reply_message=reply_message) - async def send_image(self, image_base64: str) -> bool: + async def send_image(self, image_base64: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送图片 Args: @@ -259,9 +259,9 @@ class BaseAction(ABC): logger.error(f"{self.log_prefix} 缺少聊天ID") return False - return await send_api.image_to_stream(image_base64, self.chat_id,reply_to_message=self.action_message) + return await send_api.image_to_stream(image_base64, self.chat_id,set_reply=set_reply,reply_message=reply_message) - async def send_custom(self, message_type: str, content: str, typing: bool = False, reply_to: str = "") -> bool: + async def send_custom(self, message_type: str, content: str, typing: bool = False, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送自定义类型消息 Args: @@ -282,8 +282,8 @@ class BaseAction(ABC): content=content, stream_id=self.chat_id, typing=typing, - reply_to=reply_to, - reply_to_message=self.action_message, + set_reply=set_reply, + reply_message=reply_message, ) async def store_action_info( @@ -310,7 +310,7 @@ class BaseAction(ABC): ) async def send_command( - self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True + self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True,set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None ) -> bool: """发送命令消息 @@ -338,7 +338,8 @@ class BaseAction(ABC): stream_id=self.chat_id, storage_message=storage_message, display_message=display_message, - reply_to_message=self.action_message, + set_reply=set_reply, + reply_message=reply_message, ) if success: diff --git a/src/plugin_system/base/base_command.py b/src/plugin_system/base/base_command.py index 3902cd963..1e16fca8b 100644 --- a/src/plugin_system/base/base_command.py +++ b/src/plugin_system/base/base_command.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import Dict, Tuple, Optional +from typing import Dict, Tuple, Optional, Any from src.common.logger import get_logger from src.plugin_system.base.component_types import CommandInfo, ComponentType from src.chat.message_receive.message import MessageRecv @@ -84,7 +84,7 @@ class BaseCommand(ABC): return current - async def send_text(self, content: str, reply_to: str = "") -> bool: + async def send_text(self, content: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送回复消息 Args: @@ -100,10 +100,10 @@ class BaseCommand(ABC): logger.error(f"{self.log_prefix} 缺少聊天流或stream_id") return False - return await send_api.text_to_stream(text=content, stream_id=chat_stream.stream_id, reply_to=reply_to,reply_to_message=self.message) + return await send_api.text_to_stream(text=content, stream_id=chat_stream.stream_id, set_reply=set_reply,reply_message=reply_message) async def send_type( - self, message_type: str, content: str, display_message: str = "", typing: bool = False, reply_to: str = "" + self, message_type: str, content: str, display_message: str = "", typing: bool = False, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None ) -> bool: """发送指定类型的回复消息到当前聊天环境 @@ -129,12 +129,12 @@ class BaseCommand(ABC): stream_id=chat_stream.stream_id, display_message=display_message, typing=typing, - reply_to=reply_to, - reply_to_message=self.message, + set_reply=set_reply, + reply_message=reply_message, ) async def send_command( - self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True + self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True,set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None ) -> bool: """发送命令消息 @@ -162,7 +162,8 @@ class BaseCommand(ABC): stream_id=chat_stream.stream_id, storage_message=storage_message, display_message=display_message, - reply_to_message=self.message, + set_reply=set_reply, + reply_message=reply_message, ) if success: @@ -176,7 +177,7 @@ class BaseCommand(ABC): logger.error(f"{self.log_prefix} 发送命令时出错: {e}") return False - async def send_emoji(self, emoji_base64: str) -> bool: + async def send_emoji(self, emoji_base64: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送表情包 Args: @@ -190,9 +191,9 @@ class BaseCommand(ABC): logger.error(f"{self.log_prefix} 缺少聊天流或stream_id") return False - return await send_api.emoji_to_stream(emoji_base64, chat_stream.stream_id,reply_to_message=self.message) + return await send_api.emoji_to_stream(emoji_base64, chat_stream.stream_id,set_reply=set_reply,reply_message=reply_message) - async def send_image(self, image_base64: str) -> bool: + async def send_image(self, image_base64: str, set_reply: bool = False,reply_message: Optional[Dict[str, Any]] = None) -> bool: """发送图片 Args: @@ -206,7 +207,7 @@ class BaseCommand(ABC): logger.error(f"{self.log_prefix} 缺少聊天流或stream_id") return False - return await send_api.image_to_stream(image_base64, chat_stream.stream_id,reply_to_message=self.message) + return await send_api.image_to_stream(image_base64, chat_stream.stream_id,set_reply=set_reply,reply_message=reply_message) @classmethod def get_command_info(cls) -> "CommandInfo":