diff --git a/.gitignore b/.gitignore index 88995eccc..5744424aa 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ NapCat.Framework.Windows.Once/ log/ logs/ tool_call_benchmark.py +run_maibot_core.bat +run_napcat_adapter.bat run_ad.bat llm_tool_benchmark_results.json MaiBot-Napcat-Adapter-main diff --git a/src/do_tool/tool_can_use/lpmm_get_knowledge.py b/src/do_tool/tool_can_use/lpmm_get_knowledge.py index 5eec260d5..a4ded910f 100644 --- a/src/do_tool/tool_can_use/lpmm_get_knowledge.py +++ b/src/do_tool/tool_can_use/lpmm_get_knowledge.py @@ -52,7 +52,7 @@ class SearchKnowledgeFromLPMMTool(BaseTool): except Exception as e: logger.error(f"知识库搜索工具执行失败: {str(e)}") # 在其他异常情况下,确保 id 仍然是 query (如果它被定义了) - query_id = query if 'query' in locals() else 'unknown_query' + query_id = query if "query" in locals() else "unknown_query" return {"type": "info", "id": query_id, "content": f"lpmm知识库搜索失败,炸了: {str(e)}"} # def get_info_from_db( @@ -143,13 +143,15 @@ class SearchKnowledgeFromLPMMTool(BaseTool): formatted_string = "我找到了一些相关知识:\n" for i, result in enumerate(results): - chunk_id = result.get("chunk_id") + # chunk_id = result.get("chunk_id") text = result.get("text", "") source = result.get("source", "未知来源") source_type = result.get("source_type", "未知类型") similarity = result.get("similarity", 0.0) - formatted_string += f"{i + 1}. (相似度: {similarity:.2f}) 类型: {source_type}, 来源: {source} \n内容片段: {text}\n\n" + formatted_string += ( + f"{i + 1}. (相似度: {similarity:.2f}) 类型: {source_type}, 来源: {source} \n内容片段: {text}\n\n" + ) # 暂时去掉chunk_id # formatted_string += f"{i + 1}. (相似度: {similarity:.2f}) 类型: {source_type}, 来源: {source}, Chunk ID: {chunk_id} \n内容片段: {text}\n\n" diff --git a/src/do_tool/tool_can_use/rename_person_tool.py b/src/do_tool/tool_can_use/rename_person_tool.py index 9e796931d..d9f23cf4d 100644 --- a/src/do_tool/tool_can_use/rename_person_tool.py +++ b/src/do_tool/tool_can_use/rename_person_tool.py @@ -1,28 +1,24 @@ from src.do_tool.tool_can_use.base_tool import BaseTool, register_tool from src.plugins.person_info.person_info import person_info_manager from src.common.logger_manager import get_logger -from src.plugins.person_info.relationship_manager import relationship_manager -import json import time logger = get_logger("rename_person_tool") + class RenamePersonTool(BaseTool): name = "rename_person" description = "这个工具可以改变用户的昵称。你可以选择改变对他人的称呼。" parameters = { "type": "object", "properties": { - "person_name": { - "type": "string", - "description": "需要重新取名的用户的当前昵称" - }, + "person_name": {"type": "string", "description": "需要重新取名的用户的当前昵称"}, "message_content": { "type": "string", - "description": "可选的。当前的聊天内容或特定要求,用于提供取名建议的上下文。" - } + "description": "可选的。当前的聊天内容或特定要求,用于提供取名建议的上下文。", + }, }, - "required": ["person_name"] + "required": ["person_name"], } async def execute(self, function_args: dict, message_txt=""): @@ -37,13 +33,10 @@ class RenamePersonTool(BaseTool): dict: 包含执行结果的字典 """ person_name_to_find = function_args.get("person_name") - request_context = function_args.get("message_content", "") # 如果没有提供,则为空字符串 + request_context = function_args.get("message_content", "") # 如果没有提供,则为空字符串 if not person_name_to_find: - return { - "name": self.name, - "content": "错误:必须提供需要重命名的用户昵称 (person_name)。" - } + return {"name": self.name, "content": "错误:必须提供需要重命名的用户昵称 (person_name)。"} try: # 1. 根据昵称查找用户信息 @@ -54,35 +47,34 @@ class RenamePersonTool(BaseTool): logger.info(f"未找到昵称为 '{person_name_to_find}' 的用户。") return { "name": self.name, - "content": f"找不到昵称为 '{person_name_to_find}' 的用户。请确保输入的是我之前为该用户取的昵称。" + "content": f"找不到昵称为 '{person_name_to_find}' 的用户。请确保输入的是我之前为该用户取的昵称。", } person_id = person_info.get("person_id") - user_nickname = person_info.get("nickname") # 这是用户原始昵称 + user_nickname = person_info.get("nickname") # 这是用户原始昵称 user_cardname = person_info.get("user_cardname") user_avatar = person_info.get("user_avatar") if not person_id: - logger.error(f"找到了用户 '{person_name_to_find}' 但无法获取 person_id") - return { - "name": self.name, - "content": f"找到了用户 '{person_name_to_find}' 但获取内部ID时出错。" - } + logger.error(f"找到了用户 '{person_name_to_find}' 但无法获取 person_id") + return {"name": self.name, "content": f"找到了用户 '{person_name_to_find}' 但获取内部ID时出错。"} # 2. 调用 qv_person_name 进行取名 - logger.debug(f"为用户 {person_id} (原昵称: {person_name_to_find}) 调用 qv_person_name,请求上下文: '{request_context}'") + logger.debug( + f"为用户 {person_id} (原昵称: {person_name_to_find}) 调用 qv_person_name,请求上下文: '{request_context}'" + ) result = await person_info_manager.qv_person_name( person_id=person_id, user_nickname=user_nickname, user_cardname=user_cardname, user_avatar=user_avatar, - request=request_context + request=request_context, ) # 3. 处理结果 if result and result.get("nickname"): new_name = result["nickname"] - reason = result.get("reason", "未提供理由") + # reason = result.get("reason", "未提供理由") logger.info(f"成功为用户 {person_id} 取了新昵称: {new_name}") content = f"已成功将用户 {person_name_to_find} 的备注名更新为 {new_name}" @@ -93,14 +85,14 @@ class RenamePersonTool(BaseTool): # 尝试从内存中获取可能已经更新的名字 current_name = await person_info_manager.get_value(person_id, "person_name") if current_name and current_name != person_name_to_find: - return { + return { "name": self.name, - "content": f"尝试取新昵称时遇到一点小问题,但我已经将 '{person_name_to_find}' 的昵称更新为 '{current_name}' 了。" + "content": f"尝试取新昵称时遇到一点小问题,但我已经将 '{person_name_to_find}' 的昵称更新为 '{current_name}' 了。", } else: - return { + return { "name": self.name, - "content": f"尝试为 '{person_name_to_find}' 取新昵称时遇到了问题,未能成功生成。可能需要稍后再试。" + "content": f"尝试为 '{person_name_to_find}' 取新昵称时遇到了问题,未能成功生成。可能需要稍后再试。", } except Exception as e: @@ -108,5 +100,6 @@ class RenamePersonTool(BaseTool): logger.error(error_msg, exc_info=True) return {"type": "info_error", "id": f"rename_error_{time.time()}", "content": error_msg} + # 注册工具 -register_tool(RenamePersonTool) \ No newline at end of file +register_tool(RenamePersonTool) diff --git a/src/heart_flow/background_tasks.py b/src/heart_flow/background_tasks.py index c1730d5a5..301c2984c 100644 --- a/src/heart_flow/background_tasks.py +++ b/src/heart_flow/background_tasks.py @@ -18,7 +18,7 @@ INTEREST_EVAL_INTERVAL_SECONDS = 5 # 新增聊天超时检查间隔 NORMAL_CHAT_TIMEOUT_CHECK_INTERVAL_SECONDS = 60 # 新增状态评估间隔 -HF_JUDGE_STATE_UPDATE_INTERVAL_SECONDS = 60 +HF_JUDGE_STATE_UPDATE_INTERVAL_SECONDS = 20 # 新增私聊激活检查间隔 PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS = 5 # 与兴趣评估类似,设为5秒 diff --git a/src/heart_flow/observation.py b/src/heart_flow/observation.py index 0c63e7519..2d819a880 100644 --- a/src/heart_flow/observation.py +++ b/src/heart_flow/observation.py @@ -14,6 +14,8 @@ from src.plugins.utils.chat_message_builder import ( ) from src.plugins.utils.prompt_builder import Prompt, global_prompt_manager from typing import Optional +import difflib +from src.plugins.chat.message import MessageRecv # 添加 MessageRecv 导入 # Import the new utility function from .utils_chat import get_chat_type_and_target_info @@ -227,6 +229,70 @@ class ChattingObservation(Observation): f"Chat {self.chat_id} - 压缩早期记忆:{self.mid_memory_info}\n现在聊天内容:{self.talking_message_str}" ) + async def find_best_matching_message(self, search_str: str, min_similarity: float = 0.6) -> Optional[MessageRecv]: + """ + 在 talking_message 中查找与 search_str 最匹配的消息。 + + Args: + search_str: 要搜索的字符串。 + min_similarity: 要求的最低相似度(0到1之间)。 + + Returns: + 匹配的 MessageRecv 实例,如果找不到则返回 None。 + """ + best_match_score = -1.0 + best_match_dict = None + + if not self.talking_message: + logger.debug(f"Chat {self.chat_id}: talking_message is empty, cannot find match for '{search_str}'") + return None + + for message_dict in self.talking_message: + try: + # 临时创建 MessageRecv 以处理文本 + temp_msg = MessageRecv(message_dict) + await temp_msg.process() # 处理消息以获取 processed_plain_text + current_text = temp_msg.processed_plain_text + + if not current_text: # 跳过没有文本内容的消息 + continue + + # 计算相似度 + matcher = difflib.SequenceMatcher(None, search_str, current_text) + score = matcher.ratio() + + # logger.debug(f"Comparing '{search_str}' with '{current_text}', score: {score}") # 可选:用于调试 + + if score > best_match_score: + best_match_score = score + best_match_dict = message_dict + + except Exception as e: + logger.error(f"Error processing message for matching in chat {self.chat_id}: {e}", exc_info=True) + continue # 继续处理下一条消息 + + if best_match_dict is not None and best_match_score >= min_similarity: + logger.debug(f"Found best match for '{search_str}' with score {best_match_score:.2f}") + try: + final_msg = MessageRecv(best_match_dict) + await final_msg.process() + # 确保 MessageRecv 实例有关联的 chat_stream + if hasattr(self, "chat_stream"): + final_msg.update_chat_stream(self.chat_stream) + else: + logger.warning( + f"ChattingObservation instance for chat {self.chat_id} does not have a chat_stream attribute set." + ) + return final_msg + except Exception as e: + logger.error(f"Error creating final MessageRecv for chat {self.chat_id}: {e}", exc_info=True) + return None + else: + logger.debug( + f"No suitable match found for '{search_str}' in chat {self.chat_id} (best score: {best_match_score:.2f}, threshold: {min_similarity})" + ) + return None + async def has_new_messages_since(self, timestamp: float) -> bool: """检查指定时间戳之后是否有新消息""" count = num_new_messages_since(chat_id=self.chat_id, timestamp_start=timestamp) diff --git a/src/heart_flow/sub_mind.py b/src/heart_flow/sub_mind.py index 0dfc836c2..1275fbbf4 100644 --- a/src/heart_flow/sub_mind.py +++ b/src/heart_flow/sub_mind.py @@ -1,4 +1,4 @@ -from .observation import Observation, ChattingObservation +from .observation import ChattingObservation from src.plugins.models.utils_model import LLMRequest from src.config.config import global_config import time @@ -146,10 +146,9 @@ class SubMind: lines = ["【信息】"] for item in self.structured_info: # 简化展示,突出内容和类型,包含TTL供调试 - type_str = item.get('type', '未知类型') - content_str = item.get('content', '') - ttl = item.get('ttl', '?') - + type_str = item.get("type", "未知类型") + content_str = item.get("content", "") + if type_str == "info": lines.append(f"刚刚: {content_str}") elif type_str == "memory": @@ -178,18 +177,24 @@ class SubMind: # ---------- 0. 更新和清理 structured_info ---------- if self.structured_info: - logger.debug(f"{self.log_prefix} 更新前的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}") + logger.debug( + f"{self.log_prefix} 更新前的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}" + ) updated_info = [] for item in self.structured_info: - item['ttl'] -= 1 - if item['ttl'] > 0: + item["ttl"] -= 1 + if item["ttl"] > 0: updated_info.append(item) else: logger.debug(f"{self.log_prefix} 移除过期的 structured_info 项: {item['id']}") self.structured_info = updated_info - logger.debug(f"{self.log_prefix} 更新后的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}") + logger.debug( + f"{self.log_prefix} 更新后的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}" + ) self._update_structured_info_str() - logger.debug(f"{self.log_prefix} 当前完整的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}") + logger.debug( + f"{self.log_prefix} 当前完整的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}" + ) # ---------- 1. 准备基础数据 ---------- # 获取现有想法和情绪状态 @@ -202,10 +207,10 @@ class SubMind: logger.error(f"{self.log_prefix} 无法获取有效的观察对象或缺少聊天类型信息") self.update_current_mind("(观察出错了...)") return self.current_mind, self.past_mind - + is_group_chat = observation.is_group_chat # logger.debug(f"is_group_chat: {is_group_chat}") - + chat_target_info = observation.chat_target_info chat_target_name = "对方" # Default for private if not is_group_chat and chat_target_info: @@ -496,7 +501,7 @@ class SubMind: tool_instance: 工具使用器实例 """ tool_results = [] - new_structured_items = [] # 收集新产生的结构化信息 + new_structured_items = [] # 收集新产生的结构化信息 # 执行所有工具调用 for tool_call in tool_calls: @@ -506,26 +511,26 @@ class SubMind: tool_results.append(result) # 创建新的结构化信息项 new_item = { - "type": result.get("type", "unknown_type"), # 使用 'type' 键 - "id": result.get("id", f"fallback_id_{time.time()}"), # 使用 'id' 键 - "content": result.get("content", ""), # 'content' 键保持不变 - "ttl": 3 + "type": result.get("type", "unknown_type"), # 使用 'type' 键 + "id": result.get("id", f"fallback_id_{time.time()}"), # 使用 'id' 键 + "content": result.get("content", ""), # 'content' 键保持不变 + "ttl": 3, } new_structured_items.append(new_item) except Exception as tool_e: logger.error(f"[{self.subheartflow_id}] 工具执行失败: {tool_e}") - logger.error(traceback.format_exc()) # 添加 traceback 记录 + logger.error(traceback.format_exc()) # 添加 traceback 记录 # 如果有新的工具结果,记录并更新结构化信息 if new_structured_items: - self.structured_info.extend(new_structured_items) # 添加到现有列表 + self.structured_info.extend(new_structured_items) # 添加到现有列表 logger.debug(f"工具调用收集到新的结构化信息: {safe_json_dumps(new_structured_items, ensure_ascii=False)}") # logger.debug(f"当前完整的 structured_info: {safe_json_dumps(self.structured_info, ensure_ascii=False)}") # 可以取消注释以查看完整列表 - self._update_structured_info_str() # 添加新信息后,更新字符串表示 + self._update_structured_info_str() # 添加新信息后,更新字符串表示 def update_current_mind(self, response): - if self.current_mind: # 只有当 current_mind 非空时才添加到 past_mind + if self.current_mind: # 只有当 current_mind 非空时才添加到 past_mind self.past_mind.append(self.current_mind) # 可以考虑限制 past_mind 的大小,例如: # max_past_mind_size = 10 diff --git a/src/heart_flow/subheartflow_manager.py b/src/heart_flow/subheartflow_manager.py index fa8aaa964..f06a68c87 100644 --- a/src/heart_flow/subheartflow_manager.py +++ b/src/heart_flow/subheartflow_manager.py @@ -128,7 +128,7 @@ class SubHeartflowManager: # 添加聊天观察者 observation = ChattingObservation(chat_id=subheartflow_id) await observation.initialize() - + new_subflow.add_observation(observation) # 注册子心流 diff --git a/src/plugins/chat/bot.py b/src/plugins/chat/bot.py index dd65ca1cd..9c4a33581 100644 --- a/src/plugins/chat/bot.py +++ b/src/plugins/chat/bot.py @@ -82,15 +82,14 @@ class ChatBot: if userinfo.user_id in global_config.ban_user_id: logger.debug(f"用户{userinfo.user_id}被禁止回复") return - + if groupinfo is None: logger.trace("检测到私聊消息,检查") - # 好友黑名单拦截 + # 好友黑名单拦截 if userinfo.user_id not in global_config.talk_allowed_private: logger.debug(f"用户{userinfo.user_id}没有私聊权限") return - # 群聊黑名单拦截 if groupinfo is not None and groupinfo.group_id not in global_config.talk_allowed_groups: logger.trace(f"群{groupinfo.group_id}被禁止回复") diff --git a/src/plugins/chat/message.py b/src/plugins/chat/message.py index a29d0ab29..a0ff33ab4 100644 --- a/src/plugins/chat/message.py +++ b/src/plugins/chat/message.py @@ -294,7 +294,9 @@ class MessageSending(MessageProcessBase): def set_reply(self, reply: Optional["MessageRecv"] = None): """设置回复消息""" - if self.message_info.format_info is not None and "reply" in self.message_info.format_info.accept_format: + # print(f"set_reply: {reply}") + # if self.message_info.format_info is not None and "reply" in self.message_info.format_info.accept_format: + if True: if reply: self.reply = reply if self.reply: diff --git a/src/plugins/chat/message_sender.py b/src/plugins/chat/message_sender.py index c159a4bb7..8663be56b 100644 --- a/src/plugins/chat/message_sender.py +++ b/src/plugins/chat/message_sender.py @@ -209,24 +209,31 @@ class MessageManager: _ = message.update_thinking_time() # 更新思考时间 thinking_start_time = message.thinking_start_time now_time = time.time() + logger.debug(f"thinking_start_time:{thinking_start_time},now_time:{now_time}") thinking_messages_count, thinking_messages_length = count_messages_between( start_time=thinking_start_time, end_time=now_time, stream_id=message.chat_stream.stream_id ) + # print(f"message.reply:{message.reply}") # --- 条件应用 set_reply 逻辑 --- + logger.debug( + f"[message.apply_set_reply_logic:{message.apply_set_reply_logic},message.is_head:{message.is_head},thinking_messages_count:{thinking_messages_count},thinking_messages_length:{thinking_messages_length},message.is_private_message():{message.is_private_message()}]" + ) if ( message.apply_set_reply_logic # 检查标记 and message.is_head - and (thinking_messages_count > 4 or thinking_messages_length > 250) + and (thinking_messages_count > 1 or thinking_messages_length > 20) and not message.is_private_message() ): logger.debug( f"[{message.chat_stream.stream_id}] 应用 set_reply 逻辑: {message.processed_plain_text[:20]}..." ) - message.set_reply() + message.set_reply(message.reply) # --- 结束条件 set_reply --- await message.process() # 预处理消息内容 + + logger.debug(f"{message}") # 使用全局 message_sender 实例 await send_message(message) diff --git a/src/plugins/chat/utils.py b/src/plugins/chat/utils.py index 9b71ecc5f..53e8f6f6e 100644 --- a/src/plugins/chat/utils.py +++ b/src/plugins/chat/utils.py @@ -6,13 +6,13 @@ from collections import Counter import jieba import numpy as np from src.common.logger import get_module_logger +from pymongo.errors import PyMongoError from ..models.utils_model import LLMRequest from ..utils.typo_generator import ChineseTypoGenerator from ...config.config import global_config -from .message import MessageRecv, Message +from .message import MessageRecv from maim_message import UserInfo -from .chat_stream import ChatStream from ..moods.moods import MoodManager from ...common.database import db @@ -107,8 +107,6 @@ async def get_embedding(text, request_type="embedding"): return embedding - - def get_recent_group_detailed_plain_text(chat_stream_id: str, limit: int = 12, combine=False): recent_messages = list( db.messages.find( @@ -566,93 +564,45 @@ def count_messages_between(start_time: float, end_time: float, stream_id: str) - """计算两个时间点之间的消息数量和文本总长度 Args: - start_time (float): 起始时间戳 - end_time (float): 结束时间戳 + start_time (float): 起始时间戳 (不包含) + end_time (float): 结束时间戳 (包含) stream_id (str): 聊天流ID Returns: tuple[int, int]: (消息数量, 文本总长度) - - 消息数量:包含起始时间的消息,不包含结束时间的消息 - - 文本总长度:所有消息的processed_plain_text长度之和 """ + count = 0 + total_length = 0 + + # 参数校验 (可选但推荐) + if start_time >= end_time: + # logger.debug(f"开始时间 {start_time} 大于或等于结束时间 {end_time},返回 0, 0") + return 0, 0 + if not stream_id: + logger.error("stream_id 不能为空") + return 0, 0 + + # 直接查询时间范围内的消息 + # time > start_time AND time <= end_time + query = {"chat_id": stream_id, "time": {"$gt": start_time, "$lte": end_time}} + try: - # 获取开始时间之前最新的一条消息 - start_message = db.messages.find_one( - {"chat_id": stream_id, "time": {"$lte": start_time}}, - sort=[("time", -1), ("_id", -1)], # 按时间倒序,_id倒序(最后插入的在前) - ) + # 执行查询 + messages_cursor = db.messages.find(query) - # 获取结束时间最近的一条消息 - # 先找到结束时间点的所有消息 - 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: + # 遍历结果计算数量和长度 + for msg in messages_cursor: 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")) - # }) + total_length += len(msg.get("processed_plain_text", "")) - # 如果时间不同,需要把end_message本身也计入 - return count - 1, total_length + # logger.debug(f"查询范围 ({start_time}, {end_time}] 内找到 {count} 条消息,总长度 {total_length}") + return count, total_length - except Exception as e: - logger.error(f"计算消息数量时出错: {str(e)}") + except PyMongoError as e: + logger.error(f"查询 stream_id={stream_id} 在 ({start_time}, {end_time}] 范围内的消息时出错: {e}") + return 0, 0 + except Exception as e: # 保留一个通用异常捕获以防万一 + logger.error(f"计算消息数量时发生意外错误: {e}") return 0, 0 diff --git a/src/plugins/heartFC_chat/heartflow_prompt_builder.py b/src/plugins/heartFC_chat/heartflow_prompt_builder.py index 92346c93d..c59168a7f 100644 --- a/src/plugins/heartFC_chat/heartflow_prompt_builder.py +++ b/src/plugins/heartFC_chat/heartflow_prompt_builder.py @@ -372,6 +372,7 @@ class PromptBuilder: memory_prompt = await global_prompt_manager.format_prompt( "memory_prompt", related_memory_info=related_memory_info ) + message_list_before_now = get_raw_msg_before_timestamp_with_chat( chat_id=chat_stream.stream_id, timestamp=time.time(), diff --git a/src/plugins/heartFC_chat/normal_chat.py b/src/plugins/heartFC_chat/normal_chat.py index 5b5e8e88f..70568f835 100644 --- a/src/plugins/heartFC_chat/normal_chat.py +++ b/src/plugins/heartFC_chat/normal_chat.py @@ -86,11 +86,12 @@ class NormalChat: bot_user_info=bot_user_info, reply=message, thinking_start_time=thinking_time_point, - timestamp=timestamp if timestamp is not None else None + timestamp=timestamp if timestamp is not None else None, ) await message_manager.add_message(thinking_message) return thinking_id + # 改为实例方法 async def _add_messages_to_manager( self, message: MessageRecv, response_set: List[str], thinking_id @@ -206,7 +207,10 @@ class NormalChat: try: # 处理消息 await self.normal_response( - message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response = False + message=message, + is_mentioned=is_mentioned, + interested_rate=interest_value, + rewind_response=False, ) except Exception as e: logger.error(f"[{self.stream_name}] 处理兴趣消息{msg_id}时出错: {e}\n{traceback.format_exc()}") @@ -214,7 +218,9 @@ class NormalChat: self.interest_dict.pop(msg_id, None) # 改为实例方法, 移除 chat 参数 - async def normal_response(self, message: MessageRecv, is_mentioned: bool, interested_rate: float, rewind_response: bool = False) -> None: + async def normal_response( + self, message: MessageRecv, is_mentioned: bool, interested_rate: float, rewind_response: bool = False + ) -> None: # 检查收到的消息是否属于当前实例处理的 chat stream if message.chat_stream.stream_id != self.stream_id: logger.error( @@ -393,13 +399,17 @@ class NormalChat: try: logger.info(f"[{self.stream_name}] 处理初始高兴趣消息 {msg_id} (兴趣值: {interest_value:.2f})") - await self.normal_response(message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response = True) + await self.normal_response( + message=message, is_mentioned=is_mentioned, interested_rate=interest_value, rewind_response=True + ) processed_count += 1 except Exception as e: logger.error(f"[{self.stream_name}] 处理初始兴趣消息 {msg_id} 时出错: {e}\\n{traceback.format_exc()}") # --- 新增:处理完后清空整个字典 --- - logger.info(f"[{self.stream_name}] 处理了 {processed_count} 条初始高兴趣消息。现在清空所有剩余的初始兴趣消息...") + logger.info( + f"[{self.stream_name}] 处理了 {processed_count} 条初始高兴趣消息。现在清空所有剩余的初始兴趣消息..." + ) self.interest_dict.clear() # --- 新增结束 --- diff --git a/src/plugins/person_info/person_info.py b/src/plugins/person_info/person_info.py index e95fffdb5..d4e69d7e2 100644 --- a/src/plugins/person_info/person_info.py +++ b/src/plugins/person_info/person_info.py @@ -188,7 +188,9 @@ class PersonInfoManager: logger.warning(f"无法从文本中提取有效的JSON字典: {text}") return {"nickname": "", "reason": ""} - async def qv_person_name(self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str, request: str = ""): + async def qv_person_name( + self, person_id: str, user_nickname: str, user_cardname: str, user_avatar: str, request: str = "" + ): """给某个用户取名""" if not person_id: logger.debug("取名失败:person_id不能为空") @@ -214,7 +216,7 @@ class PersonInfoManager: qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason}," qv_name_prompt += f"\n其他取名的要求是:{request}" - + qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,请最好使用用户的qq昵称,可以稍作修改" if existing_names: qv_name_prompt += f"\n请注意,以下名称已被使用,不要使用以下昵称:{existing_names}。\n" @@ -526,7 +528,7 @@ class PersonInfoManager: for pid, name in self.person_name_list.items(): if name == person_name: found_person_id = pid - break # 找到第一个匹配就停止 + break # 找到第一个匹配就停止 if not found_person_id: # 如果内存没有,尝试数据库查询(可能内存未及时更新或启动时未加载) @@ -535,21 +537,21 @@ class PersonInfoManager: found_person_id = document.get("person_id") else: logger.debug(f"数据库中也未找到名为 '{person_name}' 的用户") - return None # 数据库也找不到 + return None # 数据库也找不到 # 根据找到的 person_id 获取所需信息 if found_person_id: required_fields = ["person_id", "platform", "user_id", "nickname", "user_cardname", "user_avatar"] person_data = await self.get_values(found_person_id, required_fields) - if person_data: # 确保 get_values 成功返回 + if person_data: # 确保 get_values 成功返回 return person_data else: logger.warning(f"找到了 person_id '{found_person_id}' 但获取详细信息失败") return None else: - # 这理论上不应该发生,因为上面已经处理了找不到的情况 - logger.error(f"逻辑错误:未能为 '{person_name}' 确定 person_id") - return None + # 这理论上不应该发生,因为上面已经处理了找不到的情况 + logger.error(f"逻辑错误:未能为 '{person_name}' 确定 person_id") + return None person_info_manager = PersonInfoManager()