ForcePilot/backend/package/yuxi/channels/contract/dtos/status.py
Kris b8ac375e8e feat: 新增多渠道客服会话、身份合并与重试能力等功能
本次提交包含多项核心功能迭代与优化:
1. 新增KF客服会话类型,完善聊天类型枚举
2. 新增消息撤回操作类型与身份置信度排序方法
3. 新增控制面结果DTO与敏感字段注册表端口
4. 新增身份合并回滚、重试失败投递目标等业务能力
5. 优化Outbox投递逻辑与熔断器状态判断
6. 修复部分代码冗余与类型不匹配问题
7. 新增数据库索引并发创建与路由绑定清理逻辑
8. 优化会话关闭服务与插件重载并发控制
2026-07-09 04:21:28 +08:00

96 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""状态 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")