ForcePilot/backend/package/yuxi/channels/contract/dtos/capability.py

213 lines
8.6 KiB
Python
Raw Normal View History

"""能力 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: 是否支持表情反应默认 FalseFR-12
supports_pin: 是否支持置顶默认 FalseFR-12
supports_card_update: 是否支持投递完成后的卡片刷新
``MessageOpsAdapter.updateCard``默认 FalseFR-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: 是否支持命令默认 FalseFR-15
directory: 是否支持目录查询默认 FalseFR-14
doctor: 是否支持配置诊断与自动修复默认 FalseFR-17
whitelist: 是否支持白名单管理默认 FalseFR-18
wizard: 是否支持配置向导默认 FalseFR-16声明为 True
时要求 ``wizard_adapters`` 非空
tools: 是否支持工具能力默认 FalseFR-12 工具暴露
声明为 True 时要求 ``tools_adapters`` 非空
status: 是否支持状态分类默认 False声明为 True 时要求
``status_adapters`` 非空未声明的渠道默认将所有事件
分类为 MESSAGE
probeable: 是否支持连接探测默认 FalseFR-17 探测
声明为 True 时要求 ``probeable_adapters`` 非空
identity_resolver: 是否支持身份解析适配器默认 False
``IdentityResolverPort`` 承载不在加载期校验范围
运行时由 ``CapabilityVerifier`` 证明
生命周期与协作能力
lifecycle: 是否实现账户生命周期适配器默认 FalseAL-01
supports_qr_login: 是否支持扫码登录默认 FalseQR-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")