From 76d305696c3d902aef503618626f8e19d3062cd0 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 29 May 2025 00:44:41 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=85=B4?= =?UTF-8?q?=E8=B6=A3=E9=9B=86=E6=9C=AA=E6=B8=85=E7=A9=BA=EF=BC=8C=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=A4=B1=E8=B4=A5=E5=AF=BC=E8=87=B4planer=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=EF=BC=8C=E7=BB=98=E5=9B=BE=E6=8F=92=E4=BB=B6=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/chat/focus_chat/heartFC_chat.py | 28 +++++++++++++------ .../info_processors/self_processor.py | 2 +- .../working_memory_processor.py | 2 +- src/chat/focus_chat/memory_activator.py | 6 ++-- src/chat/focus_chat/planners/planner.py | 1 + .../observation/chatting_observation.py | 2 +- src/chat/heart_flow/sub_heartflow.py | 2 ++ .../actions/generate_pic_config.py | 13 +++------ .../test_plugin_pic/actions/pic_action.py | 4 +-- .../actions/pic_action_config.toml | 24 ---------------- 11 files changed, 35 insertions(+), 50 deletions(-) delete mode 100644 src/plugins/test_plugin_pic/actions/pic_action_config.toml diff --git a/.gitignore b/.gitignore index d6d8f50c..4b4f5b80 100644 --- a/.gitignore +++ b/.gitignore @@ -305,3 +305,4 @@ $RECYCLE.BIN/ src/chat/focus_chat/working_memory/test/test1.txt src/chat/focus_chat/working_memory/test/test4.txt run_maiserver.bat +src/plugins/test_plugin_pic/actions/pic_action_config.toml diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index ae387eb4..d5e9622f 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -54,7 +54,7 @@ CONSECUTIVE_NO_REPLY_THRESHOLD = 3 # 连续不回复的阈值 logger = get_logger("hfc") # Logger Name Changed # 设定处理器超时时间(秒) -PROCESSOR_TIMEOUT = 40 +PROCESSOR_TIMEOUT = 30 async def _handle_cycle_delay(action_taken_this_cycle: bool, cycle_start_time: float, log_prefix: str): @@ -329,11 +329,20 @@ class HeartFChatting: formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}秒" timer_strings.append(f"{name}: {formatted_time}") + # 新增:输出每个处理器的耗时 + processor_time_costs = self._current_cycle.loop_processor_info.get("processor_time_costs", {}) + processor_time_strings = [] + for pname, ptime in processor_time_costs.items(): + formatted_ptime = f"{ptime * 1000:.2f}毫秒" if ptime < 1 else f"{ptime:.2f}秒" + processor_time_strings.append(f"{pname}: {formatted_ptime}") + processor_time_log = ("\n各处理器耗时: " + "; ".join(processor_time_strings)) if processor_time_strings else "" + logger.info( f"{self.log_prefix} 第{self._current_cycle.cycle_id}次思考," f"耗时: {self._current_cycle.end_time - self._current_cycle.start_time:.1f}秒, " f"动作: {self._current_cycle.loop_plan_info['action_result']['action_type']}" + (f"\n详情: {'; '.join(timer_strings)}" if timer_strings else "") + + processor_time_log ) await asyncio.sleep(global_config.focus_chat.think_interval) @@ -369,18 +378,18 @@ class HeartFChatting: async def _process_processors( self, observations: List[Observation], running_memorys: List[Dict[str, Any]], cycle_timers: dict - ) -> List[InfoBase]: + ) -> tuple[List[InfoBase], Dict[str, float]]: # 记录并行任务开始时间 parallel_start_time = time.time() logger.debug(f"{self.log_prefix} 开始信息处理器并行任务") processor_tasks = [] task_to_name_map = {} + processor_time_costs = {} # 新增: 记录每个处理器耗时 for processor in self.processors: processor_name = processor.__class__.log_prefix - # 用lambda包裹,便于传参 async def run_with_timeout(proc=processor): return await asyncio.wait_for( proc.process_info(observations=observations, running_memorys=running_memorys), @@ -404,22 +413,24 @@ class HeartFChatting: duration_since_parallel_start = task_completed_time - parallel_start_time try: - # 使用 await task 来获取结果或触发异常 result_list = await task logger.info(f"{self.log_prefix} 处理器 {processor_name} 已完成!") if result_list is not None: all_plan_info.extend(result_list) else: logger.warning(f"{self.log_prefix} 处理器 {processor_name} 返回了 None") + # 记录耗时 + processor_time_costs[processor_name] = duration_since_parallel_start except asyncio.TimeoutError: logger.info(f"{self.log_prefix} 处理器 {processor_name} 超时(>{PROCESSOR_TIMEOUT}s),已跳过") + processor_time_costs[processor_name] = PROCESSOR_TIMEOUT except Exception as e: logger.error( f"{self.log_prefix} 处理器 {processor_name} 执行失败,耗时 (自并行开始): {duration_since_parallel_start:.2f}秒. 错误: {e}", exc_info=True, ) traceback.print_exc() - # 即使出错,也认为该任务结束了,已从 pending_tasks 中移除 + processor_time_costs[processor_name] = duration_since_parallel_start if pending_tasks: current_progress_time = time.time() @@ -435,12 +446,11 @@ class HeartFChatting: logger.info(f"{self.log_prefix} 所有处理器任务全部完成,总耗时: {total_duration:.2f}秒") # logger.debug(f"{self.log_prefix} 所有信息处理器处理后的信息: {all_plan_info}") - return all_plan_info + return all_plan_info, processor_time_costs async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> dict: try: with Timer("观察", cycle_timers): - # await self.observations[0].observe() await self.chatting_observation.observe() await self.working_observation.observe() await self.hfcloop_observation.observe() @@ -461,10 +471,11 @@ class HeartFChatting: running_memorys = await self.memory_activator.activate_memory(observations) with Timer("执行 信息处理器", cycle_timers): - all_plan_info = await self._process_processors(observations, running_memorys, cycle_timers) + all_plan_info, processor_time_costs = await self._process_processors(observations, running_memorys, cycle_timers) loop_processor_info = { "all_plan_info": all_plan_info, + "processor_time_costs": processor_time_costs, } with Timer("规划器", cycle_timers): @@ -483,7 +494,6 @@ class HeartFChatting: plan_result.get("action_result", {}).get("reasoning", "未提供理由"), ) - # 在此处添加日志记录 if action_type == "reply": action_str = "回复" elif action_type == "no_reply": diff --git a/src/chat/focus_chat/info_processors/self_processor.py b/src/chat/focus_chat/info_processors/self_processor.py index a498ec7e..cecaf308 100644 --- a/src/chat/focus_chat/info_processors/self_processor.py +++ b/src/chat/focus_chat/info_processors/self_processor.py @@ -185,7 +185,7 @@ class SelfProcessor(BaseProcessor): if content == "None": content = "" # 记录初步思考结果 - logger.debug(f"{self.log_prefix} 自我识别prompt: \n{prompt}\n") + # logger.debug(f"{self.log_prefix} 自我识别prompt: \n{prompt}\n") logger.info(f"{self.log_prefix} 自我认知: {content}") return content 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 8b601149..27af1325 100644 --- a/src/chat/focus_chat/info_processors/working_memory_processor.py +++ b/src/chat/focus_chat/info_processors/working_memory_processor.py @@ -127,7 +127,7 @@ class WorkingMemoryProcessor(BaseProcessor): # 调用LLM处理记忆 content = "" try: - logger.debug(f"{self.log_prefix} 处理工作记忆的prompt: {prompt}") + # logger.debug(f"{self.log_prefix} 处理工作记忆的prompt: {prompt}") content, _ = await self.llm_model.generate_response_async(prompt=prompt) if not content: diff --git a/src/chat/focus_chat/memory_activator.py b/src/chat/focus_chat/memory_activator.py index 2aa8fa54..a9f2c8ee 100644 --- a/src/chat/focus_chat/memory_activator.py +++ b/src/chat/focus_chat/memory_activator.py @@ -107,11 +107,11 @@ class MemoryActivator: cached_keywords=cached_keywords_str, ) - logger.debug(f"prompt: {prompt}") + # logger.debug(f"prompt: {prompt}") response = await self.summary_model.generate_response(prompt) - logger.debug(f"response: {response}") + # logger.debug(f"response: {response}") # 只取response的第一个元素(字符串) response_str = response[0] @@ -127,7 +127,7 @@ class MemoryActivator: # 添加新的关键词到缓存 self.cached_keywords.update(keywords) - logger.debug(f"更新关键词缓存: {self.cached_keywords}") + logger.debug(f"当前激活的记忆关键词: {self.cached_keywords}") # 调用记忆系统获取相关记忆 related_memory = await HippocampusManager.get_instance().get_memory_from_topic( diff --git a/src/chat/focus_chat/planners/planner.py b/src/chat/focus_chat/planners/planner.py index a914e20b..61a33990 100644 --- a/src/chat/focus_chat/planners/planner.py +++ b/src/chat/focus_chat/planners/planner.py @@ -130,6 +130,7 @@ class ActionPlanner: current_mind = "" cycle_info = "" structured_info = "" + is_group_chat = True for info in all_plan_info: if isinstance(info, ObsInfo): observed_messages = info.get_talking_message() diff --git a/src/chat/heart_flow/observation/chatting_observation.py b/src/chat/heart_flow/observation/chatting_observation.py index 187b8027..e5c5069e 100644 --- a/src/chat/heart_flow/observation/chatting_observation.py +++ b/src/chat/heart_flow/observation/chatting_observation.py @@ -179,7 +179,7 @@ class ChattingObservation(Observation): "processed_plain_text": find_msg.get("processed_plain_text"), } find_rec_msg = MessageRecv(message_dict) - logger.debug(f"锚定消息处理后:find_rec_msg: {find_rec_msg}") + # logger.debug(f"锚定消息处理后:find_rec_msg: {find_rec_msg}") return find_rec_msg async def observe(self): diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index 03667d82..435a7b61 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -111,6 +111,8 @@ class SubHeartflow: """ await self._stop_heart_fc_chat() # 确保 专注聊天已停止 + self.interest_dict.clear() + log_prefix = self.log_prefix try: # 获取聊天流并创建 NormalChat 实例 (同步部分) diff --git a/src/plugins/test_plugin_pic/actions/generate_pic_config.py b/src/plugins/test_plugin_pic/actions/generate_pic_config.py index 207e0c53..4d0ffc04 100644 --- a/src/plugins/test_plugin_pic/actions/generate_pic_config.py +++ b/src/plugins/test_plugin_pic/actions/generate_pic_config.py @@ -1,20 +1,15 @@ import os CONFIG_CONTENT = """\ -# 请替换为您的火山引擎 Access Key ID -volcano_ak = "YOUR_VOLCANO_ENGINE_ACCESS_KEY_ID_HERE" -# 请替换为您的火山引擎 Secret Access Key -volcano_sk = "YOUR_VOLCANO_ENGINE_SECRET_ACCESS_KEY_HERE" # 火山方舟 API 的基础 URL base_url = "https://ark.cn-beijing.volces.com/api/v3" +# 用于图片生成的API密钥 +volcano_generate_api_key = "YOUR_VOLCANO_GENERATE_API_KEY_HERE" # 默认图片生成模型 default_model = "doubao-seedream-3-0-t2i-250415" # 默认图片尺寸 default_size = "1024x1024" -# 用于图片生成的API密钥 -# PicAction 当前配置为在HTTP请求体和Authorization头中使用此密钥。 -# 如果您的API认证方式不同,请相应调整或移除。 -volcano_generate_api_key = "YOUR_VOLCANO_GENERATE_API_KEY_HERE" + # 是否默认开启水印 default_watermark = true @@ -38,7 +33,7 @@ def generate_config(): with open(config_file_path, "w", encoding="utf-8") as f: f.write(CONFIG_CONTENT) print(f"配置文件已生成: {config_file_path}") - print("请记得编辑该文件,填入您的火山引擎 AK/SK 和 API 密钥。") + print("请记得编辑该文件,填入您的火山引擎API 密钥。") except IOError as e: print(f"错误:无法写入配置文件 {config_file_path}。原因: {e}") else: diff --git a/src/plugins/test_plugin_pic/actions/pic_action.py b/src/plugins/test_plugin_pic/actions/pic_action.py index 6521dafc..e2eeb918 100644 --- a/src/plugins/test_plugin_pic/actions/pic_action.py +++ b/src/plugins/test_plugin_pic/actions/pic_action.py @@ -22,7 +22,7 @@ class PicAction(PluginAction): """根据描述使用火山引擎HTTP API生成图片的动作处理类""" action_name = "pic_action" - action_description = "可以根据特定的描述,使用火山引擎模型生成并发送一张图片 (通过HTTP API)" + action_description = "可以根据特定的描述,生成并发送一张图片,如果没提供描述,就根据聊天内容生成" action_parameters = { "description": "图片描述,输入你想要生成并发送的图片的描述,必填", "size": "图片尺寸,例如 '1024x1024' (可选, 默认从配置或 '1024x1024')", @@ -31,7 +31,7 @@ class PicAction(PluginAction): "当有人要求你生成并发送一张图片时使用", "当有人让你画一张图时使用", ] - default = False + default = True action_config_file_name = "pic_action_config.toml" def __init__( diff --git a/src/plugins/test_plugin_pic/actions/pic_action_config.toml b/src/plugins/test_plugin_pic/actions/pic_action_config.toml deleted file mode 100644 index 2d2b55a3..00000000 --- a/src/plugins/test_plugin_pic/actions/pic_action_config.toml +++ /dev/null @@ -1,24 +0,0 @@ -# 请替换为您的火山引擎 Access Key ID -volcano_ak = "YOUR_VOLCANO_ENGINE_ACCESS_KEY_ID_HERE" -# 请替换为您的火山引擎 Secret Access Key -volcano_sk = "YOUR_VOLCANO_ENGINE_SECRET_ACCESS_KEY_HERE" -# 火山方舟 API 的基础 URL -base_url = "https://ark.cn-beijing.volces.com/api/v3" -# 默认图片生成模型 -default_model = "doubao-seedream-3-0-t2i-250415" -# 默认图片尺寸 -default_size = "1024x1024" -# 用于图片生成的API密钥 -# PicAction 当前配置为在HTTP请求体和Authorization头中使用此密钥。 -# 如果您的API认证方式不同,请相应调整或移除。 -volcano_generate_api_key = "YOUR_VOLCANO_GENERATE_API_KEY_HERE" - -# 是否默认开启水印 -default_watermark = true -# 默认引导强度 -default_guidance_scale = 2.5 -# 默认随机种子 -default_seed = 42 - -# 更多插件特定配置可以在此添加... -# custom_parameter = "some_value"