From 289a92293b0194d5662ddf15218a3947e1a61ccf Mon Sep 17 00:00:00 2001 From: tcmofashi Date: Wed, 2 Jul 2025 13:05:57 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=AE=B5mention=5Fbot=E7=9A=84=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/message_receive/message.py | 8 ++------ src/chat/normal_chat/normal_chat.py | 6 +++++- src/chat/utils/utils.py | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/chat/message_receive/message.py b/src/chat/message_receive/message.py index 1c8f7789e..6f2c3f784 100644 --- a/src/chat/message_receive/message.py +++ b/src/chat/message_receive/message.py @@ -108,7 +108,7 @@ class MessageRecv(Message): self.detailed_plain_text = message_dict.get("detailed_plain_text", "") self.is_emoji = False self.is_picid = False - self.is_mentioned = 0.0 + self.is_mentioned = None self.priority_mode = "interest" self.priority_info = None @@ -152,14 +152,10 @@ class MessageRecv(Message): elif segment.type == "mention_bot": self.is_mentioned = float(segment.data) return "" - elif segment.type == "set_priority_mode": - # 处理设置优先级模式的消息段 - if isinstance(segment.data, str): - self.priority_mode = segment.data - return "" elif segment.type == "priority_info": if isinstance(segment.data, dict): # 处理优先级信息 + self.priority_mode = "priority" self.priority_info = segment.data """ { diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index 6c285f21d..04958b607 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -494,7 +494,11 @@ class NormalChat: # 检查是否有用户满足关系构建条件 asyncio.create_task(self._check_relation_building_conditions()) - await self.reply_one_message(message) + do_reply = await self.reply_one_message(message) + response_set = do_reply if do_reply else [] + factor = 0.5 + cnt = sum([len(r) for r in response_set]) + await asyncio.sleep(max(1, factor * cnt - 3)) # 等待tts # 等待一段时间再检查队列 await asyncio.sleep(1) diff --git a/src/chat/utils/utils.py b/src/chat/utils/utils.py index a147846ca..edfb9f31c 100644 --- a/src/chat/utils/utils.py +++ b/src/chat/utils/utils.py @@ -47,7 +47,8 @@ def is_mentioned_bot_in_message(message: MessageRecv) -> tuple[bool, float]: reply_probability = 0.0 is_at = False is_mentioned = False - + if message.is_mentioned is not None: + return bool(message.is_mentioned), message.is_mentioned if ( message.message_info.additional_config is not None and message.message_info.additional_config.get("is_mentioned") is not None From 482a171710f0a91344cf5d6a7fe0632bb7715497 Mon Sep 17 00:00:00 2001 From: tcmofashi Date: Wed, 2 Jul 2025 13:25:05 +0800 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BC=A9?= =?UTF-8?q?=E8=BF=9B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/normal_chat/normal_chat.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index be13c0605..4d37ff08f 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -808,7 +808,6 @@ class NormalChat: # 回复前处理 thinking_id = await self._create_thinking_message(message) - # 如果启用planner,预先修改可用actions(避免在并行任务中重复调用) available_actions = None if self.enable_planner: @@ -821,19 +820,17 @@ class NormalChat: logger.warning(f"[{self.stream_name}] 获取available_actions失败: {e}") available_actions = None - # 定义并行执行的任务 - async def generate_normal_response(): - """生成普通回复""" - try: - return await self.gpt.generate_response( - message=message, - available_actions=available_actions, - ) - except Exception as e: - logger.error(f"[{self.stream_name}] 回复生成出现错误:{str(e)} {traceback.format_exc()}") - return None - - + # 定义并行执行的任务 + async def generate_normal_response(): + """生成普通回复""" + try: + return await self.gpt.generate_response( + message=message, + available_actions=available_actions, + ) + except Exception as e: + logger.error(f"[{self.stream_name}] 回复生成出现错误:{str(e)} {traceback.format_exc()}") + return None async def plan_and_execute_actions(): """规划和执行额外动作""" From 869a02d232221d26bb16f54396d580e649b01d44 Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:10:14 +0800 Subject: [PATCH 03/11] Update planner_simple.py --- src/chat/focus_chat/planners/planner_simple.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/chat/focus_chat/planners/planner_simple.py b/src/chat/focus_chat/planners/planner_simple.py index 20f41c711..05c57dcf6 100644 --- a/src/chat/focus_chat/planners/planner_simple.py +++ b/src/chat/focus_chat/planners/planner_simple.py @@ -29,6 +29,11 @@ def init_prompt(): {chat_context_description},以下是具体的聊天内容: {chat_content_block} {moderation_prompt} + +重要提醒:避免重复回复同一话题 +- 如果你在最近1分钟内已经对某个话题进行了回复,不要再次回复相同或相似的内容 +- 如果聊天记录显示你刚刚已经回复过相似内容,即使话题仍然在进行,也应该选择no_reply + 现在请你根据聊天内容选择合适的action: {action_options_text} From 54516bc8731227852db9acd075419798ee2ea3fe Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:19:13 +0800 Subject: [PATCH 04/11] Update planner_simple.py --- src/chat/focus_chat/planners/planner_simple.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/chat/focus_chat/planners/planner_simple.py b/src/chat/focus_chat/planners/planner_simple.py index 05c57dcf6..0b7aa96e7 100644 --- a/src/chat/focus_chat/planners/planner_simple.py +++ b/src/chat/focus_chat/planners/planner_simple.py @@ -30,9 +30,7 @@ def init_prompt(): {chat_content_block} {moderation_prompt} -重要提醒:避免重复回复同一话题 -- 如果你在最近1分钟内已经对某个话题进行了回复,不要再次回复相同或相似的内容 -- 如果聊天记录显示你刚刚已经回复过相似内容,即使话题仍然在进行,也应该选择no_reply +重要提醒:如果聊天记录显示你刚刚已经回复过相似内容,即使话题仍然在进行,必须选择no_reply 现在请你根据聊天内容选择合适的action: From 2a0dfb7642209723628e0d205e59847f06a3f3d0 Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:25:15 +0800 Subject: [PATCH 05/11] Update working_memory_processor.py --- .../working_memory_processor.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/chat/focus_chat/info_processors/working_memory_processor.py b/src/chat/focus_chat/info_processors/working_memory_processor.py index 2de0bcfab..f81833c00 100644 --- a/src/chat/focus_chat/info_processors/working_memory_processor.py +++ b/src/chat/focus_chat/info_processors/working_memory_processor.py @@ -71,6 +71,7 @@ class WorkingMemoryProcessor(BaseProcessor): """ working_memory = None chat_info = "" + chat_obs = None try: for observation in observations: if isinstance(observation, WorkingMemoryObservation): @@ -79,10 +80,15 @@ class WorkingMemoryProcessor(BaseProcessor): chat_info = observation.get_observe_info() chat_obs = observation # 检查是否有待压缩内容 - if chat_obs.compressor_prompt: + if chat_obs and chat_obs.compressor_prompt: logger.debug(f"{self.log_prefix} 压缩聊天记忆") await self.compress_chat_memory(working_memory, chat_obs) + # 检查working_memory是否为None + if working_memory is None: + logger.debug(f"{self.log_prefix} 没有找到工作记忆观察,跳过处理") + return [] + all_memory = working_memory.get_all_memories() if not all_memory: logger.debug(f"{self.log_prefix} 目前没有工作记忆,跳过提取") @@ -183,6 +189,11 @@ class WorkingMemoryProcessor(BaseProcessor): working_memory: 工作记忆对象 obs: 聊天观察对象 """ + # 检查working_memory是否为None + if working_memory is None: + logger.warning(f"{self.log_prefix} 工作记忆对象为None,无法压缩聊天记忆") + return + try: summary_result, _ = await self.llm_model.generate_response_async(obs.compressor_prompt) if not summary_result: @@ -235,6 +246,11 @@ class WorkingMemoryProcessor(BaseProcessor): memory_id1: 第一个记忆ID memory_id2: 第二个记忆ID """ + # 检查working_memory是否为None + if working_memory is None: + logger.warning(f"{self.log_prefix} 工作记忆对象为None,无法合并记忆") + return + try: merged_memory = await working_memory.merge_memory(memory_id1, memory_id2) logger.debug(f"{self.log_prefix} 合并后的记忆梗概: {merged_memory.brief}") From c0de1fcc3f130f4e428c1da54288530100141cf8 Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:25:37 +0800 Subject: [PATCH 06/11] Update knowledge_lib.py --- src/chat/knowledge/knowledge_lib.py | 108 +++++++++++++++------------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/src/chat/knowledge/knowledge_lib.py b/src/chat/knowledge/knowledge_lib.py index 6a4fcd4ea..a9d603b9f 100644 --- a/src/chat/knowledge/knowledge_lib.py +++ b/src/chat/knowledge/knowledge_lib.py @@ -5,60 +5,68 @@ from src.chat.knowledge.mem_active_manager import MemoryActiveManager from src.chat.knowledge.qa_manager import QAManager from src.chat.knowledge.kg_manager import KGManager from src.chat.knowledge.global_logger import logger +from src.config.config import global_config as bot_global_config # try: # import quick_algo # except ImportError: # print("quick_algo not found, please install it first") -logger.info("正在初始化Mai-LPMM\n") -logger.info("创建LLM客户端") -llm_client_list = dict() -for key in global_config["llm_providers"]: - llm_client_list[key] = LLMClient( - global_config["llm_providers"][key]["base_url"], - global_config["llm_providers"][key]["api_key"], +# 检查LPMM知识库是否启用 +if bot_global_config.lpmm_knowledge.enable: + logger.info("正在初始化Mai-LPMM\n") + logger.info("创建LLM客户端") + llm_client_list = dict() + for key in global_config["llm_providers"]: + llm_client_list[key] = LLMClient( + global_config["llm_providers"][key]["base_url"], + global_config["llm_providers"][key]["api_key"], + ) + + # 初始化Embedding库 + embed_manager = EmbeddingManager(llm_client_list[global_config["embedding"]["provider"]]) + logger.info("正在从文件加载Embedding库") + try: + embed_manager.load_from_file() + except Exception as e: + logger.warning("此消息不会影响正常使用:从文件加载Embedding库时,{}".format(e)) + # logger.warning("如果你是第一次导入知识,或者还未导入知识,请忽略此错误") + logger.info("Embedding库加载完成") + # 初始化KG + kg_manager = KGManager() + logger.info("正在从文件加载KG") + try: + kg_manager.load_from_file() + except Exception as e: + logger.warning("此消息不会影响正常使用:从文件加载KG时,{}".format(e)) + # logger.warning("如果你是第一次导入知识,或者还未导入知识,请忽略此错误") + logger.info("KG加载完成") + + logger.info(f"KG节点数量:{len(kg_manager.graph.get_node_list())}") + logger.info(f"KG边数量:{len(kg_manager.graph.get_edge_list())}") + + + # 数据比对:Embedding库与KG的段落hash集合 + for pg_hash in kg_manager.stored_paragraph_hashes: + key = PG_NAMESPACE + "-" + pg_hash + if key not in embed_manager.stored_pg_hashes: + logger.warning(f"KG中存在Embedding库中不存在的段落:{key}") + + # 问答系统(用于知识库) + qa_manager = QAManager( + embed_manager, + kg_manager, + llm_client_list[global_config["embedding"]["provider"]], + llm_client_list[global_config["qa"]["llm"]["provider"]], + llm_client_list[global_config["qa"]["llm"]["provider"]], ) -# 初始化Embedding库 -embed_manager = EmbeddingManager(llm_client_list[global_config["embedding"]["provider"]]) -logger.info("正在从文件加载Embedding库") -try: - embed_manager.load_from_file() -except Exception as e: - logger.warning("此消息不会影响正常使用:从文件加载Embedding库时,{}".format(e)) - # logger.warning("如果你是第一次导入知识,或者还未导入知识,请忽略此错误") -logger.info("Embedding库加载完成") -# 初始化KG -kg_manager = KGManager() -logger.info("正在从文件加载KG") -try: - kg_manager.load_from_file() -except Exception as e: - logger.warning("此消息不会影响正常使用:从文件加载KG时,{}".format(e)) - # logger.warning("如果你是第一次导入知识,或者还未导入知识,请忽略此错误") -logger.info("KG加载完成") - -logger.info(f"KG节点数量:{len(kg_manager.graph.get_node_list())}") -logger.info(f"KG边数量:{len(kg_manager.graph.get_edge_list())}") - - -# 数据比对:Embedding库与KG的段落hash集合 -for pg_hash in kg_manager.stored_paragraph_hashes: - key = PG_NAMESPACE + "-" + pg_hash - if key not in embed_manager.stored_pg_hashes: - logger.warning(f"KG中存在Embedding库中不存在的段落:{key}") - -# 问答系统(用于知识库) -qa_manager = QAManager( - embed_manager, - kg_manager, - llm_client_list[global_config["embedding"]["provider"]], - llm_client_list[global_config["qa"]["llm"]["provider"]], - llm_client_list[global_config["qa"]["llm"]["provider"]], -) - -# 记忆激活(用于记忆库) -inspire_manager = MemoryActiveManager( - embed_manager, - llm_client_list[global_config["embedding"]["provider"]], -) + # 记忆激活(用于记忆库) + inspire_manager = MemoryActiveManager( + embed_manager, + llm_client_list[global_config["embedding"]["provider"]], + ) +else: + logger.info("LPMM知识库已禁用,跳过初始化") + # 创建空的占位符对象,避免导入错误 + qa_manager = None + inspire_manager = None From 9c0271b10f8f83277c662d36f4b805e3ee4f0141 Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:25:51 +0800 Subject: [PATCH 07/11] Update default_generator.py --- src/chat/replyer/default_generator.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index da9d9a584..1f0b438dc 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -956,6 +956,11 @@ async def get_prompt_info(message: str, threshold: float): logger.debug(f"获取知识库内容,元消息:{message[:30]}...,消息长度: {len(message)}") # 从LPMM知识库获取知识 try: + # 检查LPMM知识库是否启用 + if qa_manager is None: + logger.debug("LPMM知识库已禁用,跳过知识获取") + return "" + found_knowledge_from_lpmm = qa_manager.get_knowledge(message) end_time = time.time() From cb5fa45523ceb79e142e31f8dee6160c4e6e0bac Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:26:07 +0800 Subject: [PATCH 08/11] Update pfc_KnowledgeFetcher.py --- src/experimental/PFC/pfc_KnowledgeFetcher.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/experimental/PFC/pfc_KnowledgeFetcher.py b/src/experimental/PFC/pfc_KnowledgeFetcher.py index 38a6dafb9..c52533ea6 100644 --- a/src/experimental/PFC/pfc_KnowledgeFetcher.py +++ b/src/experimental/PFC/pfc_KnowledgeFetcher.py @@ -35,6 +35,11 @@ class KnowledgeFetcher: logger.debug(f"[私聊][{self.private_name}]正在从LPMM知识库中获取知识") try: + # 检查LPMM知识库是否启用 + if qa_manager is None: + logger.debug(f"[私聊][{self.private_name}]LPMM知识库已禁用,跳过知识获取") + return "未找到匹配的知识" + knowledge_info = qa_manager.get_knowledge(query) logger.debug(f"[私聊][{self.private_name}]LPMM知识库查询结果: {knowledge_info:150}") return knowledge_info From 1da67ae067831714c6ff25b8a3ff70ea4d6c6cc1 Mon Sep 17 00:00:00 2001 From: "CNMr.Sunshine" <61444298+CNMrSunshine@users.noreply.github.com> Date: Sun, 6 Jul 2025 11:26:22 +0800 Subject: [PATCH 09/11] Update lpmm_get_knowledge.py --- src/tools/not_using/lpmm_get_knowledge.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/not_using/lpmm_get_knowledge.py b/src/tools/not_using/lpmm_get_knowledge.py index df4fa6a4f..80b9b617b 100644 --- a/src/tools/not_using/lpmm_get_knowledge.py +++ b/src/tools/not_using/lpmm_get_knowledge.py @@ -36,6 +36,11 @@ class SearchKnowledgeFromLPMMTool(BaseTool): query = function_args.get("query") # threshold = function_args.get("threshold", 0.4) + # 检查LPMM知识库是否启用 + if qa_manager is None: + logger.debug("LPMM知识库已禁用,跳过知识获取") + return {"type": "info", "id": query, "content": "LPMM知识库已禁用"} + # 调用知识库搜索 knowledge_info = qa_manager.get_knowledge(query) From f624547034cf7c9f6e6f5bef57a78117bd333e92 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Sun, 6 Jul 2025 11:40:12 +0800 Subject: [PATCH 10/11] Update planner_simple.py --- src/chat/focus_chat/planners/planner_simple.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/chat/focus_chat/planners/planner_simple.py b/src/chat/focus_chat/planners/planner_simple.py index 0b7aa96e7..3d044d6e7 100644 --- a/src/chat/focus_chat/planners/planner_simple.py +++ b/src/chat/focus_chat/planners/planner_simple.py @@ -30,8 +30,6 @@ def init_prompt(): {chat_content_block} {moderation_prompt} -重要提醒:如果聊天记录显示你刚刚已经回复过相似内容,即使话题仍然在进行,必须选择no_reply - 现在请你根据聊天内容选择合适的action: {action_options_text} From 871d3ee7450e6233bcd7f56182358121c3b50d01 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 6 Jul 2025 03:42:36 +0000 Subject: [PATCH 11/11] =?UTF-8?q?=F0=9F=A4=96=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3=E7=A0=81=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../focus_chat/info_processors/working_memory_processor.py | 4 ++-- src/chat/knowledge/knowledge_lib.py | 1 - src/chat/replyer/default_generator.py | 2 +- src/experimental/PFC/pfc_KnowledgeFetcher.py | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/chat/focus_chat/info_processors/working_memory_processor.py b/src/chat/focus_chat/info_processors/working_memory_processor.py index f81833c00..abe9786d4 100644 --- a/src/chat/focus_chat/info_processors/working_memory_processor.py +++ b/src/chat/focus_chat/info_processors/working_memory_processor.py @@ -193,7 +193,7 @@ class WorkingMemoryProcessor(BaseProcessor): if working_memory is None: logger.warning(f"{self.log_prefix} 工作记忆对象为None,无法压缩聊天记忆") return - + try: summary_result, _ = await self.llm_model.generate_response_async(obs.compressor_prompt) if not summary_result: @@ -250,7 +250,7 @@ class WorkingMemoryProcessor(BaseProcessor): if working_memory is None: logger.warning(f"{self.log_prefix} 工作记忆对象为None,无法合并记忆") return - + try: merged_memory = await working_memory.merge_memory(memory_id1, memory_id2) logger.debug(f"{self.log_prefix} 合并后的记忆梗概: {merged_memory.brief}") diff --git a/src/chat/knowledge/knowledge_lib.py b/src/chat/knowledge/knowledge_lib.py index a9d603b9f..5540d95e2 100644 --- a/src/chat/knowledge/knowledge_lib.py +++ b/src/chat/knowledge/knowledge_lib.py @@ -44,7 +44,6 @@ if bot_global_config.lpmm_knowledge.enable: logger.info(f"KG节点数量:{len(kg_manager.graph.get_node_list())}") logger.info(f"KG边数量:{len(kg_manager.graph.get_edge_list())}") - # 数据比对:Embedding库与KG的段落hash集合 for pg_hash in kg_manager.stored_paragraph_hashes: key = PG_NAMESPACE + "-" + pg_hash diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index 1f0b438dc..1fec8646e 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -960,7 +960,7 @@ async def get_prompt_info(message: str, threshold: float): if qa_manager is None: logger.debug("LPMM知识库已禁用,跳过知识获取") return "" - + found_knowledge_from_lpmm = qa_manager.get_knowledge(message) end_time = time.time() diff --git a/src/experimental/PFC/pfc_KnowledgeFetcher.py b/src/experimental/PFC/pfc_KnowledgeFetcher.py index c52533ea6..a1d161a70 100644 --- a/src/experimental/PFC/pfc_KnowledgeFetcher.py +++ b/src/experimental/PFC/pfc_KnowledgeFetcher.py @@ -39,7 +39,7 @@ class KnowledgeFetcher: if qa_manager is None: logger.debug(f"[私聊][{self.private_name}]LPMM知识库已禁用,跳过知识获取") return "未找到匹配的知识" - + knowledge_info = qa_manager.get_knowledge(query) logger.debug(f"[私聊][{self.private_name}]LPMM知识库查询结果: {knowledge_info:150}") return knowledge_info