refactor(plugin_system): 将依赖检查逻辑从插件基类移至插件管理器

将插件的Python包依赖和插件间依赖的检查逻辑,从各个插件实例的初始化阶段 (`PluginBase`),统一前置到插件模块加载阶段 (`PluginManager`)。

这一重构有以下好处:
- **提前失败 (Fail-fast)**:在加载插件模块时立即检查依赖,如果依赖不满足,则直接跳过该插件的加载和实例化,避免了不必要的资源消耗和后续的运行时错误。
- **职责单一**: `PluginManager` 负责插件的发现、加载和依赖管理,而 `PluginBase` 更专注于插件自身的业务逻辑和生命周期,使得代码结构更清晰。
- **配置中心化**: 依赖关系现在统一在 `__plugin_meta__` 中声明,而不是分散在插件类的属性中,提高了可维护性。
- **简化插件实现**: 插件开发者不再需要在插件类中定义 `dependencies` 和 `python_dependencies` 属性,只需在 `__init__.py` 中声明元数据即可。
This commit is contained in:
minecraft1024a
2025-10-24 19:08:07 +08:00
parent c656690a1e
commit 1700bdbb42
10 changed files with 82 additions and 114 deletions

View File

@@ -1,5 +1,6 @@
from src.plugin_system.base.plugin_metadata import PluginMetadata
# 定义插件元数据
__plugin_meta__ = PluginMetadata(
name="MoFox-Bot工具箱",
description="一个集合多种实用功能的插件,旨在提升聊天体验和效率。",
@@ -11,4 +12,6 @@ __plugin_meta__ = PluginMetadata(
keywords=["emoji", "reaction", "like", "表情", "回应", "点赞"],
categories=["Chat", "Integration"],
extra={"is_built_in": "true", "plugin_type": "functional"},
dependencies=[],
python_dependencies=["httpx", "Pillow"],
)

View File

@@ -13,5 +13,6 @@ __plugin_meta__ = PluginMetadata(
extra={
"is_built_in": False,
"plugin_type": "tools",
}
},
python_dependencies = ["aiohttp", "soundfile", "pedalboard"]
)

View File

@@ -30,7 +30,6 @@ class TTSVoicePlugin(BasePlugin):
plugin_author = "Kilo Code & 靚仔"
config_file_name = "config.toml"
dependencies = []
python_dependencies = ["aiohttp", "soundfile", "pedalboard"]
permission_nodes: list[PermissionNodeField] = [
PermissionNodeField(node_name="command.use", description="是否可以使用 /tts 命令"),

View File

@@ -1,3 +1,4 @@
from src.plugin_system.base.component_types import PythonDependency
from src.plugin_system.base.plugin_metadata import PluginMetadata
__plugin_meta__ = PluginMetadata(
@@ -13,4 +14,26 @@ __plugin_meta__ = PluginMetadata(
extra={
"is_built_in": True,
},
# Python包依赖列表
python_dependencies = [ # noqa: RUF012
PythonDependency(package_name="asyncddgs", description="异步DuckDuckGo搜索库", optional=False),
PythonDependency(
package_name="exa_py",
description="Exa搜索API客户端库",
optional=True, # 如果没有API密钥这个是可选的
),
PythonDependency(
package_name="tavily",
install_name="tavily-python", # 安装时使用这个名称
description="Tavily搜索API客户端库",
optional=True, # 如果没有API密钥这个是可选的
),
PythonDependency(
package_name="httpx",
version=">=0.20.0",
install_name="httpx[socks]", # 安装时使用这个名称(包含可选依赖)
description="支持SOCKS代理的HTTP客户端库",
optional=False,
),
]
)

View File

@@ -74,29 +74,6 @@ class WEBSEARCHPLUGIN(BasePlugin):
except Exception as e:
logger.error(f"❌ 搜索引擎初始化失败: {e}", exc_info=True)
# Python包依赖列表
python_dependencies: list[PythonDependency] = [ # noqa: RUF012
PythonDependency(package_name="asyncddgs", description="异步DuckDuckGo搜索库", optional=False),
PythonDependency(
package_name="exa_py",
description="Exa搜索API客户端库",
optional=True, # 如果没有API密钥这个是可选的
),
PythonDependency(
package_name="tavily",
install_name="tavily-python", # 安装时使用这个名称
description="Tavily搜索API客户端库",
optional=True, # 如果没有API密钥这个是可选的
),
PythonDependency(
package_name="httpx",
version=">=0.20.0",
install_name="httpx[socks]", # 安装时使用这个名称(包含可选依赖)
description="支持SOCKS代理的HTTP客户端库",
optional=False,
),
]
config_file_name: str = "config.toml" # 配置文件名
# 配置节描述