Merge branch 'dev' of https://github.com/MaiM-with-u/MaiBot into dev
This commit is contained in:
@@ -61,7 +61,7 @@ __all__ = [
|
||||
"ConfigField",
|
||||
# 工具函数
|
||||
"ManifestValidator",
|
||||
"ManifestGenerator",
|
||||
"validate_plugin_manifest",
|
||||
"generate_plugin_manifest",
|
||||
# "ManifestGenerator",
|
||||
# "validate_plugin_manifest",
|
||||
# "generate_plugin_manifest",
|
||||
]
|
||||
|
||||
@@ -34,7 +34,4 @@ def register_event_plugin(cls, *args, **kwargs):
|
||||
|
||||
用法:
|
||||
@register_event_plugin
|
||||
class MyEventPlugin:
|
||||
event_type = EventType.MESSAGE_RECEIVED
|
||||
...
|
||||
"""
|
||||
@@ -111,7 +111,7 @@ async def _send_to_target(
|
||||
is_head=True,
|
||||
is_emoji=(message_type == "emoji"),
|
||||
thinking_start_time=current_time,
|
||||
reply_to = reply_to_platform_id
|
||||
reply_to=reply_to_platform_id,
|
||||
)
|
||||
|
||||
# 发送消息
|
||||
@@ -137,6 +137,7 @@ async def _send_to_target(
|
||||
|
||||
|
||||
async def _find_reply_message(target_stream, reply_to: str) -> Optional[MessageRecv]:
|
||||
# sourcery skip: inline-variable, use-named-expression
|
||||
"""查找要回复的消息
|
||||
|
||||
Args:
|
||||
@@ -184,14 +185,11 @@ async def _find_reply_message(target_stream, reply_to: str) -> Optional[MessageR
|
||||
|
||||
# 检查是否有 回复<aaa:bbb> 字段
|
||||
reply_pattern = r"回复<([^:<>]+):([^:<>]+)>"
|
||||
match = re.search(reply_pattern, translate_text)
|
||||
if match:
|
||||
if match := re.search(reply_pattern, translate_text):
|
||||
aaa = match.group(1)
|
||||
bbb = match.group(2)
|
||||
reply_person_id = get_person_info_manager().get_person_id(platform, bbb)
|
||||
reply_person_name = await get_person_info_manager().get_value(reply_person_id, "person_name")
|
||||
if not reply_person_name:
|
||||
reply_person_name = aaa
|
||||
reply_person_name = await get_person_info_manager().get_value(reply_person_id, "person_name") or aaa
|
||||
# 在内容前加上回复信息
|
||||
translate_text = re.sub(reply_pattern, f"回复 {reply_person_name}", translate_text, count=1)
|
||||
|
||||
@@ -206,9 +204,7 @@ async def _find_reply_message(target_stream, reply_to: str) -> Optional[MessageR
|
||||
aaa = m.group(1)
|
||||
bbb = m.group(2)
|
||||
at_person_id = get_person_info_manager().get_person_id(platform, bbb)
|
||||
at_person_name = await get_person_info_manager().get_value(at_person_id, "person_name")
|
||||
if not at_person_name:
|
||||
at_person_name = aaa
|
||||
at_person_name = await get_person_info_manager().get_value(at_person_id, "person_name") or aaa
|
||||
new_content += f"@{at_person_name}"
|
||||
last_end = m.end()
|
||||
new_content += translate_text[last_end:]
|
||||
@@ -403,7 +399,7 @@ async def text_to_group(
|
||||
"""
|
||||
stream_id = get_chat_manager().get_stream_id(platform, group_id, True)
|
||||
|
||||
return await _send_to_target("text", text, stream_id, "", typing, reply_to, storage_message)
|
||||
return await _send_to_target("text", text, stream_id, "", typing, reply_to, storage_message=storage_message)
|
||||
|
||||
|
||||
async def text_to_user(
|
||||
@@ -427,7 +423,7 @@ async def text_to_user(
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
stream_id = get_chat_manager().get_stream_id(platform, user_id, False)
|
||||
return await _send_to_target("text", text, stream_id, "", typing, reply_to, storage_message)
|
||||
return await _send_to_target("text", text, stream_id, "", typing, reply_to, storage_message=storage_message)
|
||||
|
||||
|
||||
async def emoji_to_group(emoji_base64: str, group_id: str, platform: str = "qq", storage_message: bool = True) -> bool:
|
||||
@@ -550,7 +546,9 @@ async def custom_to_group(
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
stream_id = get_chat_manager().get_stream_id(platform, group_id, True)
|
||||
return await _send_to_target(message_type, content, stream_id, display_message, typing, reply_to, storage_message)
|
||||
return await _send_to_target(
|
||||
message_type, content, stream_id, display_message, typing, reply_to, storage_message=storage_message
|
||||
)
|
||||
|
||||
|
||||
async def custom_to_user(
|
||||
@@ -578,7 +576,9 @@ async def custom_to_user(
|
||||
bool: 是否发送成功
|
||||
"""
|
||||
stream_id = get_chat_manager().get_stream_id(platform, user_id, False)
|
||||
return await _send_to_target(message_type, content, stream_id, display_message, typing, reply_to, storage_message)
|
||||
return await _send_to_target(
|
||||
message_type, content, stream_id, display_message, typing, reply_to, storage_message=storage_message
|
||||
)
|
||||
|
||||
|
||||
async def custom_message(
|
||||
@@ -618,4 +618,6 @@ async def custom_message(
|
||||
await send_api.custom_message("audio", audio_base64, "123456", True, reply_to="张三:你好")
|
||||
"""
|
||||
stream_id = get_chat_manager().get_stream_id(platform, target_id, is_group)
|
||||
return await _send_to_target(message_type, content, stream_id, display_message, typing, reply_to, storage_message)
|
||||
return await _send_to_target(
|
||||
message_type, content, stream_id, display_message, typing, reply_to, storage_message=storage_message
|
||||
)
|
||||
|
||||
@@ -38,7 +38,7 @@ class BaseAction(ABC):
|
||||
chat_stream: ChatStream,
|
||||
log_prefix: str = "",
|
||||
plugin_config: Optional[dict] = None,
|
||||
action_message: dict = None,
|
||||
action_message: Optional[dict] = None,
|
||||
**kwargs,
|
||||
):
|
||||
"""初始化Action组件
|
||||
@@ -63,7 +63,7 @@ class BaseAction(ABC):
|
||||
self.cycle_timers = cycle_timers
|
||||
self.thinking_id = thinking_id
|
||||
self.log_prefix = log_prefix
|
||||
|
||||
|
||||
# 保存插件配置
|
||||
self.plugin_config = plugin_config or {}
|
||||
|
||||
@@ -92,10 +92,10 @@ class BaseAction(ABC):
|
||||
self.chat_stream = chat_stream or kwargs.get("chat_stream")
|
||||
self.chat_id = self.chat_stream.stream_id
|
||||
self.platform = getattr(self.chat_stream, "platform", None)
|
||||
|
||||
|
||||
# 初始化基础信息(带类型注解)
|
||||
self.action_message = action_message
|
||||
|
||||
|
||||
self.group_id = None
|
||||
self.group_name = None
|
||||
self.user_id = None
|
||||
@@ -103,15 +103,17 @@ class BaseAction(ABC):
|
||||
self.is_group = False
|
||||
self.target_id = None
|
||||
self.has_action_message = False
|
||||
|
||||
|
||||
if self.action_message:
|
||||
self.has_action_message = True
|
||||
|
||||
else:
|
||||
self.action_message = {}
|
||||
|
||||
if self.has_action_message:
|
||||
if self.action_name != "no_reply":
|
||||
self.group_id = str(self.action_message.get("chat_info_group_id", None))
|
||||
self.group_name = self.action_message.get("chat_info_group_name", None)
|
||||
|
||||
|
||||
self.user_id = str(self.action_message.get("user_id", None))
|
||||
self.user_nickname = self.action_message.get("user_nickname", None)
|
||||
if self.group_id:
|
||||
@@ -132,8 +134,6 @@ class BaseAction(ABC):
|
||||
self.is_group = False
|
||||
self.target_id = self.user_id
|
||||
|
||||
|
||||
|
||||
logger.debug(f"{self.log_prefix} Action组件初始化完成")
|
||||
logger.info(
|
||||
f"{self.log_prefix} 聊天信息: 类型={'群聊' if self.is_group else '私聊'}, 平台={self.platform}, 目标={self.target_id}"
|
||||
@@ -199,7 +199,9 @@ class BaseAction(ABC):
|
||||
logger.error(f"{self.log_prefix} 等待新消息时发生错误: {e}")
|
||||
return False, f"等待新消息失败: {str(e)}"
|
||||
|
||||
async def send_text(self, content: str, reply_to: str = "", reply_to_platform_id: str = "", typing: bool = False) -> bool:
|
||||
async def send_text(
|
||||
self, content: str, reply_to: str = "", reply_to_platform_id: str = "", typing: bool = False
|
||||
) -> bool:
|
||||
"""发送文本消息
|
||||
|
||||
Args:
|
||||
@@ -299,7 +301,7 @@ class BaseAction(ABC):
|
||||
)
|
||||
|
||||
async def send_command(
|
||||
self, command_name: str, args: dict = None, display_message: str = None, storage_message: bool = True
|
||||
self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True
|
||||
) -> bool:
|
||||
"""发送命令消息
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class BaseCommand(ABC):
|
||||
)
|
||||
|
||||
async def send_command(
|
||||
self, command_name: str, args: dict = None, display_message: str = "", storage_message: bool = True
|
||||
self, command_name: str, args: Optional[dict] = None, display_message: str = "", storage_message: bool = True
|
||||
) -> bool:
|
||||
"""发送命令消息
|
||||
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from abc import abstractmethod
|
||||
|
||||
class BaseEventsPlugin(ABC):
|
||||
from .plugin_base import PluginBase
|
||||
from src.common.logger import get_logger
|
||||
|
||||
|
||||
class BaseEventPlugin(PluginBase):
|
||||
"""基于事件的插件基类
|
||||
|
||||
所有事件类型的插件都应该继承这个基类
|
||||
"""
|
||||
事件触发型插件基类
|
||||
|
||||
所有事件触发型插件都应该继承这个基类而不是 BasePlugin
|
||||
"""
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def plugin_name(self) -> str:
|
||||
return "" # 插件内部标识符(如 "hello_world_plugin")
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def enable_plugin(self) -> bool:
|
||||
return False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -7,10 +7,19 @@ from src.plugin_system.base.component_types import ComponentInfo
|
||||
|
||||
logger = get_logger("base_plugin")
|
||||
|
||||
|
||||
class BasePlugin(PluginBase):
|
||||
"""基于Action和Command的插件基类
|
||||
|
||||
所有上述类型的插件都应该继承这个基类,一个插件可以包含多种组件:
|
||||
- Action组件:处理聊天中的动作
|
||||
- Command组件:处理命令请求
|
||||
- 未来可扩展:Scheduler、Listener等
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def get_plugin_components(self) -> List[tuple[ComponentInfo, Type]]:
|
||||
"""获取插件包含的组件列表
|
||||
@@ -21,7 +30,7 @@ class BasePlugin(PluginBase):
|
||||
List[tuple[ComponentInfo, Type]]: [(组件信息, 组件类), ...]
|
||||
"""
|
||||
raise NotImplementedError("Subclasses must implement this method")
|
||||
|
||||
|
||||
def register_plugin(self) -> bool:
|
||||
"""注册插件及其所有组件"""
|
||||
from src.plugin_system.core.component_registry import component_registry
|
||||
|
||||
@@ -19,12 +19,9 @@ logger = get_logger("plugin_base")
|
||||
|
||||
|
||||
class PluginBase(ABC):
|
||||
"""插件基类
|
||||
"""插件总基类
|
||||
|
||||
所有插件都应该继承这个基类,一个插件可以包含多种组件:
|
||||
- Action组件:处理聊天中的动作
|
||||
- Command组件:处理命令请求
|
||||
- 未来可扩展:Scheduler、Listener等
|
||||
所有衍生插件基类都应该继承自此类,这个类定义了插件的基本结构和行为。
|
||||
"""
|
||||
|
||||
# 插件基本信息(子类必须定义)
|
||||
|
||||
@@ -346,67 +346,67 @@ class ComponentRegistry:
|
||||
|
||||
# === 状态管理方法 ===
|
||||
|
||||
def enable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
||||
# -------------------------------- NEED REFACTORING --------------------------------
|
||||
# -------------------------------- LOGIC ERROR -------------------------------------
|
||||
"""启用组件,支持命名空间解析"""
|
||||
# 首先尝试找到正确的命名空间化名称
|
||||
component_info = self.get_component_info(component_name, component_type)
|
||||
if not component_info:
|
||||
return False
|
||||
# def enable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
||||
# # -------------------------------- LOGIC ERROR -------------------------------------
|
||||
# """启用组件,支持命名空间解析"""
|
||||
# # 首先尝试找到正确的命名空间化名称
|
||||
# component_info = self.get_component_info(component_name, component_type)
|
||||
# if not component_info:
|
||||
# return False
|
||||
|
||||
# 根据组件类型构造正确的命名空间化名称
|
||||
if component_info.component_type == ComponentType.ACTION:
|
||||
namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
||||
elif component_info.component_type == ComponentType.COMMAND:
|
||||
namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
||||
else:
|
||||
namespaced_name = (
|
||||
f"{component_info.component_type.value}.{component_name}"
|
||||
if "." not in component_name
|
||||
else component_name
|
||||
)
|
||||
# # 根据组件类型构造正确的命名空间化名称
|
||||
# if component_info.component_type == ComponentType.ACTION:
|
||||
# namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
||||
# elif component_info.component_type == ComponentType.COMMAND:
|
||||
# namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
||||
# else:
|
||||
# namespaced_name = (
|
||||
# f"{component_info.component_type.value}.{component_name}"
|
||||
# if "." not in component_name
|
||||
# else component_name
|
||||
# )
|
||||
|
||||
if namespaced_name in self._components:
|
||||
self._components[namespaced_name].enabled = True
|
||||
# 如果是Action,更新默认动作集
|
||||
# ---- HERE ----
|
||||
# if isinstance(component_info, ActionInfo):
|
||||
# self._action_descriptions[component_name] = component_info.description
|
||||
logger.debug(f"已启用组件: {component_name} -> {namespaced_name}")
|
||||
return True
|
||||
return False
|
||||
# if namespaced_name in self._components:
|
||||
# self._components[namespaced_name].enabled = True
|
||||
# # 如果是Action,更新默认动作集
|
||||
# # ---- HERE ----
|
||||
# # if isinstance(component_info, ActionInfo):
|
||||
# # self._action_descriptions[component_name] = component_info.description
|
||||
# logger.debug(f"已启用组件: {component_name} -> {namespaced_name}")
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def disable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
||||
# -------------------------------- NEED REFACTORING --------------------------------
|
||||
# -------------------------------- LOGIC ERROR -------------------------------------
|
||||
"""禁用组件,支持命名空间解析"""
|
||||
# 首先尝试找到正确的命名空间化名称
|
||||
component_info = self.get_component_info(component_name, component_type)
|
||||
if not component_info:
|
||||
return False
|
||||
# def disable_component(self, component_name: str, component_type: ComponentType = None) -> bool:
|
||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
||||
# # -------------------------------- LOGIC ERROR -------------------------------------
|
||||
# """禁用组件,支持命名空间解析"""
|
||||
# # 首先尝试找到正确的命名空间化名称
|
||||
# component_info = self.get_component_info(component_name, component_type)
|
||||
# if not component_info:
|
||||
# return False
|
||||
|
||||
# 根据组件类型构造正确的命名空间化名称
|
||||
if component_info.component_type == ComponentType.ACTION:
|
||||
namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
||||
elif component_info.component_type == ComponentType.COMMAND:
|
||||
namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
||||
else:
|
||||
namespaced_name = (
|
||||
f"{component_info.component_type.value}.{component_name}"
|
||||
if "." not in component_name
|
||||
else component_name
|
||||
)
|
||||
# # 根据组件类型构造正确的命名空间化名称
|
||||
# if component_info.component_type == ComponentType.ACTION:
|
||||
# namespaced_name = f"action.{component_name}" if "." not in component_name else component_name
|
||||
# elif component_info.component_type == ComponentType.COMMAND:
|
||||
# namespaced_name = f"command.{component_name}" if "." not in component_name else component_name
|
||||
# else:
|
||||
# namespaced_name = (
|
||||
# f"{component_info.component_type.value}.{component_name}"
|
||||
# if "." not in component_name
|
||||
# else component_name
|
||||
# )
|
||||
|
||||
if namespaced_name in self._components:
|
||||
self._components[namespaced_name].enabled = False
|
||||
# 如果是Action,从默认动作集中移除
|
||||
# ---- HERE ----
|
||||
# if component_name in self._action_descriptions:
|
||||
# del self._action_descriptions[component_name]
|
||||
logger.debug(f"已禁用组件: {component_name} -> {namespaced_name}")
|
||||
return True
|
||||
return False
|
||||
# if namespaced_name in self._components:
|
||||
# self._components[namespaced_name].enabled = False
|
||||
# # 如果是Action,从默认动作集中移除
|
||||
# # ---- HERE ----
|
||||
# # if component_name in self._action_descriptions:
|
||||
# # del self._action_descriptions[component_name]
|
||||
# logger.debug(f"已禁用组件: {component_name} -> {namespaced_name}")
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def get_registry_stats(self) -> Dict[str, Any]:
|
||||
"""获取注册中心统计信息"""
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import subprocess
|
||||
import sys
|
||||
import importlib
|
||||
from typing import List, Dict, Tuple
|
||||
from typing import List, Dict, Tuple, Any
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.base.component_types import PythonDependency
|
||||
@@ -176,7 +176,7 @@ class DependencyManager:
|
||||
logger.error(f"生成requirements文件失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def get_install_summary(self) -> Dict[str, any]:
|
||||
def get_install_summary(self) -> Dict[str, Any]:
|
||||
"""获取安装摘要"""
|
||||
return {
|
||||
"install_log": self.install_log.copy(),
|
||||
|
||||
@@ -197,29 +197,29 @@ class PluginManager:
|
||||
"""获取所有启用的插件信息"""
|
||||
return list(component_registry.get_enabled_plugins().values())
|
||||
|
||||
def enable_plugin(self, plugin_name: str) -> bool:
|
||||
# -------------------------------- NEED REFACTORING --------------------------------
|
||||
"""启用插件"""
|
||||
if plugin_info := component_registry.get_plugin_info(plugin_name):
|
||||
plugin_info.enabled = True
|
||||
# 启用插件的所有组件
|
||||
for component in plugin_info.components:
|
||||
component_registry.enable_component(component.name)
|
||||
logger.debug(f"已启用插件: {plugin_name}")
|
||||
return True
|
||||
return False
|
||||
# def enable_plugin(self, plugin_name: str) -> bool:
|
||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
||||
# """启用插件"""
|
||||
# if plugin_info := component_registry.get_plugin_info(plugin_name):
|
||||
# plugin_info.enabled = True
|
||||
# # 启用插件的所有组件
|
||||
# for component in plugin_info.components:
|
||||
# component_registry.enable_component(component.name)
|
||||
# logger.debug(f"已启用插件: {plugin_name}")
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def disable_plugin(self, plugin_name: str) -> bool:
|
||||
# -------------------------------- NEED REFACTORING --------------------------------
|
||||
"""禁用插件"""
|
||||
if plugin_info := component_registry.get_plugin_info(plugin_name):
|
||||
plugin_info.enabled = False
|
||||
# 禁用插件的所有组件
|
||||
for component in plugin_info.components:
|
||||
component_registry.disable_component(component.name)
|
||||
logger.debug(f"已禁用插件: {plugin_name}")
|
||||
return True
|
||||
return False
|
||||
# def disable_plugin(self, plugin_name: str) -> bool:
|
||||
# # -------------------------------- NEED REFACTORING --------------------------------
|
||||
# """禁用插件"""
|
||||
# if plugin_info := component_registry.get_plugin_info(plugin_name):
|
||||
# plugin_info.enabled = False
|
||||
# # 禁用插件的所有组件
|
||||
# for component in plugin_info.components:
|
||||
# component_registry.disable_component(component.name)
|
||||
# logger.debug(f"已禁用插件: {plugin_name}")
|
||||
# return True
|
||||
# return False
|
||||
|
||||
def get_plugin_instance(self, plugin_name: str) -> Optional["PluginBase"]:
|
||||
"""获取插件实例
|
||||
|
||||
Reference in New Issue
Block a user