re-style: 格式化代码
This commit is contained in:
@@ -4,31 +4,31 @@
|
||||
提供插件开发的基础类和类型定义
|
||||
"""
|
||||
|
||||
from .base_plugin import BasePlugin
|
||||
from .base_action import BaseAction
|
||||
from .base_tool import BaseTool
|
||||
from .base_command import BaseCommand
|
||||
from .base_events_handler import BaseEventHandler
|
||||
from .base_plugin import BasePlugin
|
||||
from .base_tool import BaseTool
|
||||
from .command_args import CommandArgs
|
||||
from .component_types import (
|
||||
ComponentType,
|
||||
ActionActivationType,
|
||||
ActionInfo,
|
||||
ChatMode,
|
||||
ChatType,
|
||||
ComponentInfo,
|
||||
ActionInfo,
|
||||
CommandInfo,
|
||||
PlusCommandInfo,
|
||||
ToolInfo,
|
||||
PluginInfo,
|
||||
PythonDependency,
|
||||
ComponentInfo,
|
||||
ComponentType,
|
||||
EventHandlerInfo,
|
||||
EventType,
|
||||
MaiMessages,
|
||||
PluginInfo,
|
||||
PlusCommandInfo,
|
||||
PythonDependency,
|
||||
ToolInfo,
|
||||
ToolParamType,
|
||||
)
|
||||
from .config_types import ConfigField
|
||||
from .plus_command import PlusCommand, PlusCommandAdapter, create_plus_command_adapter
|
||||
from .command_args import CommandArgs
|
||||
|
||||
__all__ = [
|
||||
"BasePlugin",
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
import time
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Tuple, Optional, List, Dict
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.chat.message_receive.chat_stream import ChatStream
|
||||
from src.plugin_system.base.component_types import ActionActivationType, ChatMode, ActionInfo, ComponentType, ChatType
|
||||
from src.plugin_system.apis import send_api, database_api, message_api
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.apis import database_api, message_api, send_api
|
||||
from src.plugin_system.base.component_types import ActionActivationType, ActionInfo, ChatMode, ChatType, ComponentType
|
||||
|
||||
logger = get_logger("base_action")
|
||||
|
||||
@@ -39,7 +36,7 @@ class BaseAction(ABC):
|
||||
"""是否为二步Action。如果为True,Action将分两步执行:第一步选择操作,第二步执行具体操作"""
|
||||
step_one_description: str = ""
|
||||
"""第一步的描述,用于向LLM展示Action的基本功能"""
|
||||
sub_actions: List[Tuple[str, str, Dict[str, str]]] = []
|
||||
sub_actions: list[tuple[str, str, dict[str, str]]] = []
|
||||
"""子Action列表,格式为[(子Action名, 子Action描述, 子Action参数)]。仅在二步Action中使用"""
|
||||
|
||||
def __init__(
|
||||
@@ -50,8 +47,8 @@ class BaseAction(ABC):
|
||||
thinking_id: str,
|
||||
chat_stream: ChatStream,
|
||||
log_prefix: str = "",
|
||||
plugin_config: Optional[dict] = None,
|
||||
action_message: Optional[dict] = None,
|
||||
plugin_config: dict | None = None,
|
||||
action_message: dict | None = None,
|
||||
**kwargs,
|
||||
):
|
||||
# sourcery skip: hoist-similar-statement-from-if, merge-else-if-into-elif, move-assign-in-block, swap-if-else-branches, swap-nested-ifs
|
||||
@@ -109,8 +106,8 @@ class BaseAction(ABC):
|
||||
# 二步Action相关实例属性
|
||||
self.is_two_step_action: bool = getattr(self.__class__, "is_two_step_action", False)
|
||||
self.step_one_description: str = getattr(self.__class__, "step_one_description", "")
|
||||
self.sub_actions: List[Tuple[str, str, Dict[str, str]]] = getattr(self.__class__, "sub_actions", []).copy()
|
||||
self._selected_sub_action: Optional[str] = None
|
||||
self.sub_actions: list[tuple[str, str, dict[str, str]]] = getattr(self.__class__, "sub_actions", []).copy()
|
||||
self._selected_sub_action: str | None = None
|
||||
"""当前选择的子Action名称,用于二步Action的状态管理"""
|
||||
|
||||
# =============================================================================
|
||||
@@ -200,7 +197,7 @@ class BaseAction(ABC):
|
||||
"""
|
||||
return self._validate_chat_type()
|
||||
|
||||
async def wait_for_new_message(self, timeout: int = 1200) -> Tuple[bool, str]:
|
||||
async def wait_for_new_message(self, timeout: int = 1200) -> tuple[bool, str]:
|
||||
"""等待新消息或超时
|
||||
|
||||
在loop_start_time之后等待新消息,如果没有新消息且没有超时,就一直等待。
|
||||
@@ -232,7 +229,7 @@ class BaseAction(ABC):
|
||||
|
||||
# 检查新消息
|
||||
current_time = time.time()
|
||||
new_message_count = message_api.count_new_messages(
|
||||
new_message_count = await message_api.count_new_messages(
|
||||
chat_id=self.chat_id, start_time=loop_start_time, end_time=current_time
|
||||
)
|
||||
|
||||
@@ -258,7 +255,7 @@ class BaseAction(ABC):
|
||||
return False, ""
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 等待新消息时发生错误: {e}")
|
||||
return False, f"等待新消息失败: {str(e)}"
|
||||
return False, f"等待新消息失败: {e!s}"
|
||||
|
||||
async def send_text(self, content: str, reply_to: str = "", typing: bool = False) -> bool:
|
||||
"""发送文本消息
|
||||
@@ -359,7 +356,7 @@ class BaseAction(ABC):
|
||||
)
|
||||
|
||||
async def send_command(
|
||||
self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True
|
||||
self, command_name: str, args: dict | None = None, display_message: str = "", storage_message: bool = True
|
||||
) -> bool:
|
||||
"""发送命令消息
|
||||
|
||||
@@ -400,7 +397,7 @@ class BaseAction(ABC):
|
||||
logger.error(f"{self.log_prefix} 发送命令时出错: {e}")
|
||||
return False
|
||||
|
||||
async def call_action(self, action_name: str, action_data: Optional[dict] = None) -> Tuple[bool, str]:
|
||||
async def call_action(self, action_name: str, action_data: dict | None = None) -> tuple[bool, str]:
|
||||
"""
|
||||
在当前Action中调用另一个Action。
|
||||
|
||||
@@ -514,7 +511,7 @@ class BaseAction(ABC):
|
||||
sub_actions=getattr(cls, "sub_actions", []).copy(),
|
||||
)
|
||||
|
||||
async def handle_step_one(self) -> Tuple[bool, str]:
|
||||
async def handle_step_one(self) -> tuple[bool, str]:
|
||||
"""处理二步Action的第一步
|
||||
|
||||
Returns:
|
||||
@@ -546,7 +543,7 @@ class BaseAction(ABC):
|
||||
# 调用第二步执行
|
||||
return await self.execute_step_two(selected_action)
|
||||
|
||||
async def execute_step_two(self, sub_action_name: str) -> Tuple[bool, str]:
|
||||
async def execute_step_two(self, sub_action_name: str) -> tuple[bool, str]:
|
||||
"""执行二步Action的第二步
|
||||
|
||||
Args:
|
||||
@@ -562,7 +559,7 @@ class BaseAction(ABC):
|
||||
return False, f"二步Action必须实现execute_step_two方法来处理操作: {sub_action_name}"
|
||||
|
||||
@abstractmethod
|
||||
async def execute(self) -> Tuple[bool, str]:
|
||||
async def execute(self) -> tuple[bool, str]:
|
||||
"""执行Action的抽象方法,子类必须实现
|
||||
|
||||
对于二步Action,会自动处理第一步逻辑
|
||||
@@ -577,7 +574,7 @@ class BaseAction(ABC):
|
||||
# 普通Action由子类实现
|
||||
pass
|
||||
|
||||
async def handle_action(self) -> Tuple[bool, str]:
|
||||
async def handle_action(self) -> tuple[bool, str]:
|
||||
"""兼容旧系统的handle_action接口,委托给execute方法
|
||||
|
||||
为了保持向后兼容性,旧系统的代码可能会调用handle_action方法。
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from src.common.data_models.message_manager_data_model import StreamContext
|
||||
from .component_types import ChatType
|
||||
from src.plugin_system.base.component_types import ChatterInfo, ComponentType
|
||||
|
||||
from .component_types import ChatType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.chat.planner_actions.action_manager import ChatterActionManager
|
||||
|
||||
@@ -13,7 +15,7 @@ class BaseChatter(ABC):
|
||||
"""Chatter组件的名称"""
|
||||
chatter_description: str = ""
|
||||
"""Chatter组件的描述"""
|
||||
chat_types: List[ChatType] = [ChatType.PRIVATE, ChatType.GROUP]
|
||||
chat_types: list[ChatType] = [ChatType.PRIVATE, ChatType.GROUP]
|
||||
|
||||
def __init__(self, stream_id: str, action_manager: "ChatterActionManager"):
|
||||
"""
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, Tuple, Optional
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.base.component_types import CommandInfo, ComponentType, ChatType
|
||||
|
||||
from src.chat.message_receive.message import MessageRecv
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.apis import send_api
|
||||
from src.plugin_system.base.component_types import ChatType, CommandInfo, ComponentType
|
||||
|
||||
logger = get_logger("base_command")
|
||||
|
||||
@@ -29,7 +29,7 @@ class BaseCommand(ABC):
|
||||
chat_type_allow: ChatType = ChatType.ALL
|
||||
"""允许的聊天类型,默认为所有类型"""
|
||||
|
||||
def __init__(self, message: MessageRecv, plugin_config: Optional[dict] = None):
|
||||
def __init__(self, message: MessageRecv, plugin_config: dict | None = None):
|
||||
"""初始化Command组件
|
||||
|
||||
Args:
|
||||
@@ -37,7 +37,7 @@ class BaseCommand(ABC):
|
||||
plugin_config: 插件配置字典
|
||||
"""
|
||||
self.message = message
|
||||
self.matched_groups: Dict[str, str] = {} # 存储正则表达式匹配的命名组
|
||||
self.matched_groups: dict[str, str] = {} # 存储正则表达式匹配的命名组
|
||||
self.plugin_config = plugin_config or {} # 直接存储插件配置字典
|
||||
|
||||
self.log_prefix = "[Command]"
|
||||
@@ -55,7 +55,7 @@ class BaseCommand(ABC):
|
||||
f"{'群聊' if is_group else '私聊'}, 允许类型: {self.chat_type_allow.value}"
|
||||
)
|
||||
|
||||
def set_matched_groups(self, groups: Dict[str, str]) -> None:
|
||||
def set_matched_groups(self, groups: dict[str, str]) -> None:
|
||||
"""设置正则表达式匹配的命名组
|
||||
|
||||
Args:
|
||||
@@ -93,7 +93,7 @@ class BaseCommand(ABC):
|
||||
return self._validate_chat_type()
|
||||
|
||||
@abstractmethod
|
||||
async def execute(self) -> Tuple[bool, Optional[str], bool]:
|
||||
async def execute(self) -> tuple[bool, str | None, bool]:
|
||||
"""执行Command的抽象方法,子类必须实现
|
||||
|
||||
Returns:
|
||||
@@ -175,7 +175,7 @@ class BaseCommand(ABC):
|
||||
)
|
||||
|
||||
async def send_command(
|
||||
self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True
|
||||
self, command_name: str, args: dict | None = None, display_message: str = "", storage_message: bool = True
|
||||
) -> bool:
|
||||
"""发送命令消息
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import asyncio
|
||||
from typing import List, Dict, Any, Optional
|
||||
from typing import Any
|
||||
|
||||
from src.common.logger import get_logger
|
||||
|
||||
@@ -25,22 +25,22 @@ class HandlerResult:
|
||||
class HandlerResultsCollection:
|
||||
"""HandlerResult集合,提供便捷的查询方法"""
|
||||
|
||||
def __init__(self, results: List[HandlerResult]):
|
||||
def __init__(self, results: list[HandlerResult]):
|
||||
self.results = results
|
||||
|
||||
def all_continue_process(self) -> bool:
|
||||
"""检查是否所有handler的continue_process都为True"""
|
||||
return all(result.continue_process for result in self.results)
|
||||
|
||||
def get_all_results(self) -> List[HandlerResult]:
|
||||
def get_all_results(self) -> list[HandlerResult]:
|
||||
"""获取所有HandlerResult"""
|
||||
return self.results
|
||||
|
||||
def get_failed_handlers(self) -> List[HandlerResult]:
|
||||
def get_failed_handlers(self) -> list[HandlerResult]:
|
||||
"""获取执行失败的handler结果"""
|
||||
return [result for result in self.results if not result.success]
|
||||
|
||||
def get_stopped_handlers(self) -> List[HandlerResult]:
|
||||
def get_stopped_handlers(self) -> list[HandlerResult]:
|
||||
"""获取continue_process为False的handler结果"""
|
||||
return [result for result in self.results if not result.continue_process]
|
||||
|
||||
@@ -57,7 +57,7 @@ class HandlerResultsCollection:
|
||||
else:
|
||||
return {result.handler_name: result.message for result in self.results}
|
||||
|
||||
def get_handler_result(self, handler_name: str) -> Optional[HandlerResult]:
|
||||
def get_handler_result(self, handler_name: str) -> HandlerResult | None:
|
||||
"""获取指定handler的结果"""
|
||||
for result in self.results:
|
||||
if result.handler_name == handler_name:
|
||||
@@ -72,7 +72,7 @@ class HandlerResultsCollection:
|
||||
"""获取执行失败的handler数量"""
|
||||
return sum(1 for result in self.results if not result.success)
|
||||
|
||||
def get_summary(self) -> Dict[str, Any]:
|
||||
def get_summary(self) -> dict[str, Any]:
|
||||
"""获取执行摘要"""
|
||||
return {
|
||||
"total_handlers": len(self.results),
|
||||
@@ -85,13 +85,13 @@ class HandlerResultsCollection:
|
||||
|
||||
|
||||
class BaseEvent:
|
||||
def __init__(self, name: str, allowed_subscribers: List[str] = None, allowed_triggers: List[str] = None):
|
||||
def __init__(self, name: str, allowed_subscribers: list[str] = None, allowed_triggers: list[str] = None):
|
||||
self.name = name
|
||||
self.enabled = True
|
||||
self.allowed_subscribers = allowed_subscribers # 记录事件处理器名
|
||||
self.allowed_triggers = allowed_triggers # 记录插件名
|
||||
|
||||
self.subscribers: List["BaseEventHandler"] = [] # 订阅该事件的事件处理器列表
|
||||
self.subscribers: list["BaseEventHandler"] = [] # 订阅该事件的事件处理器列表
|
||||
|
||||
self.event_handle_lock = asyncio.Lock()
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Tuple, Optional, List, Union
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from .component_types import EventType, EventHandlerInfo, ComponentType
|
||||
|
||||
from .component_types import ComponentType, EventHandlerInfo, EventType
|
||||
|
||||
logger = get_logger("base_event_handler")
|
||||
|
||||
@@ -21,7 +21,7 @@ class BaseEventHandler(ABC):
|
||||
"""处理器权重,越大权重越高"""
|
||||
intercept_message: bool = False
|
||||
"""是否拦截消息,默认为否"""
|
||||
init_subscribe: List[Union[EventType, str]] = [EventType.UNKNOWN]
|
||||
init_subscribe: list[EventType | str] = [EventType.UNKNOWN]
|
||||
"""初始化时订阅的事件名称"""
|
||||
plugin_name = None
|
||||
|
||||
@@ -44,7 +44,7 @@ class BaseEventHandler(ABC):
|
||||
self.plugin_config = getattr(self.__class__, "plugin_config", {})
|
||||
|
||||
@abstractmethod
|
||||
async def execute(self, kwargs: dict | None) -> Tuple[bool, bool, Optional[str]]:
|
||||
async def execute(self, kwargs: dict | None) -> tuple[bool, bool, str | None]:
|
||||
"""执行事件处理的抽象方法,子类必须实现
|
||||
Args:
|
||||
kwargs (dict | None): 事件消息对象,当你注册的事件为ON_START和ON_STOP时message为None
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from abc import abstractmethod
|
||||
from typing import List, Type, Tuple, Union
|
||||
from .plugin_base import PluginBase
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.base.component_types import ActionInfo, CommandInfo, PlusCommandInfo, EventHandlerInfo, ToolInfo
|
||||
from src.plugin_system.base.component_types import ActionInfo, CommandInfo, EventHandlerInfo, PlusCommandInfo, ToolInfo
|
||||
|
||||
from .base_action import BaseAction
|
||||
from .base_command import BaseCommand
|
||||
from .base_events_handler import BaseEventHandler
|
||||
from .base_tool import BaseTool
|
||||
from .plugin_base import PluginBase
|
||||
from .plus_command import PlusCommand
|
||||
|
||||
logger = get_logger("base_plugin")
|
||||
@@ -28,14 +28,12 @@ class BasePlugin(PluginBase):
|
||||
@abstractmethod
|
||||
def get_plugin_components(
|
||||
self,
|
||||
) -> List[
|
||||
Union[
|
||||
Tuple[ActionInfo, Type[BaseAction]],
|
||||
Tuple[CommandInfo, Type[BaseCommand]],
|
||||
Tuple[PlusCommandInfo, Type[PlusCommand]],
|
||||
Tuple[EventHandlerInfo, Type[BaseEventHandler]],
|
||||
Tuple[ToolInfo, Type[BaseTool]],
|
||||
]
|
||||
) -> list[
|
||||
tuple[ActionInfo, type[BaseAction]]
|
||||
| tuple[CommandInfo, type[BaseCommand]]
|
||||
| tuple[PlusCommandInfo, type[PlusCommand]]
|
||||
| tuple[EventHandlerInfo, type[BaseEventHandler]]
|
||||
| tuple[ToolInfo, type[BaseTool]]
|
||||
]:
|
||||
"""获取插件包含的组件列表
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, List, Optional, Tuple
|
||||
from typing import Any
|
||||
|
||||
from rich.traceback import install
|
||||
|
||||
from src.common.logger import get_logger
|
||||
@@ -17,7 +18,7 @@ class BaseTool(ABC):
|
||||
"""工具的名称"""
|
||||
description: str = ""
|
||||
"""工具的描述"""
|
||||
parameters: List[Tuple[str, ToolParamType, str, bool, List[str] | None]] = []
|
||||
parameters: list[tuple[str, ToolParamType, str, bool, list[str] | None]] = []
|
||||
"""工具的参数定义,为[("param_name", param_type, "description", required, enum_values)]格式
|
||||
param_name: 参数名称
|
||||
param_type: 参数类型
|
||||
@@ -35,7 +36,7 @@ class BaseTool(ABC):
|
||||
"""是否为该工具启用缓存"""
|
||||
cache_ttl: int = 3600
|
||||
"""缓存的TTL值(秒),默认为3600秒(1小时)"""
|
||||
semantic_cache_query_key: Optional[str] = None
|
||||
semantic_cache_query_key: str | None = None
|
||||
"""用于语义缓存的查询参数键名。如果设置,将使用此参数的值进行语义相似度搜索"""
|
||||
|
||||
# 二步工具调用相关属性
|
||||
@@ -43,10 +44,10 @@ class BaseTool(ABC):
|
||||
"""是否为二步工具。如果为True,工具将分两步调用:第一步展示工具信息,第二步执行具体操作"""
|
||||
step_one_description: str = ""
|
||||
"""第一步的描述,用于向LLM展示工具的基本功能"""
|
||||
sub_tools: List[Tuple[str, str, List[Tuple[str, ToolParamType, str, bool, List[str] | None]]]] = []
|
||||
sub_tools: list[tuple[str, str, list[tuple[str, ToolParamType, str, bool, list[str] | None]]]] = []
|
||||
"""子工具列表,格式为[(子工具名, 子工具描述, 子工具参数)]。仅在二步工具中使用"""
|
||||
|
||||
def __init__(self, plugin_config: Optional[dict] = None):
|
||||
def __init__(self, plugin_config: dict | None = None):
|
||||
self.plugin_config = plugin_config or {} # 直接存储插件配置字典
|
||||
|
||||
@classmethod
|
||||
@@ -101,7 +102,7 @@ class BaseTool(ABC):
|
||||
raise ValueError(f"未找到子工具: {sub_tool_name}")
|
||||
|
||||
@classmethod
|
||||
def get_all_sub_tool_definitions(cls) -> List[dict[str, Any]]:
|
||||
def get_all_sub_tool_definitions(cls) -> list[dict[str, Any]]:
|
||||
"""获取所有子工具的定义
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
提供简单易用的命令参数解析功能
|
||||
"""
|
||||
|
||||
from typing import List, Optional
|
||||
import shlex
|
||||
|
||||
|
||||
@@ -20,7 +19,7 @@ class CommandArgs:
|
||||
raw_args: 原始参数字符串
|
||||
"""
|
||||
self._raw_args = raw_args.strip()
|
||||
self._parsed_args: Optional[List[str]] = None
|
||||
self._parsed_args: list[str] | None = None
|
||||
|
||||
def get_raw(self) -> str:
|
||||
"""获取完整的参数字符串
|
||||
@@ -30,7 +29,7 @@ class CommandArgs:
|
||||
"""
|
||||
return self._raw_args
|
||||
|
||||
def get_args(self) -> List[str]:
|
||||
def get_args(self) -> list[str]:
|
||||
"""获取解析后的参数列表
|
||||
|
||||
将参数按空格分割,支持引号包围的参数
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from enum import Enum
|
||||
from typing import Dict, Any, List, Optional, Tuple
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from maim_message import Seg
|
||||
|
||||
from src.llm_models.payload_content.tool_option import ToolParamType as ToolParamType
|
||||
from src.llm_models.payload_content.tool_option import ToolCall as ToolCall
|
||||
from src.llm_models.payload_content.tool_option import ToolParamType as ToolParamType
|
||||
|
||||
|
||||
# 组件类型枚举
|
||||
@@ -114,7 +115,7 @@ class ComponentInfo:
|
||||
enabled: bool = True # 是否启用
|
||||
plugin_name: str = "" # 所属插件名称
|
||||
is_built_in: bool = False # 是否为内置组件
|
||||
metadata: Dict[str, Any] = field(default_factory=dict) # 额外元数据
|
||||
metadata: dict[str, Any] = field(default_factory=dict) # 额外元数据
|
||||
|
||||
def __post_init__(self):
|
||||
if self.metadata is None:
|
||||
@@ -125,18 +126,18 @@ class ComponentInfo:
|
||||
class ActionInfo(ComponentInfo):
|
||||
"""动作组件信息"""
|
||||
|
||||
action_parameters: Dict[str, str] = field(
|
||||
action_parameters: dict[str, str] = field(
|
||||
default_factory=dict
|
||||
) # 动作参数与描述,例如 {"param1": "描述1", "param2": "描述2"}
|
||||
action_require: List[str] = field(default_factory=list) # 动作需求说明
|
||||
associated_types: List[str] = field(default_factory=list) # 关联的消息类型
|
||||
action_require: list[str] = field(default_factory=list) # 动作需求说明
|
||||
associated_types: list[str] = field(default_factory=list) # 关联的消息类型
|
||||
# 激活类型相关
|
||||
focus_activation_type: ActionActivationType = ActionActivationType.ALWAYS
|
||||
normal_activation_type: ActionActivationType = ActionActivationType.ALWAYS
|
||||
activation_type: ActionActivationType = ActionActivationType.ALWAYS
|
||||
random_activation_probability: float = 0.0
|
||||
llm_judge_prompt: str = ""
|
||||
activation_keywords: List[str] = field(default_factory=list) # 激活关键词列表
|
||||
activation_keywords: list[str] = field(default_factory=list) # 激活关键词列表
|
||||
keyword_case_sensitive: bool = False
|
||||
# 模式和并行设置
|
||||
mode_enable: ChatMode = ChatMode.ALL
|
||||
@@ -145,7 +146,7 @@ class ActionInfo(ComponentInfo):
|
||||
# 二步Action相关属性
|
||||
is_two_step_action: bool = False # 是否为二步Action
|
||||
step_one_description: str = "" # 第一步的描述
|
||||
sub_actions: List[Tuple[str, str, Dict[str, str]]] = field(default_factory=list) # 子Action列表
|
||||
sub_actions: list[tuple[str, str, dict[str, str]]] = field(default_factory=list) # 子Action列表
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
@@ -178,7 +179,7 @@ class CommandInfo(ComponentInfo):
|
||||
class PlusCommandInfo(ComponentInfo):
|
||||
"""增强命令组件信息"""
|
||||
|
||||
command_aliases: List[str] = field(default_factory=list) # 命令别名列表
|
||||
command_aliases: list[str] = field(default_factory=list) # 命令别名列表
|
||||
priority: int = 0 # 命令优先级
|
||||
chat_type_allow: ChatType = ChatType.ALL # 允许的聊天类型
|
||||
intercept_message: bool = False # 是否拦截消息
|
||||
@@ -194,7 +195,7 @@ class PlusCommandInfo(ComponentInfo):
|
||||
class ToolInfo(ComponentInfo):
|
||||
"""工具组件信息"""
|
||||
|
||||
tool_parameters: List[Tuple[str, ToolParamType, str, bool, List[str] | None]] = field(
|
||||
tool_parameters: list[tuple[str, ToolParamType, str, bool, list[str] | None]] = field(
|
||||
default_factory=list
|
||||
) # 工具参数定义
|
||||
tool_description: str = "" # 工具描述
|
||||
@@ -248,18 +249,18 @@ class PluginInfo:
|
||||
author: str = "" # 插件作者
|
||||
enabled: bool = True # 是否启用
|
||||
is_built_in: bool = False # 是否为内置插件
|
||||
components: List[ComponentInfo] = field(default_factory=list) # 包含的组件列表
|
||||
dependencies: List[str] = field(default_factory=list) # 依赖的其他插件
|
||||
python_dependencies: List[PythonDependency] = field(default_factory=list) # Python包依赖
|
||||
components: list[ComponentInfo] = field(default_factory=list) # 包含的组件列表
|
||||
dependencies: list[str] = field(default_factory=list) # 依赖的其他插件
|
||||
python_dependencies: list[PythonDependency] = field(default_factory=list) # Python包依赖
|
||||
config_file: str = "" # 配置文件路径
|
||||
metadata: Dict[str, Any] = field(default_factory=dict) # 额外元数据
|
||||
metadata: dict[str, Any] = field(default_factory=dict) # 额外元数据
|
||||
# 新增:manifest相关信息
|
||||
manifest_data: Dict[str, Any] = field(default_factory=dict) # manifest文件数据
|
||||
manifest_data: dict[str, Any] = field(default_factory=dict) # manifest文件数据
|
||||
license: str = "" # 插件许可证
|
||||
homepage_url: str = "" # 插件主页
|
||||
repository_url: str = "" # 插件仓库地址
|
||||
keywords: List[str] = field(default_factory=list) # 插件关键词
|
||||
categories: List[str] = field(default_factory=list) # 插件分类
|
||||
keywords: list[str] = field(default_factory=list) # 插件关键词
|
||||
categories: list[str] = field(default_factory=list) # 插件分类
|
||||
min_host_version: str = "" # 最低主机版本要求
|
||||
max_host_version: str = "" # 最高主机版本要求
|
||||
|
||||
@@ -279,7 +280,7 @@ class PluginInfo:
|
||||
if self.categories is None:
|
||||
self.categories = []
|
||||
|
||||
def get_missing_packages(self) -> List[PythonDependency]:
|
||||
def get_missing_packages(self) -> list[PythonDependency]:
|
||||
"""检查缺失的Python包"""
|
||||
missing = []
|
||||
for dep in self.python_dependencies:
|
||||
@@ -290,7 +291,7 @@ class PluginInfo:
|
||||
missing.append(dep)
|
||||
return missing
|
||||
|
||||
def get_pip_requirements(self) -> List[str]:
|
||||
def get_pip_requirements(self) -> list[str]:
|
||||
"""获取所有pip安装格式的依赖"""
|
||||
return [dep.get_pip_requirement() for dep in self.python_dependencies]
|
||||
|
||||
@@ -299,16 +300,16 @@ class PluginInfo:
|
||||
class MaiMessages:
|
||||
"""MaiM插件消息"""
|
||||
|
||||
message_segments: List[Seg] = field(default_factory=list)
|
||||
message_segments: list[Seg] = field(default_factory=list)
|
||||
"""消息段列表,支持多段消息"""
|
||||
|
||||
message_base_info: Dict[str, Any] = field(default_factory=dict)
|
||||
message_base_info: dict[str, Any] = field(default_factory=dict)
|
||||
"""消息基本信息,包含平台,用户信息等数据"""
|
||||
|
||||
plain_text: str = ""
|
||||
"""纯文本消息内容"""
|
||||
|
||||
raw_message: Optional[str] = None
|
||||
raw_message: str | None = None
|
||||
"""原始消息内容"""
|
||||
|
||||
is_group_message: bool = False
|
||||
@@ -317,28 +318,28 @@ class MaiMessages:
|
||||
is_private_message: bool = False
|
||||
"""是否为私聊消息"""
|
||||
|
||||
stream_id: Optional[str] = None
|
||||
stream_id: str | None = None
|
||||
"""流ID,用于标识消息流"""
|
||||
|
||||
llm_prompt: Optional[str] = None
|
||||
llm_prompt: str | None = None
|
||||
"""LLM提示词"""
|
||||
|
||||
llm_response_content: Optional[str] = None
|
||||
llm_response_content: str | None = None
|
||||
"""LLM响应内容"""
|
||||
|
||||
llm_response_reasoning: Optional[str] = None
|
||||
llm_response_reasoning: str | None = None
|
||||
"""LLM响应推理内容"""
|
||||
|
||||
llm_response_model: Optional[str] = None
|
||||
llm_response_model: str | None = None
|
||||
"""LLM响应模型名称"""
|
||||
|
||||
llm_response_tool_call: Optional[List[ToolCall]] = None
|
||||
llm_response_tool_call: list[ToolCall] | None = None
|
||||
"""LLM使用的工具调用"""
|
||||
|
||||
action_usage: Optional[List[str]] = None
|
||||
action_usage: list[str] | None = None
|
||||
"""使用的Action"""
|
||||
|
||||
additional_data: Dict[Any, Any] = field(default_factory=dict)
|
||||
additional_data: dict[Any, Any] = field(default_factory=dict)
|
||||
"""附加数据,可以存储额外信息"""
|
||||
|
||||
def __post_init__(self):
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
插件系统配置类型定义
|
||||
"""
|
||||
|
||||
from typing import Any, Optional, List
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -13,6 +13,6 @@ class ConfigField:
|
||||
type: type # 字段类型
|
||||
default: Any # 默认值
|
||||
description: str # 字段描述
|
||||
example: Optional[str] = None # 示例值
|
||||
example: str | None = None # 示例值
|
||||
required: bool = False # 是否必需
|
||||
choices: Optional[List[Any]] = field(default_factory=list) # 可选值列表
|
||||
choices: list[Any] | None = field(default_factory=list) # 可选值列表
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Dict, List, Any, Union
|
||||
import os
|
||||
import toml
|
||||
import orjson
|
||||
import shutil
|
||||
import datetime
|
||||
import os
|
||||
import shutil
|
||||
from abc import ABC, abstractmethod
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import orjson
|
||||
import toml
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import CONFIG_DIR
|
||||
@@ -38,12 +39,12 @@ class PluginBase(ABC):
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def dependencies(self) -> List[str]:
|
||||
def dependencies(self) -> list[str]:
|
||||
return [] # 依赖的其他插件
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def python_dependencies(self) -> List[Union[str, PythonDependency]]:
|
||||
def python_dependencies(self) -> list[str | PythonDependency]:
|
||||
return [] # Python包依赖,支持字符串列表或PythonDependency对象列表
|
||||
|
||||
@property
|
||||
@@ -53,15 +54,15 @@ class PluginBase(ABC):
|
||||
|
||||
# manifest文件相关
|
||||
manifest_file_name: str = "_manifest.json" # manifest文件名
|
||||
manifest_data: Dict[str, Any] = {} # manifest数据
|
||||
manifest_data: dict[str, Any] = {} # manifest数据
|
||||
|
||||
# 配置定义
|
||||
@property
|
||||
@abstractmethod
|
||||
def config_schema(self) -> Dict[str, Union[Dict[str, ConfigField], str]]:
|
||||
def config_schema(self) -> dict[str, dict[str, ConfigField] | str]:
|
||||
return {}
|
||||
|
||||
config_section_descriptions: Dict[str, str] = {}
|
||||
config_section_descriptions: dict[str, str] = {}
|
||||
|
||||
def __init__(self, plugin_dir: str):
|
||||
"""初始化插件
|
||||
@@ -69,7 +70,7 @@ class PluginBase(ABC):
|
||||
Args:
|
||||
plugin_dir: 插件目录路径,由插件管理器传递
|
||||
"""
|
||||
self.config: Dict[str, Any] = {} # 插件配置
|
||||
self.config: dict[str, Any] = {} # 插件配置
|
||||
self.plugin_dir = plugin_dir # 插件目录路径
|
||||
self.log_prefix = f"[Plugin:{self.plugin_name}]"
|
||||
self._is_enabled = self.enable_plugin # 从插件定义中获取默认启用状态
|
||||
@@ -144,7 +145,7 @@ class PluginBase(ABC):
|
||||
raise FileNotFoundError(error_msg)
|
||||
|
||||
try:
|
||||
with open(manifest_path, "r", encoding="utf-8") as f:
|
||||
with open(manifest_path, encoding="utf-8") as f:
|
||||
self.manifest_data = orjson.loads(f.read())
|
||||
|
||||
logger.debug(f"{self.log_prefix} 成功加载manifest文件: {manifest_path}")
|
||||
@@ -155,8 +156,8 @@ class PluginBase(ABC):
|
||||
except orjson.JSONDecodeError as e:
|
||||
error_msg = f"{self.log_prefix} manifest文件格式错误: {e}"
|
||||
logger.error(error_msg)
|
||||
raise ValueError(error_msg) # noqa
|
||||
except IOError as e:
|
||||
raise ValueError(error_msg)
|
||||
except OSError as e:
|
||||
error_msg = f"{self.log_prefix} 读取manifest文件失败: {e}"
|
||||
logger.error(error_msg)
|
||||
raise IOError(error_msg) # noqa
|
||||
@@ -266,7 +267,7 @@ class PluginBase(ABC):
|
||||
with open(config_file_path, "w", encoding="utf-8") as f:
|
||||
f.write(toml_str)
|
||||
logger.info(f"{self.log_prefix} 已生成默认配置文件: {config_file_path}")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
logger.error(f"{self.log_prefix} 保存默认配置文件失败: {e}", exc_info=True)
|
||||
|
||||
def _backup_config_file(self, config_file_path: str) -> str:
|
||||
@@ -288,13 +289,13 @@ class PluginBase(ABC):
|
||||
return ""
|
||||
|
||||
def _synchronize_config(
|
||||
self, schema_config: Dict[str, Any], user_config: Dict[str, Any]
|
||||
) -> tuple[Dict[str, Any], bool]:
|
||||
self, schema_config: dict[str, Any], user_config: dict[str, Any]
|
||||
) -> tuple[dict[str, Any], bool]:
|
||||
"""递归地将用户配置与 schema 同步,返回同步后的配置和是否发生变化的标志"""
|
||||
changed = False
|
||||
|
||||
# 内部递归函数
|
||||
def _sync_dicts(schema_dict: Dict[str, Any], user_dict: Dict[str, Any], parent_key: str = "") -> Dict[str, Any]:
|
||||
def _sync_dicts(schema_dict: dict[str, Any], user_dict: dict[str, Any], parent_key: str = "") -> dict[str, Any]:
|
||||
nonlocal changed
|
||||
synced_dict = schema_dict.copy()
|
||||
|
||||
@@ -326,7 +327,7 @@ class PluginBase(ABC):
|
||||
final_config = _sync_dicts(schema_config, user_config)
|
||||
return final_config, changed
|
||||
|
||||
def _generate_config_from_schema(self) -> Dict[str, Any]:
|
||||
def _generate_config_from_schema(self) -> dict[str, Any]:
|
||||
# sourcery skip: dict-comprehension
|
||||
"""根据schema生成配置数据结构(不写入文件)"""
|
||||
if not self.config_schema:
|
||||
@@ -348,7 +349,7 @@ class PluginBase(ABC):
|
||||
|
||||
return config_data
|
||||
|
||||
def _save_config_to_file(self, config_data: Dict[str, Any], config_file_path: str):
|
||||
def _save_config_to_file(self, config_data: dict[str, Any], config_file_path: str):
|
||||
"""将配置数据保存为TOML文件(包含注释)"""
|
||||
if not self.config_schema:
|
||||
logger.debug(f"{self.log_prefix} 插件未定义config_schema,不生成配置文件")
|
||||
@@ -410,7 +411,7 @@ class PluginBase(ABC):
|
||||
with open(config_file_path, "w", encoding="utf-8") as f:
|
||||
f.write(toml_str)
|
||||
logger.info(f"{self.log_prefix} 配置文件已保存: {config_file_path}")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
logger.error(f"{self.log_prefix} 保存配置文件失败: {e}", exc_info=True)
|
||||
|
||||
def _load_plugin_config(self): # sourcery skip: extract-method
|
||||
@@ -456,7 +457,7 @@ class PluginBase(ABC):
|
||||
return
|
||||
|
||||
try:
|
||||
with open(user_config_path, "r", encoding="utf-8") as f:
|
||||
with open(user_config_path, encoding="utf-8") as f:
|
||||
user_config = toml.load(f) or {}
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 加载用户配置文件 {user_config_path} 失败: {e}", exc_info=True)
|
||||
@@ -520,7 +521,7 @@ class PluginBase(ABC):
|
||||
|
||||
return current
|
||||
|
||||
def _normalize_python_dependencies(self, dependencies: Any) -> List[PythonDependency]:
|
||||
def _normalize_python_dependencies(self, dependencies: Any) -> list[PythonDependency]:
|
||||
"""将依赖列表标准化为PythonDependency对象"""
|
||||
from packaging.requirements import Requirement
|
||||
|
||||
@@ -549,7 +550,7 @@ class PluginBase(ABC):
|
||||
|
||||
return normalized
|
||||
|
||||
def _check_python_dependencies(self, dependencies: List[PythonDependency]) -> bool:
|
||||
def _check_python_dependencies(self, dependencies: list[PythonDependency]) -> bool:
|
||||
"""检查Python依赖并尝试自动安装"""
|
||||
if not dependencies:
|
||||
logger.info(f"{self.log_prefix} 无Python依赖需要检查")
|
||||
|
||||
@@ -3,17 +3,16 @@
|
||||
提供更简单易用的命令处理方式,无需手写正则表达式
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Tuple, Optional, List
|
||||
import re
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.base.component_types import PlusCommandInfo, ComponentType, ChatType
|
||||
from src.chat.message_receive.message import MessageRecv
|
||||
from src.plugin_system.apis import send_api
|
||||
from src.plugin_system.base.command_args import CommandArgs
|
||||
from src.plugin_system.base.base_command import BaseCommand
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import global_config
|
||||
from src.plugin_system.apis import send_api
|
||||
from src.plugin_system.base.base_command import BaseCommand
|
||||
from src.plugin_system.base.command_args import CommandArgs
|
||||
from src.plugin_system.base.component_types import ChatType, ComponentType, PlusCommandInfo
|
||||
|
||||
logger = get_logger("plus_command")
|
||||
|
||||
@@ -39,7 +38,7 @@ class PlusCommand(ABC):
|
||||
command_description: str = ""
|
||||
"""命令描述"""
|
||||
|
||||
command_aliases: List[str] = []
|
||||
command_aliases: list[str] = []
|
||||
"""命令别名列表,如 ['say', 'repeat']"""
|
||||
|
||||
priority: int = 0
|
||||
@@ -51,7 +50,7 @@ class PlusCommand(ABC):
|
||||
intercept_message: bool = False
|
||||
"""是否拦截消息,不进行后续处理"""
|
||||
|
||||
def __init__(self, message: MessageRecv, plugin_config: Optional[dict] = None):
|
||||
def __init__(self, message: MessageRecv, plugin_config: dict | None = None):
|
||||
"""初始化命令组件
|
||||
|
||||
Args:
|
||||
@@ -172,7 +171,7 @@ class PlusCommand(ABC):
|
||||
return False
|
||||
|
||||
@abstractmethod
|
||||
async def execute(self, args: CommandArgs) -> Tuple[bool, Optional[str], bool]:
|
||||
async def execute(self, args: CommandArgs) -> tuple[bool, str | None, bool]:
|
||||
"""执行命令的抽象方法,子类必须实现
|
||||
|
||||
Args:
|
||||
@@ -341,7 +340,7 @@ class PlusCommandAdapter(BaseCommand):
|
||||
将PlusCommand适配到现有的插件系统,继承BaseCommand
|
||||
"""
|
||||
|
||||
def __init__(self, plus_command_class, message: MessageRecv, plugin_config: Optional[dict] = None):
|
||||
def __init__(self, plus_command_class, message: MessageRecv, plugin_config: dict | None = None):
|
||||
"""初始化适配器
|
||||
|
||||
Args:
|
||||
@@ -363,7 +362,7 @@ class PlusCommandAdapter(BaseCommand):
|
||||
# 创建PlusCommand实例
|
||||
self.plus_command = plus_command_class(message, plugin_config)
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str], bool]:
|
||||
async def execute(self) -> tuple[bool, str | None, bool]:
|
||||
"""执行命令
|
||||
|
||||
Returns:
|
||||
@@ -382,7 +381,7 @@ class PlusCommandAdapter(BaseCommand):
|
||||
return await self.plus_command.execute(self.plus_command.args)
|
||||
except Exception as e:
|
||||
logger.error(f"执行命令时出错: {e}", exc_info=True)
|
||||
return False, f"命令执行出错: {str(e)}", self.intercept_message
|
||||
return False, f"命令执行出错: {e!s}", self.intercept_message
|
||||
|
||||
|
||||
def create_plus_command_adapter(plus_command_class):
|
||||
@@ -401,13 +400,13 @@ def create_plus_command_adapter(plus_command_class):
|
||||
command_pattern = plus_command_class._generate_command_pattern()
|
||||
chat_type_allow = getattr(plus_command_class, "chat_type_allow", ChatType.ALL)
|
||||
|
||||
def __init__(self, message: MessageRecv, plugin_config: Optional[dict] = None):
|
||||
def __init__(self, message: MessageRecv, plugin_config: dict | None = None):
|
||||
super().__init__(message, plugin_config)
|
||||
self.plus_command = plus_command_class(message, plugin_config)
|
||||
self.priority = getattr(plus_command_class, "priority", 0)
|
||||
self.intercept_message = getattr(plus_command_class, "intercept_message", False)
|
||||
|
||||
async def execute(self) -> Tuple[bool, Optional[str], bool]:
|
||||
async def execute(self) -> tuple[bool, str | None, bool]:
|
||||
"""执行命令"""
|
||||
# 从BaseCommand的正则匹配结果中提取参数
|
||||
args_text = ""
|
||||
@@ -429,7 +428,7 @@ def create_plus_command_adapter(plus_command_class):
|
||||
return await self.plus_command.execute(command_args)
|
||||
except Exception as e:
|
||||
logger.error(f"执行命令时出错: {e}", exc_info=True)
|
||||
return False, f"命令执行出错: {str(e)}", self.intercept_message
|
||||
return False, f"命令执行出错: {e!s}", self.intercept_message
|
||||
|
||||
return AdapterClass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user