From a92aa35e72d8be52258ee525c015b3250f537270 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Fri, 4 Apr 2025 00:30:27 +0800 Subject: [PATCH] =?UTF-8?q?better=EF=BC=9A=E5=9B=9E=E5=A4=8D=E7=8E=B0?= =?UTF-8?q?=E5=9C=A8=E4=BE=9D=E7=85=A7=E6=9D=A1=E6=95=B0=E5=92=8C=E9=95=BF?= =?UTF-8?q?=E5=BA=A6=E8=80=8C=E4=B8=8D=E6=98=AF=E6=97=B6=E9=97=B4=E5=BC=95?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelogs/changelog_dev.md | 7 +- src/heart_flow/sub_heartflow.py | 2 +- src/plugins/chat/bot.py | 84 +++++++++++----------- src/plugins/chat/message.py | 2 +- src/plugins/chat/message_sender.py | 31 +++++--- src/plugins/chat/utils.py | 105 ++++++++++++++++++++++++++++ src/plugins/message/message_base.py | 2 +- 7 files changed, 177 insertions(+), 56 deletions(-) diff --git a/changelogs/changelog_dev.md b/changelogs/changelog_dev.md index ab211c4b9..e99dc44cd 100644 --- a/changelogs/changelog_dev.md +++ b/changelogs/changelog_dev.md @@ -1,8 +1,13 @@ 这里放置了测试版本的细节更新 +## [test-0.6.0-snapshot-8] - 2025-4-3 +- 修复了表情包的注册,获取和发送逻辑 +- 更改了回复引用的逻辑,从基于时间改为基于新消息 +- 增加了调试信息 + ## [test-0.6.0-snapshot-7] - 2025-4-2 - 修改版本号命名:test-前缀为测试版,无前缀为正式版 -- 提供私聊的PFC模式 +- 提供私聊的PFC模式,可以进行有目的,自由多轮对话 ## [0.6.0-mmc-4] - 2025-4-1 - 提供两种聊天逻辑,思维流聊天(ThinkFlowChat 和 推理聊天(ReasoningChat) diff --git a/src/heart_flow/sub_heartflow.py b/src/heart_flow/sub_heartflow.py index 5aa69a6f6..fcbe9332f 100644 --- a/src/heart_flow/sub_heartflow.py +++ b/src/heart_flow/sub_heartflow.py @@ -192,7 +192,7 @@ class SubHeartflow: logger.info(f"麦麦的思考前脑内状态:{self.current_mind}") async def do_thinking_after_reply(self, reply_content, chat_talking_prompt): - print("麦麦回复之后脑袋转起来了") + # print("麦麦回复之后脑袋转起来了") current_thinking_info = self.current_mind mood_info = self.current_state.mood diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py index d5fc303a6..68afd2e76 100644 --- a/src/plugins/chat/bot.py +++ b/src/plugins/chat/bot.py @@ -75,55 +75,57 @@ class ChatBot: - 表情包处理 - 性能计时 """ - - message = MessageRecv(message_data) - groupinfo = message.message_info.group_info - logger.debug(f"开始处理消息{message_data}") + try: + message = MessageRecv(message_data) + groupinfo = message.message_info.group_info + logger.debug(f"处理消息:{str(message_data)[:50]}...") - if global_config.enable_pfc_chatting: - try: + if global_config.enable_pfc_chatting: + try: + if groupinfo is None and global_config.enable_friend_chat: + userinfo = message.message_info.user_info + messageinfo = message.message_info + # 创建聊天流 + chat = await chat_manager.get_or_create_stream( + platform=messageinfo.platform, + user_info=userinfo, + group_info=groupinfo, + ) + message.update_chat_stream(chat) + await self.only_process_chat.process_message(message) + await self._create_PFC_chat(message) + else: + if groupinfo.group_id in global_config.talk_allowed_groups: + logger.debug(f"开始群聊模式{message_data}") + if global_config.response_mode == "heart_flow": + await self.think_flow_chat.process_message(message_data) + elif global_config.response_mode == "reasoning": + logger.debug(f"开始推理模式{message_data}") + await self.reasoning_chat.process_message(message_data) + else: + logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}") + except Exception as e: + logger.error(f"处理PFC消息失败: {e}") + else: if groupinfo is None and global_config.enable_friend_chat: - userinfo = message.message_info.user_info - messageinfo = message.message_info - # 创建聊天流 - chat = await chat_manager.get_or_create_stream( - platform=messageinfo.platform, - user_info=userinfo, - group_info=groupinfo, - ) - message.update_chat_stream(chat) - await self.only_process_chat.process_message(message) - await self._create_PFC_chat(message) - else: - if groupinfo.group_id in global_config.talk_allowed_groups: - logger.debug(f"开始群聊模式{message_data}") - if global_config.response_mode == "heart_flow": - await self.think_flow_chat.process_message(message_data) - elif global_config.response_mode == "reasoning": - logger.debug(f"开始推理模式{message_data}") - await self.reasoning_chat.process_message(message_data) - else: - logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}") - except Exception as e: - logger.error(f"处理PFC消息失败: {e}") - else: - if groupinfo is None and global_config.enable_friend_chat: - # 私聊处理流程 - # await self._handle_private_chat(message) - if global_config.response_mode == "heart_flow": - await self.think_flow_chat.process_message(message_data) - elif global_config.response_mode == "reasoning": - await self.reasoning_chat.process_message(message_data) - else: - logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}") - else: # 群聊处理 - if groupinfo.group_id in global_config.talk_allowed_groups: + # 私聊处理流程 + # await self._handle_private_chat(message) if global_config.response_mode == "heart_flow": await self.think_flow_chat.process_message(message_data) elif global_config.response_mode == "reasoning": await self.reasoning_chat.process_message(message_data) else: logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}") + else: # 群聊处理 + if groupinfo.group_id in global_config.talk_allowed_groups: + if global_config.response_mode == "heart_flow": + await self.think_flow_chat.process_message(message_data) + elif global_config.response_mode == "reasoning": + await self.reasoning_chat.process_message(message_data) + else: + logger.error(f"未知的回复模式,请检查配置文件!!: {global_config.response_mode}") + except Exception as e: + logger.error(f"预处理消息失败: {e}") # 创建全局ChatBot实例 diff --git a/src/plugins/chat/message.py b/src/plugins/chat/message.py index 8427a02e1..22487831f 100644 --- a/src/plugins/chat/message.py +++ b/src/plugins/chat/message.py @@ -31,7 +31,7 @@ class Message(MessageBase): def __init__( self, message_id: str, - time: int, + time: float, chat_stream: ChatStream, user_info: UserInfo, message_segment: Optional[Seg] = None, diff --git a/src/plugins/chat/message_sender.py b/src/plugins/chat/message_sender.py index daba61552..70b5cf84d 100644 --- a/src/plugins/chat/message_sender.py +++ b/src/plugins/chat/message_sender.py @@ -9,7 +9,7 @@ from .message import MessageSending, MessageThinking, MessageSet from ..storage.storage import MessageStorage from ..config.config import global_config -from .utils import truncate_message, calculate_typing_time +from .utils import truncate_message, calculate_typing_time, count_messages_between from src.common.logger import LogConfig, SENDER_STYLE_CONFIG @@ -85,7 +85,7 @@ class MessageContainer: self.max_size = max_size self.messages = [] self.last_send_time = 0 - self.thinking_timeout = 10 # 思考等待超时时间(秒) + self.thinking_timeout = 20 # 思考等待超时时间(秒) def get_timeout_messages(self) -> List[MessageSending]: """获取所有超时的Message_Sending对象(思考时间超过30秒),按thinking_start_time排序""" @@ -172,6 +172,7 @@ class MessageManager: message_earliest = container.get_earliest_message() if isinstance(message_earliest, MessageThinking): + """取得了思考消息""" message_earliest.update_thinking_time() thinking_time = message_earliest.thinking_time # print(thinking_time) @@ -187,14 +188,18 @@ class MessageManager: container.remove_message(message_earliest) else: - # print(message_earliest.is_head) - # print(message_earliest.update_thinking_time()) - # print(message_earliest.is_private_message()) + """取得了发送消息""" thinking_time = message_earliest.update_thinking_time() - print(thinking_time) + thinking_start_time = message_earliest.thinking_start_time + now_time = time.time() + thinking_messages_count, thinking_messages_length = count_messages_between(start_time=thinking_start_time, end_time=now_time, stream_id=message_earliest.chat_stream.stream_id) + # print(thinking_time) + # print(thinking_messages_count) + # print(thinking_messages_length) + if ( message_earliest.is_head - and message_earliest.update_thinking_time() > 18 + and (thinking_messages_count > 4 or thinking_messages_length > 250) and not message_earliest.is_private_message() # 避免在私聊时插入reply ): logger.debug(f"设置回复消息{message_earliest.processed_plain_text}") @@ -216,12 +221,16 @@ class MessageManager: continue try: - # print(msg.is_head) - print(msg.update_thinking_time()) - # print(msg.is_private_message()) + thinking_time = msg.update_thinking_time() + thinking_start_time = msg.thinking_start_time + now_time = time.time() + thinking_messages_count, thinking_messages_length = count_messages_between(start_time=thinking_start_time, end_time=now_time, stream_id=msg.chat_stream.stream_id) + # print(thinking_time) + # print(thinking_messages_count) + # print(thinking_messages_length) if ( msg.is_head - and msg.update_thinking_time() > 18 + and (thinking_messages_count > 4 or thinking_messages_length > 250) and not msg.is_private_message() # 避免在私聊时插入reply ): logger.debug(f"设置回复消息{msg.processed_plain_text}") diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py index c575eea88..9646fe73b 100644 --- a/src/plugins/chat/utils.py +++ b/src/plugins/chat/utils.py @@ -487,3 +487,108 @@ def is_western_char(char): def is_western_paragraph(paragraph): """检测是否为西文字符段落""" return all(is_western_char(char) for char in paragraph if char.isalnum()) + + +def count_messages_between(start_time: float, end_time: float, stream_id: str) -> tuple[int, int]: + """计算两个时间点之间的消息数量和文本总长度 + + Args: + start_time (float): 起始时间戳 + end_time (float): 结束时间戳 + stream_id (str): 聊天流ID + + Returns: + tuple[int, int]: (消息数量, 文本总长度) + - 消息数量:包含起始时间的消息,不包含结束时间的消息 + - 文本总长度:所有消息的processed_plain_text长度之和 + """ + try: + # 获取开始时间之前最新的一条消息 + start_message = db.messages.find_one( + { + "chat_id": stream_id, + "time": {"$lte": start_time} + }, + sort=[("time", -1), ("_id", -1)] # 按时间倒序,_id倒序(最后插入的在前) + ) + + # 获取结束时间最近的一条消息 + # 先找到结束时间点的所有消息 + end_time_messages = list(db.messages.find( + { + "chat_id": stream_id, + "time": {"$lte": end_time} + }, + sort=[("time", -1)] # 先按时间倒序 + ).limit(10)) # 限制查询数量,避免性能问题 + + if not end_time_messages: + logger.warning(f"未找到结束时间 {end_time} 之前的消息") + return 0, 0 + + # 找到最大时间 + max_time = end_time_messages[0]["time"] + # 在最大时间的消息中找最后插入的(_id最大的) + end_message = max( + [msg for msg in end_time_messages if msg["time"] == max_time], + key=lambda x: x["_id"] + ) + + if not start_message: + logger.warning(f"未找到开始时间 {start_time} 之前的消息") + return 0, 0 + + # 调试输出 + # print("\n=== 消息范围信息 ===") + # print("Start message:", { + # "message_id": start_message.get("message_id"), + # "time": start_message.get("time"), + # "text": start_message.get("processed_plain_text", ""), + # "_id": str(start_message.get("_id")) + # }) + # print("End message:", { + # "message_id": end_message.get("message_id"), + # "time": end_message.get("time"), + # "text": end_message.get("processed_plain_text", ""), + # "_id": str(end_message.get("_id")) + # }) + # print("Stream ID:", stream_id) + + # 如果结束消息的时间等于开始时间,返回0 + if end_message["time"] == start_message["time"]: + return 0, 0 + + # 获取并打印这个时间范围内的所有消息 + # print("\n=== 时间范围内的所有消息 ===") + all_messages = list(db.messages.find( + { + "chat_id": stream_id, + "time": { + "$gte": start_message["time"], + "$lte": end_message["time"] + } + }, + sort=[("time", 1), ("_id", 1)] # 按时间正序,_id正序 + )) + + count = 0 + total_length = 0 + for msg in all_messages: + count += 1 + text_length = len(msg.get("processed_plain_text", "")) + total_length += text_length + # print(f"\n消息 {count}:") + # print({ + # "message_id": msg.get("message_id"), + # "time": msg.get("time"), + # "text": msg.get("processed_plain_text", ""), + # "text_length": text_length, + # "_id": str(msg.get("_id")) + # }) + + # 如果时间不同,需要把end_message本身也计入 + return count - 1, total_length + + except Exception as e: + logger.error(f"计算消息数量时出错: {str(e)}") + return 0, 0 diff --git a/src/plugins/message/message_base.py b/src/plugins/message/message_base.py index ea5c3daef..edaa9a033 100644 --- a/src/plugins/message/message_base.py +++ b/src/plugins/message/message_base.py @@ -166,7 +166,7 @@ class BaseMessageInfo: platform: Optional[str] = None message_id: Union[str, int, None] = None - time: Optional[int] = None + time: Optional[float] = None group_info: Optional[GroupInfo] = None user_info: Optional[UserInfo] = None format_info: Optional[FormatInfo] = None