本次提交包含多项核心功能迭代与优化: 1. 新增KF客服会话类型,完善聊天类型枚举 2. 新增消息撤回操作类型与身份置信度排序方法 3. 新增控制面结果DTO与敏感字段注册表端口 4. 新增身份合并回滚、重试失败投递目标等业务能力 5. 优化Outbox投递逻辑与熔断器状态判断 6. 修复部分代码冗余与类型不匹配问题 7. 新增数据库索引并发创建与路由绑定清理逻辑 8. 优化会话关闭服务与插件重载并发控制
96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
"""状态 DTO。
|
||
|
||
定义消息状态事件的枚举与不可变值对象,包括事件类型、消息状态与状态
|
||
负载。所有枚举继承 ``str, Enum`` 以支持 JSON 序列化,DTO 均为
|
||
``dataclass(frozen=True)``,仅依赖标准库,用于渠道侧消息状态事件
|
||
(送达 / 已读 / 编辑 / 撤回等)的回传与状态机推进。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
from datetime import datetime
|
||
from enum import StrEnum
|
||
from typing import Any
|
||
|
||
from yuxi.channels.contract.errors import ValidationError
|
||
|
||
|
||
class EventType(StrEnum):
|
||
"""事件类型。
|
||
|
||
标识渠道侧回传的消息状态事件类型,用于状态事件解析与状态机推进。
|
||
继承 ``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
||
|
||
取值:
|
||
MESSAGE: 消息事件。
|
||
DELIVERED: 已送达。
|
||
READ: 已读。
|
||
EDITED: 已编辑。
|
||
RECALLED: 已撤回。
|
||
UNKNOWN: 未知事件。
|
||
AGENT_MENTION: Agent 提及事件(多 Agent 协作,标识 @Agent 提及)。
|
||
"""
|
||
|
||
MESSAGE = "message"
|
||
DELIVERED = "delivered"
|
||
READ = "read"
|
||
EDITED = "edited"
|
||
RECALLED = "recalled"
|
||
UNKNOWN = "unknown"
|
||
AGENT_MENTION = "agent_mention"
|
||
|
||
|
||
class MessageStatus(StrEnum):
|
||
"""消息状态。
|
||
|
||
标识出站消息在渠道侧的状态,用于出站状态机推进与持久化。继承
|
||
``str, Enum`` 以支持 JSON 序列化与字符串比较。
|
||
|
||
取值:
|
||
PENDING: 待发送。
|
||
SENT: 已发送。
|
||
DELIVERED: 已送达。
|
||
READ: 已读。
|
||
FAILED: 已失败。
|
||
"""
|
||
|
||
PENDING = "pending"
|
||
SENT = "sent"
|
||
DELIVERED = "delivered"
|
||
READ = "read"
|
||
FAILED = "failed"
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class StatusPayload:
|
||
"""状态负载。
|
||
|
||
描述渠道侧回传的消息状态事件负载,包括事件类型、关联的渠道消息 ID
|
||
与事件时间戳,用于状态事件解析与状态机推进。
|
||
|
||
字段:
|
||
event_type: 事件类型。
|
||
ref_channel_msg_id: 关联的渠道消息 ID(通讯录变更等无消息 ID 的
|
||
事件可为空字符串,调用方按 ``event_type`` 区分)。
|
||
timestamp: 事件时间戳。
|
||
metadata: 渠道侧扩展信息(可选,如通讯录变更的 ``change_type``、
|
||
客服事件的 ``external_userid`` 等)。
|
||
"""
|
||
|
||
event_type: EventType
|
||
ref_channel_msg_id: str
|
||
timestamp: datetime
|
||
metadata: dict[str, Any] | None = None
|
||
|
||
def __post_init__(self) -> None:
|
||
"""校验必填字段。
|
||
|
||
``event_type`` 与 ``timestamp`` 必填;``ref_channel_msg_id`` 对
|
||
``MESSAGE`` 事件必须非空,对通讯录变更等非消息事件允许为空
|
||
(由调用方按 ``event_type`` 区分)。空 ``ref_channel_msg_id`` 仅在
|
||
``event_type != MESSAGE`` 时允许。
|
||
"""
|
||
if not self.ref_channel_msg_id and self.event_type == EventType.MESSAGE:
|
||
raise ValidationError("ref_channel_msg_id", "must not be empty for MESSAGE event")
|