mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
3.4 KiB
3.4 KiB
Context
ABP 协议第一阶段完成了核心握手、传输层和事件系统。当前 OutOfProcessPluginLoader 已实现,但:
PluginLoadertrait 未定义,InProcess 模式缺失tools/list端点未实现,工具发现依赖它- Python FFI 绑定未完成,Python 层无法调用 Rust 核心
- 配置集成未落地,无 PluginRegistry
Goals / Non-Goals
Goals:
- 实现
PluginLoadertrait,统一进程内/外加载逻辑 - 实现
InProcessPluginLoader,Python 模块直接加载 - 实现
tools/list端点和工具 Schema 验证 - 完成 Python FFI 绑定链路
- 落地 config.yaml 插件配置和 PluginRegistry
Non-Goals:
- 不实现 Stars → ABP 插件迁移(下一阶段)
- 不实现 WebUI 插件配置界面(config.yaml 落地即可)
- 不改变 Rust 核心源码(仅调用已有接口)
Decisions
1. PluginLoader Trait 设计
决定:定义抽象 trait,包含 load()、unload()、reload()、get_plugin_info() 方法。
class PluginLoader(ABC):
@abstractmethod
async def load(self, config: PluginConfig) -> PluginInstance: ...
@abstractmethod
async def unload(self, plugin_id: str) -> None: ...
@abstractmethod
async def reload(self, plugin_id: str) -> PluginInstance: ...
替代方案:
- 工厂模式(被否定):增加抽象层级,当前场景不需要
- 统一接口参数(被否定):进程内/外行为差异大,分离更清晰
2. InProcessPluginLoader 实现
决定:Python 模块直接导入,插件实例化后存入 Dict[str, PluginInstance]。
理由:
- 无进程通信开销,性能最优
- 与项目 "Rust 核心 + Python 胶水层" 架构一致
- 插件需遵循
ABPPluginProtocol接口约定
3. 工具发现架构
决定:ToolRegistry 统一管理,tools/list 聚合所有插件工具。
ToolRegistry
├── register(plugin_id, tools)
├── unregister(plugin_id)
├── list_tools() -> List[ToolDef]
└── call_tool(name, args) -> ToolResult
理由:
- 中心化管理避免冲突
- Schema 验证在注册时执行
- 跨插件工具调用统一入口
4. FFI 绑定链路
决定:Python → Rust _core.so → ABP PluginLoader。
Python PluginManager
→ ctypes / cffi 调用 _core.so
→ Rust abp_plugin_loader_* 函数
→ 返回 Python 对象(通过 .pyi 类型提示)
理由:
- Rust 源码待提交,当前仅使用编译产物
_core.pyi提供类型检查- anyio 异步调用通过
run_in_executor封装
Risks / Trade-offs
| 风险 | 影响 | 缓解措施 |
|---|---|---|
| Rust 源码未提交,接口可能变 | FFI 调用失败 | 接口版本化,核心保持向后兼容 |
| InProcess 插件崩溃影响主进程 | 稳定性下降 | 进程内插件加超时保护 + 错误隔离 |
| 工具 Schema 验证复杂度 | 开发体验下降 | JSON Schema 仅校验格式,不校验业务逻辑 |
Migration Plan
- Phase 1:PluginLoader trait + InProcessPluginLoader(对现有 OutOfProcess 透明)
- Phase 2:tools/list + ToolRegistry
- Phase 3:FFI 绑定 + config.yaml 集成
- Phase 4:测试覆盖 + 文档
Open Questions
- Q1: InProcess 插件是否需要独立的沙箱隔离?(当前:无)
- Q2: 工具注册时 Schema 校验严格程度?(当前:格式校验 + 必需字段)
- Q3: PluginRegistry 是否需要持久化?(当前:内存,进程重启丢失)