From 49f2e91abbe8c305246e4fcf103d938f5ac0a5b4 Mon Sep 17 00:00:00 2001 From: SengokuCola <1026294844@qq.com> Date: Thu, 12 Jun 2025 22:08:01 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E5=AF=BC=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- .../focus_chat/planners/action_manager.py | 22 ++- src/plugin_system/apis/hearflow_api.py | 166 +++++++++++------- 3 files changed, 119 insertions(+), 71 deletions(-) diff --git a/.gitignore b/.gitignore index 8b8757a91..700806770 100644 --- a/.gitignore +++ b/.gitignore @@ -310,4 +310,4 @@ src/plugins/test_plugin_pic/actions/pic_action_config.toml run_pet.bat # 忽略 /src/plugins 但保留特定目录 -/plugins/* +plugins/* diff --git a/src/chat/focus_chat/planners/action_manager.py b/src/chat/focus_chat/planners/action_manager.py index b1de7627d..f60df9652 100644 --- a/src/chat/focus_chat/planners/action_manager.py +++ b/src/chat/focus_chat/planners/action_manager.py @@ -1,5 +1,5 @@ from typing import Dict, List, Optional, Type, Any -from src.plugin_system.base.base_action import BaseAction, _ACTION_REGISTRY +from src.plugin_system.base.base_action import BaseAction from src.chat.heart_flow.observation.observation import Observation from src.chat.focus_chat.replyer.default_replyer import DefaultReplyer from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor @@ -121,8 +121,12 @@ class ActionManager: 加载所有通过装饰器注册的动作 """ try: - # 从_ACTION_REGISTRY获取所有已注册动作 - for action_name, action_class in _ACTION_REGISTRY.items(): + # 从组件注册中心获取所有已注册的action + from src.plugin_system.core.component_registry import component_registry + action_registry = component_registry.get_action_registry() + + # 从action_registry获取所有已注册动作 + for action_name, action_class in action_registry.items(): # 获取动作相关信息 # 不读取插件动作和基类 @@ -186,11 +190,11 @@ class ActionManager: """ 加载所有插件目录中的动作 - 注意:插件动作的实际导入已经在main.py中完成,这里只需要从_ACTION_REGISTRY获取 + 注意:插件动作的实际导入已经在main.py中完成,这里只需要从action_registry获取 同时也从新插件系统的component_registry获取Action组件 """ try: - # 从旧的_ACTION_REGISTRY获取插件动作 + # 从旧的action_registry获取插件动作 self._load_registered_actions() logger.debug("从旧注册表加载插件动作成功") @@ -311,7 +315,9 @@ class ActionManager: ) # 旧系统的动作创建逻辑 - handler_class = _ACTION_REGISTRY.get(action_name) + from src.plugin_system.core.component_registry import component_registry + action_registry = component_registry.get_action_registry() + handler_class = action_registry.get(action_name) if not handler_class: logger.warning(f"未注册的动作类型: {action_name}") return None @@ -575,4 +581,6 @@ class ActionManager: Returns: Optional[Type[BaseAction]]: 动作处理器类,如果不存在则返回None """ - return _ACTION_REGISTRY.get(action_name) + from src.plugin_system.core.component_registry import component_registry + action_registry = component_registry.get_action_registry() + return action_registry.get(action_name) diff --git a/src/plugin_system/apis/hearflow_api.py b/src/plugin_system/apis/hearflow_api.py index 54a3c3689..35ca75536 100644 --- a/src/plugin_system/apis/hearflow_api.py +++ b/src/plugin_system/apis/hearflow_api.py @@ -1,18 +1,31 @@ -from typing import Optional, List, Any +from typing import Optional, List, Any, Tuple from src.common.logger import get_logger -from src.chat.heart_flow.heartflow import heartflow -from src.chat.heart_flow.sub_heartflow import SubHeartflow, ChatState logger = get_logger("hearflow_api") +def _get_heartflow(): + """获取heartflow实例的延迟导入函数""" + from src.chat.heart_flow.heartflow import heartflow + return heartflow + + +def _get_subheartflow_types(): + """获取SubHeartflow和ChatState类型的延迟导入函数""" + from src.chat.heart_flow.sub_heartflow import SubHeartflow, ChatState + return SubHeartflow, ChatState + + class HearflowAPI: """心流API模块 提供与心流和子心流相关的操作接口 """ - async def get_sub_hearflow_by_chat_id(self, chat_id: str) -> Optional[SubHeartflow]: + def __init__(self): + self.log_prefix = "[HearflowAPI]" + + async def get_sub_hearflow_by_chat_id(self, chat_id: str) -> Optional[Any]: """根据chat_id获取指定的sub_hearflow实例 Args: @@ -21,20 +34,31 @@ class HearflowAPI: Returns: Optional[SubHeartflow]: sub_hearflow实例,如果不存在则返回None """ - try: - # 直接从subheartflow_manager获取已存在的子心流 - # 使用锁来确保线程安全 - async with heartflow.subheartflow_manager._lock: - subflow = heartflow.subheartflow_manager.subheartflows.get(chat_id) - if subflow and not subflow.should_stop: - logger.debug(f"{self.log_prefix} 成功获取子心流实例: {chat_id}") - return subflow - else: - logger.debug(f"{self.log_prefix} 子心流不存在或已停止: {chat_id}") - return None - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流实例时出错: {e}") - return None + # 使用延迟导入 + heartflow = _get_heartflow() + + # 直接从subheartflow_manager获取已存在的子心流 + # 使用锁来确保线程安全 + async with heartflow.subheartflow_manager._lock: + subflow = heartflow.subheartflow_manager.subheartflows.get(chat_id) + if subflow and not subflow.should_stop: + logger.debug(f"{self.log_prefix} 成功获取子心流实例: {chat_id}") + return subflow + else: + logger.debug(f"{self.log_prefix} 子心流不存在或已停止: {chat_id}") + return None + + async def get_or_create_sub_hearflow_by_chat_id(self, chat_id: str) -> Optional[Any]: + """根据chat_id获取或创建sub_hearflow实例 + + Args: + chat_id: 聊天ID + + Returns: + Optional[SubHeartflow]: sub_hearflow实例,创建失败时返回None + """ + heartflow = _get_heartflow() + return await heartflow.get_or_create_subheartflow(chat_id) def get_all_sub_hearflow_ids(self) -> List[str]: """获取所有子心流的ID列表 @@ -42,31 +66,25 @@ class HearflowAPI: Returns: List[str]: 所有子心流的ID列表 """ - try: - all_subflows = heartflow.subheartflow_manager.get_all_subheartflows() - chat_ids = [subflow.chat_id for subflow in all_subflows if not subflow.should_stop] - logger.debug(f"{self.log_prefix} 获取到 {len(chat_ids)} 个活跃的子心流ID") - return chat_ids - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流ID列表时出错: {e}") - return [] + heartflow = _get_heartflow() + all_subflows = heartflow.subheartflow_manager.get_all_subheartflows() + chat_ids = [subflow.chat_id for subflow in all_subflows if not subflow.should_stop] + logger.debug(f"{self.log_prefix} 获取到 {len(chat_ids)} 个活跃的子心流ID") + return chat_ids - def get_all_sub_hearflows(self) -> List[SubHeartflow]: + def get_all_sub_hearflows(self) -> List[Any]: """获取所有子心流实例 Returns: List[SubHeartflow]: 所有活跃的子心流实例列表 """ - try: - all_subflows = heartflow.subheartflow_manager.get_all_subheartflows() - active_subflows = [subflow for subflow in all_subflows if not subflow.should_stop] - logger.debug(f"{self.log_prefix} 获取到 {len(active_subflows)} 个活跃的子心流实例") - return active_subflows - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流实例列表时出错: {e}") - return [] + heartflow = _get_heartflow() + all_subflows = heartflow.subheartflow_manager.get_all_subheartflows() + active_subflows = [subflow for subflow in all_subflows if not subflow.should_stop] + logger.debug(f"{self.log_prefix} 获取到 {len(active_subflows)} 个活跃的子心流实例") + return active_subflows - async def get_sub_hearflow_chat_state(self, chat_id: str) -> Optional[ChatState]: + async def get_sub_hearflow_chat_state(self, chat_id: str) -> Optional[Any]: """获取指定子心流的聊天状态 Args: @@ -75,30 +93,60 @@ class HearflowAPI: Returns: Optional[ChatState]: 聊天状态,如果子心流不存在则返回None """ - try: - subflow = await self.get_sub_hearflow_by_chat_id(chat_id) - if subflow: - return subflow.chat_state.chat_status - return None - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流聊天状态时出错: {e}") - return None + subflow = await self.get_sub_hearflow_by_chat_id(chat_id) + if subflow: + return subflow.chat_state.chat_status + return None - async def set_sub_hearflow_chat_state(self, chat_id: str, target_state: ChatState) -> bool: + async def set_sub_hearflow_chat_state(self, chat_id: str, target_state: Any) -> bool: """设置指定子心流的聊天状态 Args: chat_id: 聊天ID - target_state: 目标状态 + target_state: 目标状态(ChatState枚举值) Returns: bool: 是否设置成功 """ - try: - return await heartflow.subheartflow_manager.force_change_state(chat_id, target_state) - except Exception as e: - logger.error(f"{self.log_prefix} 设置子心流聊天状态时出错: {e}") - return False + heartflow = _get_heartflow() + return await heartflow.subheartflow_manager.force_change_state(chat_id, target_state) + + async def get_sub_hearflow_replyer_and_expressor(self, chat_id: str) -> Tuple[Optional[Any], Optional[Any]]: + """根据chat_id获取指定子心流的replyer和expressor实例 + + Args: + chat_id: 聊天ID + + Returns: + Tuple[Optional[Any], Optional[Any]]: (replyer实例, expressor实例),如果子心流不存在或未处于FOCUSED状态,返回(None, None) + """ + subflow = await self.get_sub_hearflow_by_chat_id(chat_id) + if not subflow: + logger.debug(f"{self.log_prefix} 子心流不存在: {chat_id}") + return None, None + + # 使用延迟导入获取ChatState + _, ChatState = _get_subheartflow_types() + + # 检查子心流是否处于FOCUSED状态且有HeartFC实例 + if subflow.chat_state.chat_status != ChatState.FOCUSED: + logger.debug(f"{self.log_prefix} 子心流 {chat_id} 未处于FOCUSED状态,当前状态: {subflow.chat_state.chat_status.value}") + return None, None + + if not subflow.heart_fc_instance: + logger.debug(f"{self.log_prefix} 子心流 {chat_id} 没有HeartFC实例") + return None, None + + # 返回replyer和expressor实例 + replyer = subflow.heart_fc_instance.replyer + expressor = subflow.heart_fc_instance.expressor + + if replyer and expressor: + logger.debug(f"{self.log_prefix} 成功获取子心流 {chat_id} 的replyer和expressor") + else: + logger.warning(f"{self.log_prefix} 子心流 {chat_id} 的replyer或expressor为空") + + return replyer, expressor async def get_sub_hearflow_replyer(self, chat_id: str) -> Optional[Any]: """根据chat_id获取指定子心流的replyer实例 @@ -109,12 +157,8 @@ class HearflowAPI: Returns: Optional[Any]: replyer实例,如果不存在则返回None """ - try: - replyer, _ = await self.get_sub_hearflow_replyer_and_expressor(chat_id) - return replyer - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流replyer时出错: {e}") - return None + replyer, _ = await self.get_sub_hearflow_replyer_and_expressor(chat_id) + return replyer async def get_sub_hearflow_expressor(self, chat_id: str) -> Optional[Any]: """根据chat_id获取指定子心流的expressor实例 @@ -125,9 +169,5 @@ class HearflowAPI: Returns: Optional[Any]: expressor实例,如果不存在则返回None """ - try: - _, expressor = await self.get_sub_hearflow_replyer_and_expressor(chat_id) - return expressor - except Exception as e: - logger.error(f"{self.log_prefix} 获取子心流expressor时出错: {e}") - return None + _, expressor = await self.get_sub_hearflow_replyer_and_expressor(chat_id) + return expressor