287 lines
10 KiB
Python
287 lines
10 KiB
Python
from typing import Dict, List, Optional, Type
|
||
from src.plugin_system.base.base_action import BaseAction
|
||
from src.chat.message_receive.chat_stream import ChatStream
|
||
from src.common.logger import get_logger
|
||
from src.plugin_system.core.component_registry import component_registry
|
||
from src.plugin_system.base.component_types import ComponentType, ActionActivationType, ChatMode, ActionInfo
|
||
|
||
logger = get_logger("action_manager")
|
||
|
||
|
||
class ActionManager:
|
||
"""
|
||
动作管理器,用于管理各种类型的动作
|
||
|
||
现在统一使用新插件系统,简化了原有的新旧兼容逻辑。
|
||
"""
|
||
|
||
# 类常量
|
||
DEFAULT_RANDOM_PROBABILITY = 0.3
|
||
DEFAULT_MODE = ChatMode.ALL
|
||
DEFAULT_ACTIVATION_TYPE = ActionActivationType.ALWAYS
|
||
|
||
def __init__(self):
|
||
"""初始化动作管理器"""
|
||
# 所有注册的动作集合
|
||
self._registered_actions: Dict[str, ActionInfo] = {}
|
||
# 当前正在使用的动作集合,默认加载默认动作
|
||
self._using_actions: Dict[str, ActionInfo] = {}
|
||
|
||
# 加载插件动作
|
||
self._load_plugin_actions()
|
||
|
||
# 初始化时将默认动作加载到使用中的动作
|
||
self._using_actions = component_registry.get_default_actions()
|
||
|
||
def _load_plugin_actions(self) -> None:
|
||
"""
|
||
加载所有插件系统中的动作
|
||
"""
|
||
try:
|
||
# 从新插件系统获取Action组件
|
||
self._load_plugin_system_actions()
|
||
logger.debug("从插件系统加载Action组件成功")
|
||
|
||
except Exception as e:
|
||
logger.error(f"加载插件动作失败: {e}")
|
||
|
||
def _load_plugin_system_actions(self) -> None:
|
||
"""从插件系统的component_registry加载Action组件"""
|
||
try:
|
||
# 获取所有Action组件
|
||
action_components: Dict[str, ActionInfo] = component_registry.get_components_by_type(ComponentType.ACTION) # type: ignore
|
||
|
||
for action_name, action_info in action_components.items():
|
||
if action_name in self._registered_actions:
|
||
logger.debug(f"Action组件 {action_name} 已存在,跳过")
|
||
continue
|
||
|
||
self._registered_actions[action_name] = action_info
|
||
|
||
logger.debug(
|
||
f"从插件系统加载Action组件: {action_name} (插件: {getattr(action_info, 'plugin_name', 'unknown')})"
|
||
)
|
||
|
||
logger.info(f"加载了 {len(action_components)} 个Action动作")
|
||
|
||
except Exception as e:
|
||
logger.error(f"从插件系统加载Action组件失败: {e}")
|
||
import traceback
|
||
|
||
logger.error(traceback.format_exc())
|
||
|
||
def create_action(
|
||
self,
|
||
action_name: str,
|
||
action_data: dict,
|
||
reasoning: str,
|
||
cycle_timers: dict,
|
||
thinking_id: str,
|
||
chat_stream: ChatStream,
|
||
log_prefix: str,
|
||
shutting_down: bool = False,
|
||
) -> Optional[BaseAction]:
|
||
"""
|
||
创建动作处理器实例
|
||
|
||
Args:
|
||
action_name: 动作名称
|
||
action_data: 动作数据
|
||
reasoning: 执行理由
|
||
cycle_timers: 计时器字典
|
||
thinking_id: 思考ID
|
||
chat_stream: 聊天流
|
||
log_prefix: 日志前缀
|
||
shutting_down: 是否正在关闭
|
||
|
||
Returns:
|
||
Optional[BaseAction]: 创建的动作处理器实例,如果动作名称未注册则返回None
|
||
"""
|
||
try:
|
||
# 获取组件类 - 明确指定查询Action类型
|
||
component_class: Type[BaseAction] = component_registry.get_component_class(
|
||
action_name, ComponentType.ACTION
|
||
) # type: ignore
|
||
if not component_class:
|
||
logger.warning(f"{log_prefix} 未找到Action组件: {action_name}")
|
||
return None
|
||
|
||
# 获取组件信息
|
||
component_info = component_registry.get_component_info(action_name, ComponentType.ACTION)
|
||
if not component_info:
|
||
logger.warning(f"{log_prefix} 未找到Action组件信息: {action_name}")
|
||
return None
|
||
|
||
# 获取插件配置
|
||
plugin_config = component_registry.get_plugin_config(component_info.plugin_name)
|
||
|
||
# 创建动作实例
|
||
instance = component_class(
|
||
action_data=action_data,
|
||
reasoning=reasoning,
|
||
cycle_timers=cycle_timers,
|
||
thinking_id=thinking_id,
|
||
chat_stream=chat_stream,
|
||
log_prefix=log_prefix,
|
||
shutting_down=shutting_down,
|
||
plugin_config=plugin_config,
|
||
)
|
||
|
||
logger.debug(f"创建Action实例成功: {action_name}")
|
||
return instance
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建Action实例失败 {action_name}: {e}")
|
||
import traceback
|
||
|
||
logger.error(traceback.format_exc())
|
||
return None
|
||
|
||
def get_registered_actions(self) -> Dict[str, ActionInfo]:
|
||
"""获取所有已注册的动作集"""
|
||
return self._registered_actions.copy()
|
||
|
||
def get_using_actions(self) -> Dict[str, ActionInfo]:
|
||
"""获取当前正在使用的动作集合"""
|
||
return self._using_actions.copy()
|
||
|
||
def get_using_actions_for_mode(self, mode: ChatMode) -> Dict[str, ActionInfo]:
|
||
"""
|
||
根据聊天模式获取可用的动作集合
|
||
|
||
Args:
|
||
mode: 聊天模式 (ChatMode.FOCUS, ChatMode.NORMAL, ChatMode.ALL)
|
||
|
||
Returns:
|
||
Dict[str, ActionInfo]: 在指定模式下可用的动作集合
|
||
"""
|
||
enabled_actions = {}
|
||
|
||
for action_name, action_info in self._using_actions.items():
|
||
action_mode = action_info.mode_enable
|
||
|
||
# 检查动作是否在当前模式下启用
|
||
if action_mode in [ChatMode.ALL, mode]:
|
||
enabled_actions[action_name] = action_info
|
||
logger.debug(f"动作 {action_name} 在模式 {mode} 下可用 (mode_enable: {action_mode})")
|
||
|
||
logger.debug(f"模式 {mode} 下可用动作: {list(enabled_actions.keys())}")
|
||
return enabled_actions
|
||
|
||
def add_action_to_using(self, action_name: str) -> bool:
|
||
"""
|
||
添加已注册的动作到当前使用的动作集
|
||
|
||
Args:
|
||
action_name: 动作名称
|
||
|
||
Returns:
|
||
bool: 添加是否成功
|
||
"""
|
||
if action_name not in self._registered_actions:
|
||
logger.warning(f"添加失败: 动作 {action_name} 未注册")
|
||
return False
|
||
|
||
if action_name in self._using_actions:
|
||
logger.info(f"动作 {action_name} 已经在使用中")
|
||
return True
|
||
|
||
self._using_actions[action_name] = self._registered_actions[action_name]
|
||
logger.info(f"添加动作 {action_name} 到使用集")
|
||
return True
|
||
|
||
def remove_action_from_using(self, action_name: str) -> bool:
|
||
"""
|
||
从当前使用的动作集中移除指定动作
|
||
|
||
Args:
|
||
action_name: 动作名称
|
||
|
||
Returns:
|
||
bool: 移除是否成功
|
||
"""
|
||
if action_name not in self._using_actions:
|
||
logger.warning(f"移除失败: 动作 {action_name} 不在当前使用的动作集中")
|
||
return False
|
||
|
||
del self._using_actions[action_name]
|
||
logger.debug(f"已从使用集中移除动作 {action_name}")
|
||
return True
|
||
|
||
# def add_action(self, action_name: str, description: str, parameters: Dict = None, require: List = None) -> bool:
|
||
# """
|
||
# 添加新的动作到注册集
|
||
|
||
# Args:
|
||
# action_name: 动作名称
|
||
# description: 动作描述
|
||
# parameters: 动作参数定义,默认为空字典
|
||
# require: 动作依赖项,默认为空列表
|
||
|
||
# Returns:
|
||
# bool: 添加是否成功
|
||
# """
|
||
# if action_name in self._registered_actions:
|
||
# return False
|
||
|
||
# if parameters is None:
|
||
# parameters = {}
|
||
# if require is None:
|
||
# require = []
|
||
|
||
# action_info = {"description": description, "parameters": parameters, "require": require}
|
||
|
||
# self._registered_actions[action_name] = action_info
|
||
# return True
|
||
|
||
def remove_action(self, action_name: str) -> bool:
|
||
"""从注册集移除指定动作"""
|
||
if action_name not in self._registered_actions:
|
||
return False
|
||
del self._registered_actions[action_name]
|
||
# 如果在使用集中也存在,一并移除
|
||
if action_name in self._using_actions:
|
||
del self._using_actions[action_name]
|
||
return True
|
||
|
||
def temporarily_remove_actions(self, actions_to_remove: List[str]) -> None:
|
||
"""临时移除使用集中的指定动作"""
|
||
for name in actions_to_remove:
|
||
self._using_actions.pop(name, None)
|
||
|
||
def restore_actions(self) -> None:
|
||
"""恢复到默认动作集"""
|
||
actions_to_restore = list(self._using_actions.keys())
|
||
self._using_actions = component_registry.get_default_actions()
|
||
logger.debug(f"恢复动作集: 从 {actions_to_restore} 恢复到默认动作集 {list(self._using_actions.keys())}")
|
||
|
||
def add_system_action_if_needed(self, action_name: str) -> bool:
|
||
"""
|
||
根据需要添加系统动作到使用集
|
||
|
||
Args:
|
||
action_name: 动作名称
|
||
|
||
Returns:
|
||
bool: 是否成功添加
|
||
"""
|
||
if action_name in self._registered_actions and action_name not in self._using_actions:
|
||
self._using_actions[action_name] = self._registered_actions[action_name]
|
||
logger.info(f"临时添加系统动作到使用集: {action_name}")
|
||
return True
|
||
return False
|
||
|
||
def get_action(self, action_name: str) -> Optional[Type[BaseAction]]:
|
||
"""
|
||
获取指定动作的处理器类
|
||
|
||
Args:
|
||
action_name: 动作名称
|
||
|
||
Returns:
|
||
Optional[Type[BaseAction]]: 动作处理器类,如果不存在则返回None
|
||
"""
|
||
from src.plugin_system.core.component_registry import component_registry
|
||
|
||
return component_registry.get_component_class(action_name) # type: ignore
|