From 6e15fec8b42b3d4d8bd3a782b2a77670bfff21f9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 6 Jul 2025 10:36:29 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20=E8=87=AA=E5=8A=A8=E6=A0=BC?= =?UTF-8?q?=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 --- src/chat/focus_chat/heartFC_chat.py | 10 ++---- src/chat/focus_chat/memory_activator.py | 1 - src/chat/normal_chat/normal_chat.py | 15 +++++---- src/chat/planner_actions/action_modifier.py | 34 ++++++++++----------- src/chat/planner_actions/planner_focus.py | 4 +-- src/chat/replyer/default_generator.py | 21 ++++++++++--- src/config/official_configs.py | 4 +-- src/person_info/relationship_fetcher.py | 2 +- src/plugin_system/apis/generator_api.py | 4 +-- src/tools/tool_executor.py | 2 +- 10 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index a6d12b821..b6ac6f050 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -50,7 +50,6 @@ PROCESSOR_CLASSES = { logger = get_logger("hfc") # Logger Name Changed - class HeartFChatting: """ 管理一个连续的Focus Chat循环 @@ -100,9 +99,7 @@ class HeartFChatting: self._register_default_processors() self.action_manager = ActionManager() - self.action_planner = ActionPlanner( - log_prefix=self.log_prefix, action_manager=self.action_manager - ) + self.action_planner = ActionPlanner(log_prefix=self.log_prefix, action_manager=self.action_manager) self.action_modifier = ActionModifier(action_manager=self.action_manager, chat_id=self.stream_id) self.action_observation = ActionObservation(observe_id=self.stream_id) self.action_observation.set_action_manager(self.action_manager) @@ -360,7 +357,6 @@ class HeartFChatting: formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}秒" timer_strings.append(f"{name}: {formatted_time}") - logger.info( f"{self.log_prefix} 第{self._current_cycle_detail.cycle_id}次思考," f"耗时: {self._current_cycle_detail.end_time - self._current_cycle_detail.start_time:.1f}秒, " @@ -382,7 +378,7 @@ class HeartFChatting: self.performance_logger.record_cycle(cycle_performance_data) except Exception as perf_e: logger.warning(f"{self.log_prefix} 记录性能数据失败: {perf_e}") - + await asyncio.sleep(global_config.focus_chat.think_interval) except asyncio.CancelledError: @@ -494,7 +490,6 @@ class HeartFChatting: ) traceback.print_exc() - return all_plan_info async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> dict: @@ -528,7 +523,6 @@ class HeartFChatting: logger.error(f"{self.log_prefix} 动作修改失败: {e}") # 继续执行,不中断流程 - try: all_plan_info = await self._process_processors(self.observations) except Exception as e: diff --git a/src/chat/focus_chat/memory_activator.py b/src/chat/focus_chat/memory_activator.py index eb783d483..ab6e0c4a3 100644 --- a/src/chat/focus_chat/memory_activator.py +++ b/src/chat/focus_chat/memory_activator.py @@ -117,7 +117,6 @@ class MemoryActivator: # 添加新的关键词到缓存 self.cached_keywords.update(keywords) - # 调用记忆系统获取相关记忆 related_memory = await hippocampus_manager.get_memory_from_topic( diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index 6817670f0..89e5dd0c3 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -28,6 +28,7 @@ willing_manager = get_willing_manager() logger = get_logger("normal_chat") + class NormalChat: """ 普通聊天处理类,负责处理非核心对话的聊天逻辑。 @@ -61,7 +62,7 @@ class NormalChat: self.willing_amplifier = 1 self.start_time = time.time() - + self.mood_manager = mood_manager self.start_time = time.time() @@ -77,7 +78,6 @@ class NormalChat: self.recent_replies = [] self.max_replies_history = 20 # 最多保存最近20条回复记录 - # 添加回调函数,用于在满足条件时通知切换到focus_chat模式 self.on_switch_to_focus_callback = on_switch_to_focus_callback @@ -561,16 +561,14 @@ class NormalChat: async def reply_one_message(self, message: MessageRecv) -> None: # 回复前处理 await self.relationship_builder.build_relation() - + thinking_id = await self._create_thinking_message(message) # 如果启用planner,预先修改可用actions(避免在并行任务中重复调用) available_actions = None if self.enable_planner: try: - await self.action_modifier.modify_actions( - mode="normal", message_content=message.processed_plain_text - ) + await self.action_modifier.modify_actions(mode="normal", message_content=message.processed_plain_text) available_actions = self.action_manager.get_using_actions_for_mode("normal") except Exception as e: logger.warning(f"[{self.stream_name}] 获取available_actions失败: {e}") @@ -647,7 +645,7 @@ class NormalChat: logger.info(f"[{self.stream_name}] 回复内容中没有文本,不发送消息") await self._cleanup_thinking_message_by_id(thinking_id) return False - + # 发送回复 (不再需要传入 chat) first_bot_msg = await self._add_messages_to_manager(message, reply_texts, thinking_id) @@ -954,6 +952,7 @@ class NormalChat: except Exception as e: logger.warning(f"[{self.stream_name}] 获取疲劳调整系数时出错: {e}") return 1.0 # 出错时返回正常系数 + async def _check_should_switch_to_focus(self) -> bool: """ 检查是否满足切换到focus模式的条件 @@ -1027,4 +1026,4 @@ def get_recent_message_stats(minutes: int = 30, chat_id: str = None) -> dict: bot_filter["user_id"] = bot_id bot_reply_count = count_messages(bot_filter) - return {"bot_reply_count": bot_reply_count, "total_message_count": total_message_count} \ No newline at end of file + return {"bot_reply_count": bot_reply_count, "total_message_count": total_message_count} diff --git a/src/chat/planner_actions/action_modifier.py b/src/chat/planner_actions/action_modifier.py index c57842ae4..f75ce1235 100644 --- a/src/chat/planner_actions/action_modifier.py +++ b/src/chat/planner_actions/action_modifier.py @@ -2,7 +2,6 @@ from typing import List, Optional, Any, Dict from src.chat.heart_flow.observation.observation import Observation from src.common.logger import get_logger from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation -from src.chat.heart_flow.observation.chatting_observation import ChattingObservation from src.chat.message_receive.chat_stream import get_chat_manager from src.config.config import global_config from src.llm_models.utils_model import LLMRequest @@ -62,10 +61,10 @@ class ActionModifier: removals_s1 = [] removals_s2 = [] - + self.action_manager.restore_actions() all_actions = self.action_manager.get_using_actions_for_mode(mode) - + message_list_before_now_half = get_raw_msg_before_timestamp_with_chat( chat_id=self.chat_stream.stream_id, timestamp=time.time(), @@ -79,7 +78,7 @@ class ActionModifier: read_mark=0.0, show_actions=True, ) - + if message_content: chat_content = chat_content + "\n" + f"现在,最新的消息是:{message_content}" @@ -104,14 +103,13 @@ class ActionModifier: self.action_manager.remove_action_from_using(action_name) logger.debug(f"{self.log_prefix}阶段一移除动作: {action_name},原因: {reason}") - # === 第二阶段:激活类型判定 === if chat_content is not None: logger.debug(f"{self.log_prefix}开始激活类型判定阶段") # 获取当前使用的动作集(经过第一阶段处理) current_using_actions = self.action_manager.get_using_actions_for_mode(mode) - + # 获取因激活类型判定而需要移除的动作 removals_s2 = await self._get_deactivated_actions_by_type( current_using_actions, @@ -123,7 +121,7 @@ class ActionModifier: for action_name, reason in removals_s2: self.action_manager.remove_action_from_using(action_name) logger.debug(f"{self.log_prefix}阶段二移除动作: {action_name},原因: {reason}") - + # === 统一日志记录 === all_removals = removals_s1 + removals_s2 if all_removals: @@ -141,11 +139,9 @@ class ActionModifier: associated_types_str = ", ".join(data["associated_types"]) reason = f"适配器不支持(需要: {associated_types_str})" type_mismatched_actions.append((action_name, reason)) - logger.debug( - f"{self.log_prefix}决定移除动作: {action_name},原因: {reason}" - ) + logger.debug(f"{self.log_prefix}决定移除动作: {action_name},原因: {reason}") return type_mismatched_actions - + async def _get_deactivated_actions_by_type( self, actions_with_info: Dict[str, Any], @@ -166,7 +162,7 @@ class ActionModifier: # 分类处理不同激活类型的actions llm_judge_actions = {} - + actions_to_check = list(actions_with_info.items()) random.shuffle(actions_to_check) @@ -193,7 +189,7 @@ class ActionModifier: elif activation_type == "llm_judge": llm_judge_actions[action_name] = action_info - + else: logger.warning(f"{self.log_prefix}未知的激活类型: {activation_type},跳过处理") @@ -517,21 +513,23 @@ class ActionModifier: # 如果最近sec_thres_reply_num次都是reply,40%概率移除 removal_probability = 0.4 / global_config.focus_chat.consecutive_replies if random.random() < removal_probability: - reason = f"连续回复较多(最近{sec_thres_reply_num}次全是reply,{removal_probability:.2f}概率移除,触发移除)" + reason = ( + f"连续回复较多(最近{sec_thres_reply_num}次全是reply,{removal_probability:.2f}概率移除,触发移除)" + ) removals.append(("reply", reason)) elif len(last_max_reply_num) >= one_thres_reply_num and all(last_max_reply_num[-one_thres_reply_num:]): # 如果最近one_thres_reply_num次都是reply,20%概率移除 removal_probability = 0.2 / global_config.focus_chat.consecutive_replies if random.random() < removal_probability: - reason = f"连续回复检测(最近{one_thres_reply_num}次全是reply,{removal_probability:.2f}概率移除,触发移除)" + reason = ( + f"连续回复检测(最近{one_thres_reply_num}次全是reply,{removal_probability:.2f}概率移除,触发移除)" + ) removals.append(("reply", reason)) else: logger.debug(f"{self.log_prefix}连续回复检测:无需移除reply动作,最近回复模式正常") return removals - - def get_available_actions_count(self) -> int: """获取当前可用动作数量(排除默认的no_action)""" current_actions = self.action_manager.get_using_actions_for_mode("normal") @@ -545,4 +543,4 @@ class ActionModifier: if available_count == 0: logger.debug(f"{self.log_prefix} 没有可用动作,跳过规划") return True - return False \ No newline at end of file + return False diff --git a/src/chat/planner_actions/planner_focus.py b/src/chat/planner_actions/planner_focus.py index bb3bdcacd..5a093ce93 100644 --- a/src/chat/planner_actions/planner_focus.py +++ b/src/chat/planner_actions/planner_focus.py @@ -83,9 +83,7 @@ class ActionPlanner: request_type="focus.planner", # 用于动作规划 ) - async def plan( - self, all_plan_info: List[InfoBase],loop_start_time: float - ) -> Dict[str, Any]: + async def plan(self, all_plan_info: List[InfoBase], loop_start_time: float) -> Dict[str, Any]: """ 规划器 (Planner): 使用LLM根据上下文决定做出什么动作。 diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index dd1b4e8a6..c5b9080ef 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -98,7 +98,6 @@ class DefaultReplyer: self.log_prefix = "replyer" self.request_type = request_type - if model_configs: self.express_model_configs = model_configs else: @@ -470,7 +469,13 @@ class DefaultReplyer: duration = end_time - start_time return name, result, duration - async def build_prompt_reply_context(self, reply_data=None, available_actions: List[str] = None, enable_timeout: bool = False, enable_tool: bool = True) -> str: + async def build_prompt_reply_context( + self, + reply_data=None, + available_actions: List[str] = None, + enable_timeout: bool = False, + enable_tool: bool = True, + ) -> str: """ 构建回复器上下文 @@ -537,10 +542,16 @@ class DefaultReplyer: # 并行执行四个构建任务 task_results = await asyncio.gather( - self._time_and_run_task(self.build_expression_habits(chat_talking_prompt_half, target), "build_expression_habits"), - self._time_and_run_task(self.build_relation_info(reply_data, chat_talking_prompt_half), "build_relation_info"), + self._time_and_run_task( + self.build_expression_habits(chat_talking_prompt_half, target), "build_expression_habits" + ), + self._time_and_run_task( + self.build_relation_info(reply_data, chat_talking_prompt_half), "build_relation_info" + ), self._time_and_run_task(self.build_memory_block(chat_talking_prompt_half, target), "build_memory_block"), - self._time_and_run_task(self.build_tool_info(reply_data, chat_talking_prompt_half, enable_tool=enable_tool), "build_tool_info"), + self._time_and_run_task( + self.build_tool_info(reply_data, chat_talking_prompt_half, enable_tool=enable_tool), "build_tool_info" + ), ) # 处理结果 diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 1c28ab7c8..290a73f1e 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -273,7 +273,6 @@ class MessageReceiveConfig(ConfigBase): class NormalChatConfig(ConfigBase): """普通聊天配置类""" - willing_mode: str = "classical" """意愿模式""" @@ -290,7 +289,6 @@ class NormalChatConfig(ConfigBase): """是否启用动作规划器""" - @dataclass class FocusChatConfig(ConfigBase): """专注聊天配置类""" @@ -348,7 +346,7 @@ class ToolConfig(ConfigBase): @dataclass class EmojiConfig(ConfigBase): """表情包配置类""" - + emoji_chance: float = 0.6 """发送表情包的基础概率""" diff --git a/src/person_info/relationship_fetcher.py b/src/person_info/relationship_fetcher.py index e2bde69de..f1c62851a 100644 --- a/src/person_info/relationship_fetcher.py +++ b/src/person_info/relationship_fetcher.py @@ -106,7 +106,7 @@ class RelationshipFetcher: await self._extract_single_info(person_id, info_type, person_name) relation_info = self._organize_known_info() - if short_impression and relation_info: + if short_impression and relation_info: relation_info = f"你对{person_name}的印象是:{short_impression}。具体来说:{relation_info}" elif short_impression: relation_info = f"你对{person_name}的印象是:{short_impression}" diff --git a/src/plugin_system/apis/generator_api.py b/src/plugin_system/apis/generator_api.py index ead002064..d4ed0f51b 100644 --- a/src/plugin_system/apis/generator_api.py +++ b/src/plugin_system/apis/generator_api.py @@ -92,9 +92,7 @@ async def generate_reply( """ try: # 获取回复器 - replyer = get_replyer( - chat_stream, chat_id, model_configs=model_configs, request_type=request_type - ) + replyer = get_replyer(chat_stream, chat_id, model_configs=model_configs, request_type=request_type) if not replyer: logger.error("[GeneratorAPI] 无法获取回复器") return False, [] diff --git a/src/tools/tool_executor.py b/src/tools/tool_executor.py index b43dfcff3..b7b0d8f69 100644 --- a/src/tools/tool_executor.py +++ b/src/tools/tool_executor.py @@ -45,7 +45,7 @@ class ToolExecutor: self.chat_id = chat_id self.chat_stream = get_chat_manager().get_stream(self.chat_id) self.log_prefix = f"[{get_chat_manager().get_stream_name(self.chat_id) or self.chat_id}]" - + self.llm_model = LLMRequest( model=global_config.model.tool_use, request_type="tool_executor",