本次提交包含多项代码优化与规范修正: 1. 文档与注释优化:修正注释术语、补充注解与FR编号 2. 代码格式调整:统一空格、换行与缩进规范 3. 类型与接口完善:补充__all__导出、修正返回类型注解 4. 错误处理增强:新增领域错误类与校验逻辑 5. 依赖与导入调整:修复路径引用、统一时区导入 6. 协议与契约更新:完善接口文档与一致性注解
178 lines
5.6 KiB
Python
178 lines
5.6 KiB
Python
"""提及 DTO。
|
||
|
||
定义消息提及的不可变值对象,包括提及类型、隐式提及类型、提及上下文、入站
|
||
提及策略、入站提及事实与提及决策。所有 DTO 均为 ``dataclass(frozen=True)``,
|
||
仅依赖标准库,用于提及检测与提及策略决策。集合字段使用 tuple 以保证
|
||
frozen dataclass 的不可变语义。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from enum import StrEnum
|
||
|
||
from yuxi.channels.contract.errors import ValidationError
|
||
|
||
|
||
class MentionType(StrEnum):
|
||
"""提及类型。
|
||
|
||
标识消息中提及机器人的方式,用于提及检测与策略决策。继承
|
||
``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
||
|
||
取值:
|
||
EXPLICIT: 显式 @提及。
|
||
IMPLICIT: 隐式提及(FR-29)。
|
||
NONE: 无提及。
|
||
"""
|
||
|
||
EXPLICIT = "explicit"
|
||
IMPLICIT = "implicit"
|
||
NONE = "none"
|
||
|
||
|
||
class ImplicitMentionKind(StrEnum):
|
||
"""隐式提及类型。
|
||
|
||
标识隐式提及的具体形式,用于提及策略的精细化匹配。继承
|
||
``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
||
|
||
取值:
|
||
REPLY_TO_BOT: 回复机器人。
|
||
QUOTED_BOT: 引用机器人。
|
||
BOT_THREAD_PARTICIPANT: 机器人话题参与者。
|
||
NATIVE: 原生 @ 提及。
|
||
"""
|
||
|
||
REPLY_TO_BOT = "reply_to_bot"
|
||
QUOTED_BOT = "quoted_bot"
|
||
BOT_THREAD_PARTICIPANT = "bot_thread_participant"
|
||
NATIVE = "native"
|
||
|
||
|
||
class MentionTargetKind(StrEnum):
|
||
"""提及目标类型。
|
||
|
||
标识被提及目标的种类(用户 / Agent / Bot),用于多 Agent 协作场景的
|
||
提及目标区分。继承 ``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
||
|
||
取值:
|
||
USER: 用户。
|
||
AGENT: Agent。
|
||
BOT: Bot。
|
||
"""
|
||
|
||
USER = "user"
|
||
AGENT = "agent"
|
||
BOT = "bot"
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MentionTarget:
|
||
"""提及目标。
|
||
|
||
描述消息中提及的目标,包括目标 ID、目标种类与显示名称,用于多 Agent
|
||
协作场景的提及目标传递。集合字段使用 tuple 以保证 frozen dataclass
|
||
的不可变语义。
|
||
|
||
字段:
|
||
id: 目标 ID。
|
||
kind: 目标种类。
|
||
display_name: 显示名称(可选,默认 None)。
|
||
"""
|
||
|
||
id: str
|
||
kind: MentionTargetKind
|
||
display_name: str | None = None
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验 id 非空。
|
||
|
||
``id`` 必须非空,在构造时即抛出 ``ValidationError``,避免空目标
|
||
ID 导致提及目标无法定位(INV-8)。
|
||
"""
|
||
if not self.id:
|
||
raise ValidationError("id", "must not be empty")
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MentionContext:
|
||
"""提及上下文。
|
||
|
||
描述消息中提及的上下文信息,包括提及类型、被提及用户列表与隐式提及
|
||
类型。集合字段使用 tuple 以保证不可变。
|
||
|
||
字段:
|
||
type: 提及类型。
|
||
mentioned_users: 被提及用户 ID 列表(默认空 tuple)。
|
||
implicit_kind: 隐式提及类型(FR-29),仅当 ``type`` 为 IMPLICIT
|
||
时由渠道适配器填充,描述隐式提及的具体形式。EXPLICIT / NONE
|
||
时为 None。
|
||
mentioned_targets: 被提及目标列表(默认空 tuple,推荐字段),
|
||
携带结构化的提及目标(用户 / Agent / Bot),用于多 Agent 协作。
|
||
target_agent_ids: 目标 Agent ID 列表(默认空 tuple,便捷访问),
|
||
从 ``mentioned_targets`` 中筛选 ``kind == AGENT`` 的目标 ID。
|
||
|
||
迁移说明(§20.2 coexist → migrate → delete):``mentioned_users`` 为
|
||
向后兼容字段(INV-4),在共存期保留;``mentioned_targets`` 为推荐字段,
|
||
新代码应优先使用;``target_agent_ids`` 提供对 Agent ID 的便捷访问,
|
||
由 ``mentioned_targets`` 中 ``kind == AGENT`` 的目标 ID 组成。
|
||
"""
|
||
|
||
type: MentionType
|
||
mentioned_users: tuple[str, ...] = ()
|
||
implicit_kind: ImplicitMentionKind | None = None
|
||
mentioned_targets: tuple[MentionTarget, ...] = ()
|
||
target_agent_ids: tuple[str, ...] = ()
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class InboundMentionPolicy:
|
||
"""入站提及策略。
|
||
|
||
描述入站消息的提及策略,包括允许的隐式提及类型。集合字段使用 tuple
|
||
以保证不可变。
|
||
|
||
字段:
|
||
allowed_implicit_kinds: 允许的隐式提及类型列表(默认空 tuple)。
|
||
"""
|
||
|
||
allowed_implicit_kinds: tuple[ImplicitMentionKind, ...] = ()
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class InboundMentionFact:
|
||
"""入站提及事实。
|
||
|
||
描述入站消息的提及检测结果,包括是否可检测、是否被提及、是否有任意提及
|
||
与检测到的隐式提及类型。集合字段使用 tuple 以保证不可变。
|
||
|
||
字段:
|
||
can_detect: 是否可检测提及。
|
||
is_mentioned: 是否被提及。
|
||
has_any_mention: 是否有任意提及。
|
||
implicit_kinds: 检测到的隐式提及类型列表(默认空 tuple)。
|
||
"""
|
||
|
||
can_detect: bool
|
||
is_mentioned: bool
|
||
has_any_mention: bool
|
||
implicit_kinds: tuple[ImplicitMentionKind, ...] = ()
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class MentionDecision:
|
||
"""提及决策。
|
||
|
||
描述提及策略的最终决策结果,用于管道下游决定是否处理消息。
|
||
|
||
字段:
|
||
bypass_mention_requirement: 是否绕过提及要求(默认 False)。
|
||
skip_message: 是否跳过消息(默认 False)。
|
||
is_mentioned: 是否被提及(默认 False)。
|
||
"""
|
||
|
||
bypass_mention_requirement: bool = False
|
||
skip_message: bool = False
|
||
is_mentioned: bool = False
|