本次提交包含多维度代码优化与功能增强: 1. 移除报告模块冗余导入与枚举,清理报表相关代码 2. 新增扫码登录支持方法与飞书适配器适配 3. 完善异常日志与健康检查信息 4. 扩展目录、配对管理、能力查询等接口 5. 优化出站管道与事务提交后钩子逻辑 6. 修复飞书消息解析与响应空值问题 7. 重构配置更新与服务账号创建逻辑 8. 统一传输错误分类契约与错误基类扩展
213 lines
8.6 KiB
Python
213 lines
8.6 KiB
Python
"""能力 DTO。
|
||
|
||
定义渠道能力相关的不可变值对象,包括渠道能力集合与能力探测结果。
|
||
所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库,用于渠道
|
||
能力声明、探测与降级决策。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from enum import StrEnum
|
||
|
||
from yuxi.channels.contract.dtos.channel import ChannelType
|
||
from yuxi.channels.contract.dtos.config import ConfigField
|
||
from yuxi.channels.contract.errors import ValidationError
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class ChannelCapabilities:
|
||
"""渠道能力集合。
|
||
|
||
描述渠道支持的能力集合,全部为 ``bool`` 类型的能力声明字段,用于
|
||
适配器能力声明与降级决策。
|
||
|
||
字段(按语义分组):
|
||
基础消息能力:
|
||
rich_message: 是否支持富消息(默认 False)。
|
||
streaming: 是否支持流式输出(默认 False)。
|
||
typing_indicator: 是否支持输入指示(默认 False)。由出站
|
||
适配器承载,不在加载期校验范围,运行时由
|
||
``CapabilityVerifier`` 证明。
|
||
message_edit: 是否支持消息编辑(默认 False)。
|
||
message_recall: 是否支持消息撤回(默认 False)。
|
||
|
||
消息操作子能力(任一为 True 时要求 ``message_ops_adapters`` 非空):
|
||
supports_reaction: 是否支持表情反应(默认 False,FR-12)。
|
||
supports_pin: 是否支持置顶(默认 False,FR-12)。
|
||
supports_card_update: 是否支持投递完成后的卡片刷新
|
||
(``MessageOpsAdapter.updateCard``,默认 False,FR-12)。
|
||
**不** 涵盖流式输出过程中的渐进式卡片更新,后者由
|
||
``supports_card_update_streaming`` 声明。
|
||
supports_card_update_streaming: 是否支持流式输出过程中的
|
||
渐进式卡片更新(``StreamingAdapter.updateFullCard`` /
|
||
``updatePartialCard``,默认 False)。声明为 True 时要求
|
||
``streaming_adapters`` 非空。
|
||
|
||
媒体能力(FR-43):
|
||
supports_image_inbound: 是否支持入站图片(默认 False)。
|
||
supports_video_inbound: 是否支持入站视频(默认 False)。
|
||
supports_image_outbound: 是否支持出站图片(默认 False)。
|
||
supports_video_outbound: 是否支持出站视频(默认 False)。
|
||
|
||
扩展能力:
|
||
mention: 是否支持提及(默认 False)。
|
||
command: 是否支持命令(默认 False,FR-15)。
|
||
directory: 是否支持目录查询(默认 False,FR-14)。
|
||
doctor: 是否支持配置诊断与自动修复(默认 False,FR-17)。
|
||
whitelist: 是否支持白名单管理(默认 False,FR-18)。
|
||
wizard: 是否支持配置向导(默认 False,FR-16)。声明为 True
|
||
时要求 ``wizard_adapters`` 非空。
|
||
tools: 是否支持工具能力(默认 False,FR-12 工具暴露)。
|
||
声明为 True 时要求 ``tools_adapters`` 非空。
|
||
status: 是否支持状态分类(默认 False)。声明为 True 时要求
|
||
``status_adapters`` 非空;未声明的渠道默认将所有事件
|
||
分类为 MESSAGE。
|
||
probeable: 是否支持连接探测(默认 False,FR-17 探测)。
|
||
声明为 True 时要求 ``probeable_adapters`` 非空。
|
||
identity_resolver: 是否支持身份解析适配器(默认 False)。
|
||
由 ``IdentityResolverPort`` 承载,不在加载期校验范围,
|
||
运行时由 ``CapabilityVerifier`` 证明。
|
||
|
||
生命周期与协作能力:
|
||
lifecycle: 是否实现账户生命周期适配器(默认 False,AL-01)。
|
||
supports_qr_login: 是否支持扫码登录(默认 False,QR-02)。
|
||
agent_collaboration: 是否支持多 Agent 协作(默认 False,
|
||
FR-AgentCollab)。声明为 True 时要求 ``mention_adapters``
|
||
非空(FR-21 契约一致性)。
|
||
"""
|
||
|
||
# 基础消息能力
|
||
rich_message: bool = False
|
||
streaming: bool = False
|
||
typing_indicator: bool = False
|
||
message_edit: bool = False
|
||
message_recall: bool = False
|
||
# 消息操作子能力
|
||
supports_reaction: bool = False
|
||
supports_pin: bool = False
|
||
supports_card_update: bool = False
|
||
supports_card_update_streaming: bool = False
|
||
# 媒体能力(FR-43)
|
||
supports_image_inbound: bool = False
|
||
supports_video_inbound: bool = False
|
||
supports_image_outbound: bool = False
|
||
supports_video_outbound: bool = False
|
||
# 扩展能力
|
||
mention: bool = False
|
||
command: bool = False
|
||
directory: bool = False
|
||
doctor: bool = False
|
||
whitelist: bool = False
|
||
wizard: bool = False
|
||
tools: bool = False
|
||
status: bool = False
|
||
probeable: bool = False
|
||
identity_resolver: bool = False
|
||
# 生命周期与协作能力
|
||
lifecycle: bool = False
|
||
supports_qr_login: bool = False
|
||
agent_collaboration: bool = False
|
||
|
||
|
||
class RuntimeAvailability(StrEnum):
|
||
"""能力运行时可用性状态。
|
||
|
||
用于能力查询页区分"声明支持"与"实际可用":
|
||
available: 声明支持且依赖配置已满足。
|
||
unavailable: 声明支持但依赖配置缺失,实际不可用。
|
||
unknown: 声明支持但无法判断运行时状态(无依赖声明、依赖账户级配置
|
||
或未实现检测)。
|
||
unsupported: 声明不支持。
|
||
"""
|
||
|
||
AVAILABLE = "available"
|
||
UNAVAILABLE = "unavailable"
|
||
UNKNOWN = "unknown"
|
||
UNSUPPORTED = "unsupported"
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class CapabilityAvailabilityDetail:
|
||
"""单项能力运行时可用性详情。
|
||
|
||
补充 ``runtime_availability`` 的状态码,提供可解释的运行时推导结果,
|
||
供前端 tooltip 与详情面板展示缺失项与原因。
|
||
|
||
字段:
|
||
status: 运行时可用性状态。
|
||
missing_config_keys: 缺失或未有效配置的配置键清单。
|
||
missing_adapters: 缺失的适配器类型清单(如 directory/wizard)。
|
||
reason: 人类可读的原因说明(可选)。
|
||
"""
|
||
|
||
status: RuntimeAvailability
|
||
missing_config_keys: tuple[str, ...] = ()
|
||
missing_adapters: tuple[str, ...] = ()
|
||
reason: str | None = None
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class ChannelCapabilityProfile:
|
||
"""渠道能力画像。
|
||
|
||
聚合单个渠道的能力声明、运行时可用性、插件元数据与配置 schema,
|
||
供能力查询页矩阵/详情/对比视图一次性消费。
|
||
|
||
字段:
|
||
channel_type: 渠道类型。
|
||
display_name: 渠道显示名。
|
||
plugin_id: 插件 ID。
|
||
plugin_version: 插件版本。
|
||
plugin_state: 插件当前状态(如 started / paused / stopped)。
|
||
is_loaded: 是否已加载。
|
||
max_message_length: 单条消息最大长度。
|
||
capabilities: 静态能力声明集合。
|
||
runtime_availability: 运行时可用性映射,键为能力字段名,
|
||
值为 ``RuntimeAvailability``。
|
||
availability_details: 运行时可用性详情映射,键为能力字段名,
|
||
值为 ``CapabilityAvailabilityDetail``,解释状态原因与缺失项。
|
||
config_schema: 配置字段 schema 摘要。
|
||
"""
|
||
|
||
channel_type: ChannelType
|
||
display_name: str
|
||
plugin_id: str
|
||
plugin_version: str
|
||
plugin_state: str
|
||
is_loaded: bool
|
||
max_message_length: int
|
||
capabilities: ChannelCapabilities
|
||
runtime_availability: dict[str, RuntimeAvailability]
|
||
availability_details: dict[str, CapabilityAvailabilityDetail]
|
||
config_schema: tuple[ConfigField, ...]
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class CapabilityResult:
|
||
"""能力探测结果。
|
||
|
||
描述单项能力的探测结果,包括声明层、证明层与降级标记,用于能力
|
||
探测流程的决策与审计。
|
||
|
||
字段:
|
||
capability: 能力名称。
|
||
declared: 声明层是否支持。
|
||
proven: 证明层是否验证通过(默认 False)。
|
||
degraded: 是否降级(默认 False)。
|
||
"""
|
||
|
||
capability: str
|
||
declared: bool
|
||
proven: bool = False
|
||
degraded: bool = False
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 capability 非空。
|
||
|
||
``capability`` 必须非空,在构造时即抛出 ``ValidationError``,
|
||
避免空能力名称传播到探测决策(INV-8)。
|
||
"""
|
||
if not self.capability:
|
||
raise ValidationError("capability", "must not be empty")
|