mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
docs: remove SDK integration plan document
The SDK integration was reverted, remove the now-stale planning document.
This commit is contained in:
@@ -1,638 +0,0 @@
|
||||
# AstrBot SDK 接入实施计划
|
||||
|
||||
> 本文档基于用户 `whatevertogo` 的分析文档,补充具体实施细节。
|
||||
|
||||
## 一、架构验证结果
|
||||
|
||||
经代码审查确认:
|
||||
|
||||
| 组件 | 路径 | 状态 |
|
||||
|------|------|------|
|
||||
| Core Context | `astrbot/core/star/context.py` | ✅ 包含所有核心能力方法 |
|
||||
| CapabilityRouter | `src-new/astrbot_sdk/runtime/capability_router.py` | ✅ 已实现内置能力注册 |
|
||||
| StarHandlerMetadata | `astrbot/core/star/star_handler.py` | ✅ 定义清晰,可扩展 |
|
||||
| HandlerDescriptor | `src-new/astrbot_sdk/protocol/descriptors.py` | ✅ Pydantic 模型,类型安全 |
|
||||
| SupervisorRuntime | `src-new/astrbot_sdk/runtime/bootstrap.py` | ✅ 已实现完整生命周期 |
|
||||
| CoreLifecycle | `astrbot/core/core_lifecycle.py` | ✅ 接入点明确 |
|
||||
|
||||
---
|
||||
|
||||
## 二、实施阶段
|
||||
|
||||
### Phase 1: 基础桥接层 (预计 2-3 天)
|
||||
|
||||
#### 1.1 创建目录结构
|
||||
|
||||
```
|
||||
astrbot/core/sdk_bridge/
|
||||
├── __init__.py
|
||||
├── capability_bridge.py # CoreCapabilityBridge
|
||||
├── supervisor_bridge.py # SdkPluginBridge
|
||||
├── event_bridge.py # 事件转换
|
||||
├── handler_bridge.py # Handler 注册桥接
|
||||
└── transport_adapter.py # Transport 适配
|
||||
```
|
||||
|
||||
#### 1.2 实现 `capability_bridge.py`
|
||||
|
||||
```python
|
||||
"""CoreCapabilityBridge: 把 astrbot.core.Context 能力映射到 CapabilityRouter。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from astrbot.core.star.context import Context as CoreContext
|
||||
from astrbot_sdk.runtime.capability_router import CapabilityRouter
|
||||
|
||||
logger = logging.getLogger("astrbot.sdk_bridge")
|
||||
|
||||
|
||||
class CoreCapabilityBridge:
|
||||
"""把 astrbot.core.Context 的真实实现注入进 SDK CapabilityRouter。
|
||||
|
||||
SupervisorRuntime 初始化后,Core 侧的 Peer 调用此 Bridge 来响应插件发来的能力请求。
|
||||
"""
|
||||
|
||||
def __init__(self, core_context: CoreContext, router: CapabilityRouter) -> None:
|
||||
self.ctx = core_context
|
||||
self.router = router
|
||||
self._wire()
|
||||
|
||||
def _wire(self) -> None:
|
||||
"""注册所有能力处理器到 router。"""
|
||||
# 替换 router 的内置 echo 实现为真实实现
|
||||
self._wire_llm()
|
||||
self._wire_db()
|
||||
self._wire_platform()
|
||||
self._wire_memory()
|
||||
self._wire_metadata()
|
||||
logger.info("SDK CapabilityBridge 已连接")
|
||||
|
||||
def _wire_llm(self) -> None:
|
||||
"""连接 LLM 能力。"""
|
||||
async def llm_chat(request_id: str, payload: dict[str, Any], _token) -> dict[str, Any]:
|
||||
# 从 payload 提取参数
|
||||
prompt = payload.get("prompt", "")
|
||||
provider_id = payload.get("provider_id")
|
||||
# 调用 core 的 llm_generate
|
||||
if provider_id:
|
||||
resp = await self.ctx.llm_generate(
|
||||
chat_provider_id=provider_id,
|
||||
prompt=prompt,
|
||||
# ... 其他参数
|
||||
)
|
||||
else:
|
||||
# 使用默认 provider
|
||||
prov = self.ctx.get_using_provider()
|
||||
if prov:
|
||||
resp = await self.ctx.llm_generate(
|
||||
chat_provider_id=prov.meta().id,
|
||||
prompt=prompt,
|
||||
)
|
||||
else:
|
||||
return {"text": f"Echo (no provider): {prompt}"}
|
||||
return {"text": resp.completion_text or ""}
|
||||
|
||||
# 注册到 router (覆盖默认 echo 实现)
|
||||
self.router.unregister("llm.chat")
|
||||
self.router.register(
|
||||
self.router._registrations["llm.chat"].descriptor, # 复用 descriptor
|
||||
call_handler=llm_chat,
|
||||
)
|
||||
|
||||
def _wire_db(self) -> None:
|
||||
"""连接数据库能力。"""
|
||||
async def db_get(request_id: str, payload: dict[str, Any], _token) -> dict[str, Any]:
|
||||
key = str(payload.get("key", ""))
|
||||
# 使用 core 的数据库
|
||||
db = self.ctx.get_db()
|
||||
value = await db.get(key)
|
||||
return {"value": value}
|
||||
|
||||
async def db_set(request_id: str, payload: dict[str, Any], _token) -> dict[str, Any]:
|
||||
key = str(payload.get("key", ""))
|
||||
value = payload.get("value")
|
||||
db = self.ctx.get_db()
|
||||
await db.set(key, value)
|
||||
return {}
|
||||
|
||||
# 覆盖注册
|
||||
self.router.unregister("db.get")
|
||||
self.router.unregister("db.set")
|
||||
# ... 类似注册其他 db 方法
|
||||
|
||||
def _wire_platform(self) -> None:
|
||||
"""连接平台消息发送能力。"""
|
||||
async def platform_send(request_id: str, payload: dict[str, Any], _token) -> dict[str, Any]:
|
||||
from astrbot.core.platform.astr_message_event import MessageSesion
|
||||
from astrbot.core.message.message_event_result import MessageChain
|
||||
|
||||
session_str = payload.get("session", "")
|
||||
text = payload.get("text", "")
|
||||
|
||||
# 构建 MessageChain
|
||||
chain = MessageChain().message(text)
|
||||
|
||||
# 调用 core 的 send_message
|
||||
success = await self.ctx.send_message(session_str, chain)
|
||||
return {"message_id": f"msg_{request_id}", "success": success}
|
||||
|
||||
self.router.unregister("platform.send")
|
||||
self.router.register(
|
||||
self.router._registrations["platform.send"].descriptor,
|
||||
call_handler=platform_send,
|
||||
)
|
||||
|
||||
def _wire_memory(self) -> None:
|
||||
"""连接记忆/会话管理能力。"""
|
||||
async def memory_save(request_id: str, payload: dict[str, Any], _token) -> dict[str, Any]:
|
||||
# 使用 conversation_manager
|
||||
key = str(payload.get("key", ""))
|
||||
value = payload.get("value")
|
||||
# 实现具体逻辑
|
||||
return {}
|
||||
|
||||
# 注册...
|
||||
|
||||
def _wire_metadata(self) -> None:
|
||||
"""连接插件元数据能力。"""
|
||||
# metadata.get_config -> context.get_config()
|
||||
# metadata.get_star -> star_registry 查询
|
||||
pass
|
||||
```
|
||||
|
||||
#### 1.3 实现 `event_bridge.py`
|
||||
|
||||
```python
|
||||
"""事件双向转换模块。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from astrbot.core.platform.astr_message_event import AstrMessageEvent
|
||||
|
||||
|
||||
def astr_event_to_sdk_payload(event: AstrMessageEvent) -> dict[str, Any]:
|
||||
"""把旧版 AstrMessageEvent 转成 SDK MessageEvent 的 to_payload() 格式。"""
|
||||
return {
|
||||
"text": event.message_str,
|
||||
"user_id": event.get_sender_id(),
|
||||
"group_id": event.get_group_id() if event.is_group_message() else None,
|
||||
"platform": event.get_platform_name(),
|
||||
"session_id": event.unified_msg_origin,
|
||||
"target": {
|
||||
"conversation_id": event.unified_msg_origin,
|
||||
"platform": event.get_platform_name(),
|
||||
},
|
||||
# 保留原始消息对象引用
|
||||
"_raw_message_obj": event.message_obj,
|
||||
"_raw_platform_meta": event.platform_meta,
|
||||
# 保留原始 event 引用,供后续处理
|
||||
"_core_event": event,
|
||||
}
|
||||
|
||||
|
||||
def sdk_payload_to_event_context(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
"""从 SDK payload 提取事件上下文信息。"""
|
||||
return {
|
||||
"session": payload.get("session_id", ""),
|
||||
"user_id": payload.get("user_id"),
|
||||
"group_id": payload.get("group_id"),
|
||||
"platform": payload.get("platform"),
|
||||
"text": payload.get("text"),
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.4 实现 `handler_bridge.py`
|
||||
|
||||
```python
|
||||
"""Handler 注册桥接:把 SDK HandlerDescriptor 转换为 StarHandlerMetadata。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from collections.abc import Awaitable
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
from astrbot.core.star.filter import HandlerFilter
|
||||
from astrbot.core.star.star_handler import EventType, StarHandlerMetadata
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from astrbot_sdk.protocol.descriptors import HandlerDescriptor
|
||||
from astrbot_sdk.runtime.bootstrap import WorkerSession
|
||||
|
||||
logger = logging.getLogger("astrbot.sdk_bridge")
|
||||
|
||||
|
||||
# SDK 事件类型到 Core 事件类型的映射
|
||||
TRIGGER_TO_EVENT_TYPE = {
|
||||
"message": EventType.AdapterMessageEvent,
|
||||
"command": EventType.AdapterMessageEvent,
|
||||
"event": EventType.AdapterMessageEvent, # 需要根据具体 event_type 细分
|
||||
"schedule": EventType.OnAstrBotLoadedEvent, # 定时任务特殊处理
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class SdkHandlerWrapper:
|
||||
"""包装 SDK handler 的调用闭包。"""
|
||||
session: WorkerSession
|
||||
handler_id: str
|
||||
|
||||
async def __call__(self, *args, **kwargs) -> Any:
|
||||
"""调用 SDK handler。"""
|
||||
# 从 args/kwargs 提取事件信息
|
||||
event = kwargs.get("event") or (args[0] if args else None)
|
||||
if event is None:
|
||||
raise ValueError("SDK handler 需要 event 参数")
|
||||
|
||||
# 转换事件格式
|
||||
from .event_bridge import astr_event_to_sdk_payload
|
||||
payload = astr_event_to_sdk_payload(event)
|
||||
|
||||
# 通过 session 调用远程 handler
|
||||
return await self.session.invoke_handler(self.handler_id, payload)
|
||||
|
||||
|
||||
def handler_descriptor_to_metadata(
|
||||
descriptor: HandlerDescriptor,
|
||||
session: WorkerSession,
|
||||
) -> StarHandlerMetadata:
|
||||
"""把 SDK HandlerDescriptor 转换为 Core 的 StarHandlerMetadata。
|
||||
|
||||
Args:
|
||||
descriptor: SDK handler 描述符
|
||||
session: Worker 会话,用于调用远程 handler
|
||||
|
||||
Returns:
|
||||
StarHandlerMetadata: Core 兼容的 handler 元数据
|
||||
"""
|
||||
# 创建包装器
|
||||
wrapper = SdkHandlerWrapper(session=session, handler_id=descriptor.id)
|
||||
|
||||
# 确定 Core 事件类型
|
||||
trigger = descriptor.trigger
|
||||
event_type = TRIGGER_TO_EVENT_TYPE.get(trigger.type, EventType.AdapterMessageEvent)
|
||||
|
||||
# 构建 event_filters
|
||||
event_filters = _build_event_filters(trigger)
|
||||
|
||||
# 构建 extras_configs
|
||||
extras_configs = {
|
||||
"priority": descriptor.priority,
|
||||
"require_admin": descriptor.permissions.require_admin,
|
||||
"level": descriptor.permissions.level,
|
||||
"sdk_handler": True, # 标记为 SDK handler
|
||||
}
|
||||
|
||||
# 解析 handler_full_name
|
||||
parts = descriptor.id.rsplit(".", 1)
|
||||
if len(parts) == 2:
|
||||
module_path, handler_name = parts
|
||||
else:
|
||||
module_path = descriptor.id
|
||||
handler_name = descriptor.id
|
||||
|
||||
return StarHandlerMetadata(
|
||||
event_type=event_type,
|
||||
handler_full_name=descriptor.id,
|
||||
handler_name=handler_name,
|
||||
handler_module_path=module_path,
|
||||
handler=wrapper, # 使用包装器
|
||||
event_filters=event_filters,
|
||||
desc=getattr(trigger, "description", "") or "",
|
||||
extras_configs=extras_configs,
|
||||
)
|
||||
|
||||
|
||||
def _build_event_filters(trigger: Any) -> list[HandlerFilter]:
|
||||
"""根据 trigger 类型构建事件过滤器。"""
|
||||
from astrbot.core.star.filter.command import CommandFilter
|
||||
from astrbot.core.star.filter.regex import RegexFilter
|
||||
|
||||
filters: list[HandlerFilter] = []
|
||||
|
||||
if trigger.type == "command":
|
||||
# 命令触发器 -> CommandFilter
|
||||
filters.append(CommandFilter(
|
||||
command_name=trigger.command,
|
||||
# handler_md 需要稍后设置
|
||||
))
|
||||
elif trigger.type == "message":
|
||||
# 消息触发器 -> RegexFilter
|
||||
if trigger.regex:
|
||||
filters.append(RegexFilter(regex=trigger.regex))
|
||||
# keywords 过滤需要在运行时检查
|
||||
|
||||
return filters
|
||||
```
|
||||
|
||||
#### 1.5 实现 `supervisor_bridge.py`
|
||||
|
||||
```python
|
||||
"""SdkPluginBridge: 在 Core 侧管理 SupervisorRuntime。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from astrbot.core.star.context import Context as CoreContext
|
||||
|
||||
logger = logging.getLogger("astrbot.sdk_bridge")
|
||||
|
||||
|
||||
class SdkPluginBridge:
|
||||
"""在 Core 侧管理 SupervisorRuntime,并把 SDK handler 注册进 pipeline。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
core_context: CoreContext,
|
||||
sdk_plugins_dir: Path,
|
||||
) -> None:
|
||||
from astrbot_sdk.runtime.capability_router import CapabilityRouter
|
||||
from astrbot_sdk.runtime.bootstrap import SupervisorRuntime
|
||||
from astrbot_sdk.transport.stdio import StdioTransport
|
||||
|
||||
self.ctx = core_context
|
||||
self.plugins_dir = sdk_plugins_dir
|
||||
|
||||
# 创建 CapabilityRouter 和 Bridge
|
||||
self.capability_router = CapabilityRouter()
|
||||
self.capability_bridge = None # 延迟初始化
|
||||
|
||||
# 创建 Transport (使用 stdio 进行进程间通信)
|
||||
self.transport = StdioTransport()
|
||||
|
||||
# 创建 Supervisor
|
||||
self.supervisor = SupervisorRuntime(
|
||||
transport=self.transport,
|
||||
plugins_dir=sdk_plugins_dir,
|
||||
)
|
||||
|
||||
# 已注册的 handler 映射
|
||||
self._registered_handlers: dict[str, str] = {} # handler_id -> plugin_name
|
||||
|
||||
async def start(self) -> None:
|
||||
"""启动 SDK 插件桥接。"""
|
||||
# 初始化 CapabilityBridge (替换默认 echo 实现)
|
||||
from .capability_bridge import CoreCapabilityBridge
|
||||
self.capability_bridge = CoreCapabilityBridge(self.ctx, self.capability_router)
|
||||
|
||||
# 启动 Supervisor
|
||||
await self.supervisor.start()
|
||||
|
||||
# 注册所有 handler 到 pipeline
|
||||
self._register_handlers_into_pipeline()
|
||||
|
||||
logger.info(f"SDK 插件桥接已启动,共加载 {len(self._registered_handlers)} 个 handler")
|
||||
|
||||
async def stop(self) -> None:
|
||||
"""停止 SDK 插件桥接。"""
|
||||
await self.supervisor.stop()
|
||||
self._registered_handlers.clear()
|
||||
logger.info("SDK 插件桥接已停止")
|
||||
|
||||
def _register_handlers_into_pipeline(self) -> None:
|
||||
"""把 supervisor 聚合的所有 HandlerDescriptor 注册进 star_handlers_registry。"""
|
||||
from astrbot.core.star.star_handler import star_handlers_registry
|
||||
|
||||
from .handler_bridge import handler_descriptor_to_metadata
|
||||
|
||||
for handler_id, session in self.supervisor.handler_to_worker.items():
|
||||
# 获取 handler 的 descriptor
|
||||
descriptor = self._get_handler_descriptor(handler_id)
|
||||
if descriptor is None:
|
||||
logger.warning(f"无法获取 handler descriptor: {handler_id}")
|
||||
continue
|
||||
|
||||
# 转换为 StarHandlerMetadata
|
||||
metadata = handler_descriptor_to_metadata(descriptor, session)
|
||||
|
||||
# 注册到全局 registry
|
||||
star_handlers_registry.append(metadata)
|
||||
|
||||
self._registered_handlers[handler_id] = descriptor.id.split(".")[0]
|
||||
logger.debug(f"注册 SDK handler: {handler_id}")
|
||||
|
||||
def _get_handler_descriptor(self, handler_id: str):
|
||||
"""从 supervisor 获取 handler descriptor。"""
|
||||
# 遍历所有 session 的 loaded_plugin 找到对应的 handler
|
||||
for plugin_id, session in self.supervisor._plugin_sessions.items():
|
||||
if session.loaded_plugin:
|
||||
for handler in session.loaded_plugin.handlers:
|
||||
if handler.id == handler_id:
|
||||
return handler
|
||||
return None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: 生命周期集成 (预计 1 天)
|
||||
|
||||
#### 2.1 修改 `core_lifecycle.py`
|
||||
|
||||
```python
|
||||
# 在 CoreLifecycle 类中添加
|
||||
|
||||
def __init__(self, ...):
|
||||
# ... 现有代码 ...
|
||||
self.sdk_bridge: SdkPluginBridge | None = None
|
||||
|
||||
async def initialize(self) -> None:
|
||||
# ... 现有初始化代码 ...
|
||||
|
||||
# 在 PluginManager 初始化后,初始化 SDK Bridge
|
||||
if self.astrbot_config.get("enable_sdk_plugins", False):
|
||||
from pathlib import Path
|
||||
from astrbot.core.sdk_bridge.supervisor_bridge import SdkPluginBridge
|
||||
|
||||
sdk_plugins_dir = Path("data/sdk_plugins")
|
||||
sdk_plugins_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self.sdk_bridge = SdkPluginBridge(
|
||||
core_context=self.star_context,
|
||||
sdk_plugins_dir=sdk_plugins_dir,
|
||||
)
|
||||
|
||||
async def start(self) -> None:
|
||||
self._load()
|
||||
|
||||
# 启动 SDK Bridge
|
||||
if self.sdk_bridge:
|
||||
await self.sdk_bridge.start()
|
||||
logger.info("SDK 插件桥接启动完成")
|
||||
|
||||
# ... 现有代码 ...
|
||||
|
||||
async def stop(self) -> None:
|
||||
# 停止 SDK Bridge
|
||||
if self.sdk_bridge:
|
||||
await self.sdk_bridge.stop()
|
||||
|
||||
# ... 现有代码 ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: 测试与验证 (预计 2 天)
|
||||
|
||||
#### 3.1 单元测试
|
||||
|
||||
```python
|
||||
# tests/test_sdk_bridge.py
|
||||
|
||||
import pytest
|
||||
from astrbot.core.sdk_bridge.capability_bridge import CoreCapabilityBridge
|
||||
from astrbot.core.sdk_bridge.event_bridge import astr_event_to_sdk_payload
|
||||
from astrbot.core.sdk_bridge.handler_bridge import handler_descriptor_to_metadata
|
||||
|
||||
|
||||
class TestEventBridge:
|
||||
def test_astr_event_to_sdk_payload(self, mock_event):
|
||||
payload = astr_event_to_sdk_payload(mock_event)
|
||||
assert payload["text"] == mock_event.message_str
|
||||
assert payload["user_id"] == mock_event.get_sender_id()
|
||||
assert "_core_event" in payload
|
||||
|
||||
|
||||
class TestCapabilityBridge:
|
||||
async def test_llm_chat_capability(self, mock_core_context, mock_router):
|
||||
bridge = CoreCapabilityBridge(mock_core_context, mock_router)
|
||||
# 验证 llm.chat 已被覆盖
|
||||
assert "llm.chat" in mock_router._registrations
|
||||
|
||||
|
||||
class TestHandlerBridge:
|
||||
def test_command_handler_conversion(self, mock_descriptor, mock_session):
|
||||
metadata = handler_descriptor_to_metadata(mock_descriptor, mock_session)
|
||||
assert metadata.handler_full_name == mock_descriptor.id
|
||||
assert len(metadata.event_filters) > 0
|
||||
```
|
||||
|
||||
#### 3.2 集成测试
|
||||
|
||||
```python
|
||||
# tests/integration/test_sdk_integration.py
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def sdk_bridge(test_context, tmp_path):
|
||||
from astrbot.core.sdk_bridge.supervisor_bridge import SdkPluginBridge
|
||||
|
||||
bridge = SdkPluginBridge(
|
||||
core_context=test_context,
|
||||
sdk_plugins_dir=tmp_path / "sdk_plugins",
|
||||
)
|
||||
await bridge.start()
|
||||
yield bridge
|
||||
await bridge.stop()
|
||||
|
||||
|
||||
async def test_sdk_plugin_loading(sdk_bridge):
|
||||
"""测试 SDK 插件能被正确加载。"""
|
||||
assert len(sdk_bridge._registered_handlers) > 0
|
||||
|
||||
|
||||
async def test_sdk_handler_invocation(sdk_bridge, mock_event):
|
||||
"""测试 SDK handler 能被正确调用。"""
|
||||
from astrbot.core.star.star_handler import star_handlers_registry
|
||||
|
||||
# 查找 SDK 注册的 handler
|
||||
handlers = [h for h in star_handlers_registry if h.extras_configs.get("sdk_handler")]
|
||||
assert len(handlers) > 0
|
||||
|
||||
# 调用 handler
|
||||
handler = handlers[0]
|
||||
result = await handler.handler(event=mock_event)
|
||||
# 验证结果
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: 配置与文档 (预计 1 天)
|
||||
|
||||
#### 4.1 配置项
|
||||
|
||||
```yaml
|
||||
# config/astrbot_config.yaml
|
||||
sdk_plugins:
|
||||
enabled: true
|
||||
plugins_dir: "data/sdk_plugins"
|
||||
worker_timeout: 30 # Worker 启动超时(秒)
|
||||
max_restarts: 3 # Worker 崩溃后最大重启次数
|
||||
```
|
||||
|
||||
#### 4.2 用户文档
|
||||
|
||||
创建 `docs/sdk_plugin_development.md`,说明:
|
||||
- SDK 插件目录结构
|
||||
- `plugin.yaml` 配置格式
|
||||
- Handler 注册方式
|
||||
- Capability 调用示例
|
||||
|
||||
---
|
||||
|
||||
## 三、能力映射详细表
|
||||
|
||||
| SDK Capability | Core Context 方法 | 实现状态 |
|
||||
|----------------|------------------|----------|
|
||||
| `llm.chat` | `context.llm_generate()` | 待实现 |
|
||||
| `llm.chat_raw` | `context.llm_generate()` | 待实现 |
|
||||
| `llm.stream_chat` | `context.llm_generate()` + stream | 待实现 |
|
||||
| `db.get` | `context.get_db().get()` | 待实现 |
|
||||
| `db.set` | `context.get_db().set()` | 待实现 |
|
||||
| `db.delete` | `context.get_db().delete()` | 待实现 |
|
||||
| `db.list` | `context.get_db().list()` | 待实现 |
|
||||
| `platform.send` | `context.send_message()` | 待实现 |
|
||||
| `platform.send_image` | `context.send_message()` + image | 待实现 |
|
||||
| `platform.send_chain` | `context.send_message()` | 待实现 |
|
||||
| `memory.search` | `context.conversation_manager.*` | 待实现 |
|
||||
| `memory.save` | `context.conversation_manager.*` | 待实现 |
|
||||
| `metadata.get_config` | `context.get_config()` | 待实现 |
|
||||
| `metadata.get_star` | `star_registry` 查询 | 待实现 |
|
||||
|
||||
---
|
||||
|
||||
## 四、风险与缓解措施
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| Worker 进程崩溃 | 插件不可用 | 实现自动重启机制 |
|
||||
| 事件格式不兼容 | 功能异常 | 完善事件转换层 |
|
||||
| 性能下降 | 用户体验变差 | 优化序列化,考虑共享内存 |
|
||||
| 旧插件迁移成本 | 用户流失 | 保持 legacy 兼容层 |
|
||||
|
||||
---
|
||||
|
||||
## 五、后续优化
|
||||
|
||||
1. **Worker 崩溃重启**:在 `SupervisorRuntime` 中添加指数退避重启机制
|
||||
2. **性能优化**:考虑使用共享内存传输大消息
|
||||
3. **调试支持**:添加 SDK 插件调试模式
|
||||
4. **热重载**:支持 SDK 插件热更新
|
||||
|
||||
---
|
||||
|
||||
## 六、实施检查清单
|
||||
|
||||
- [ ] 创建 `astrbot/core/sdk_bridge/` 目录
|
||||
- [ ] 实现 `capability_bridge.py`
|
||||
- [ ] 实现 `event_bridge.py`
|
||||
- [ ] 实现 `handler_bridge.py`
|
||||
- [ ] 实现 `supervisor_bridge.py`
|
||||
- [ ] 修改 `core_lifecycle.py` 集成
|
||||
- [ ] 添加配置项
|
||||
- [ ] 编写单元测试
|
||||
- [ ] 编写集成测试
|
||||
- [ ] 编写用户文档
|
||||
- [ ] 处理 `legacy_adapter.py` 死代码
|
||||
- [ ] 给 `CommandComponent` 添加 DeprecationWarning
|
||||
Reference in New Issue
Block a user