mirror of https://github.com/Mai-with-u/MaiBot.git
120 lines
4.3 KiB
Python
120 lines
4.3 KiB
Python
from abc import ABC, abstractmethod
|
||
from typing import Tuple, Dict, Any, Optional
|
||
from src.common.logger_manager import get_logger
|
||
from src.plugin_system.apis.plugin_api import PluginAPI
|
||
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType
|
||
|
||
logger = get_logger("base_action")
|
||
|
||
class BaseAction(ABC):
|
||
"""Action组件基类
|
||
|
||
Action是插件的一种组件类型,用于处理聊天中的动作逻辑
|
||
|
||
子类可以通过类属性定义激活条件:
|
||
- focus_activation_type: 专注模式激活类型
|
||
- normal_activation_type: 普通模式激活类型
|
||
- activation_keywords: 激活关键词列表
|
||
- keyword_case_sensitive: 关键词是否区分大小写
|
||
- mode_enable: 启用的聊天模式
|
||
- parallel_action: 是否允许并行执行
|
||
- random_activation_probability: 随机激活概率
|
||
- llm_judge_prompt: LLM判断提示词
|
||
"""
|
||
|
||
# 默认激活设置(子类可以覆盖)
|
||
focus_activation_type: ActionActivationType = ActionActivationType.NEVER
|
||
normal_activation_type: ActionActivationType = ActionActivationType.NEVER
|
||
activation_keywords: list = []
|
||
keyword_case_sensitive: bool = False
|
||
mode_enable: ChatMode = ChatMode.ALL
|
||
parallel_action: bool = True
|
||
random_activation_probability: float = 0.0
|
||
llm_judge_prompt: str = ""
|
||
|
||
def __init__(self,
|
||
action_data: dict,
|
||
reasoning: str,
|
||
cycle_timers: dict,
|
||
thinking_id: str,
|
||
**kwargs):
|
||
"""初始化Action组件
|
||
|
||
Args:
|
||
action_data: 动作数据
|
||
reasoning: 执行该动作的理由
|
||
cycle_timers: 计时器字典
|
||
thinking_id: 思考ID
|
||
**kwargs: 其他参数(包含服务对象)
|
||
"""
|
||
self.action_data = action_data
|
||
self.reasoning = reasoning
|
||
self.cycle_timers = cycle_timers
|
||
self.thinking_id = thinking_id
|
||
|
||
# 创建API实例
|
||
self.api = PluginAPI(
|
||
chat_stream=kwargs.get("chat_stream"),
|
||
expressor=kwargs.get("expressor"),
|
||
replyer=kwargs.get("replyer"),
|
||
observations=kwargs.get("observations"),
|
||
log_prefix=kwargs.get("log_prefix", "")
|
||
)
|
||
|
||
self.log_prefix = kwargs.get("log_prefix", "")
|
||
|
||
logger.debug(f"{self.log_prefix} Action组件初始化完成")
|
||
|
||
async def send_reply(self, content: str) -> bool:
|
||
"""发送回复消息
|
||
|
||
Args:
|
||
content: 回复内容
|
||
|
||
Returns:
|
||
bool: 是否发送成功
|
||
"""
|
||
return await self.api.send_message("text", content)
|
||
|
||
@classmethod
|
||
def get_action_info(cls, name: str = None, description: str = None) -> 'ActionInfo':
|
||
"""从类属性生成ActionInfo
|
||
|
||
Args:
|
||
name: Action名称,如果不提供则使用类名
|
||
description: Action描述,如果不提供则使用类文档字符串
|
||
|
||
Returns:
|
||
ActionInfo: 生成的Action信息对象
|
||
"""
|
||
|
||
|
||
# 自动生成名称和描述
|
||
if name is None:
|
||
name = cls.__name__.lower().replace('action', '')
|
||
if description is None:
|
||
description = cls.__doc__ or f"{cls.__name__} Action组件"
|
||
description = description.strip().split('\n')[0] # 取第一行作为描述
|
||
|
||
return ActionInfo(
|
||
name=name,
|
||
component_type=ComponentType.ACTION,
|
||
description=description,
|
||
focus_activation_type=cls.focus_activation_type,
|
||
normal_activation_type=cls.normal_activation_type,
|
||
activation_keywords=cls.activation_keywords.copy() if cls.activation_keywords else [],
|
||
keyword_case_sensitive=cls.keyword_case_sensitive,
|
||
mode_enable=cls.mode_enable,
|
||
parallel_action=cls.parallel_action,
|
||
random_activation_probability=cls.random_activation_probability,
|
||
llm_judge_prompt=cls.llm_judge_prompt
|
||
)
|
||
|
||
@abstractmethod
|
||
async def execute(self) -> Tuple[bool, str]:
|
||
"""执行Action的抽象方法,子类必须实现
|
||
|
||
Returns:
|
||
Tuple[bool, str]: (是否执行成功, 回复文本)
|
||
"""
|
||
pass |