新增了插件相关的完整领域模型、应用服务、基础设施实现,包括: 1. 插件状态、注册模式、来源等基础枚举和数据结构 2. 插件清单解析、发现、加载工具类 3. 插件注册表领域服务和内存存储实现 4. 插件相关的命令、查询、事件定义 5. 插件REST API接口和DTO映射 6. 集成了原有通道适配器到插件系统 7. 新增内置插件注册和自动发现能力
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
from dataclasses import dataclass
|
|
|
|
from yuxi.channel.domain.exception.plugin_exception import InvalidManifestException
|
|
from yuxi.channel.domain.model.plugin_registry.plugin_manifest import PluginManifest
|
|
from yuxi.channel.domain.model.shared.channel_capabilities import ChannelCapabilities
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@dataclass
|
|
class ManifestParseResult:
|
|
manifest: PluginManifest
|
|
raw: dict
|
|
|
|
|
|
class ManifestParser:
|
|
def parse(self, data: dict) -> ManifestParseResult:
|
|
try:
|
|
plugin_id = data.get("id", "")
|
|
name = data.get("name", "")
|
|
version = data.get("version", "0.0.0")
|
|
channel_type = data.get("channel_type", "")
|
|
entry = data.get("entry", "")
|
|
dependencies = data.get("dependencies", [])
|
|
config_schema = data.get("config_schema", None)
|
|
|
|
caps_data = data.get("capabilities", {})
|
|
capabilities = ChannelCapabilities(
|
|
media=caps_data.get("media", False),
|
|
group=caps_data.get("group", False),
|
|
dm=caps_data.get("dm", True),
|
|
streaming=caps_data.get("streaming", False),
|
|
typing=caps_data.get("typing", False),
|
|
reaction=caps_data.get("reaction", False),
|
|
thread=caps_data.get("thread", False),
|
|
max_text_length=caps_data.get("max_text_length", 4096),
|
|
)
|
|
|
|
manifest = PluginManifest(
|
|
id=plugin_id,
|
|
name=name,
|
|
version=version,
|
|
channel_type=channel_type,
|
|
capabilities=capabilities,
|
|
config_schema=config_schema,
|
|
entry=entry,
|
|
dependencies=dependencies,
|
|
)
|
|
|
|
return ManifestParseResult(manifest=manifest, raw=data)
|
|
except InvalidManifestException:
|
|
raise
|
|
except Exception as exc:
|
|
raise InvalidManifestException(str(exc)) from exc
|
|
|
|
async def parse_file(self, path: str) -> ManifestParseResult:
|
|
try:
|
|
import yaml
|
|
|
|
with open(path) as f:
|
|
data = yaml.safe_load(f) or {}
|
|
except FileNotFoundError as exc:
|
|
raise InvalidManifestException(f"manifest file not found: {path}") from exc
|
|
except Exception as exc:
|
|
raise InvalidManifestException(f"failed to parse manifest: {exc}") from exc
|
|
|
|
return self.parse(data)
|