ForcePilot/backend/package/yuxi/channels/contract/dtos/trusted.py
Kris 00092c818e chore: 批量代码优化与规范完善
本次提交包含多项代码优化与规范修正:
1. 文档与注释优化:修正注释术语、补充注解与FR编号
2. 代码格式调整:统一空格、换行与缩进规范
3. 类型与接口完善:补充__all__导出、修正返回类型注解
4. 错误处理增强:新增领域错误类与校验逻辑
5. 依赖与导入调整:修复路径引用、统一时区导入
6. 协议与契约更新:完善接口文档与一致性注解
2026-07-03 19:18:13 +08:00

160 lines
7.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。
定义可信注入边界FR-25的不可变值对象包括可信上下文、可信消息上下文
与消息操作上下文。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库
与契约层内部类型,用于服务端强制注入发送者身份与所有者标记,确保渠道侧
无法伪造发送者。
FR25-P0-2 可信上下文(``TrustedContext``):聚合入站管道解析的可信字段
(会话、发送者、渠道类型、对端等),由 ``ChannelToolExecutor`` 注入到
``_trusted_*`` 保留键,供 ``MessageOperationExecutor`` 提取构建可信消息
操作上下文。
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Literal
from yuxi.channels.contract.dtos.channel import ChannelType
from yuxi.channels.contract.errors import ValidationError
# === FR-25 可信上下文保留键 ===
# Agent 运行时在调用渠道工具执行器前,将服务端可信上下文以这些保留键
# 注入到工具参数字典中。``MessageOperationExecutor`` 提取后从参数中移除,
# 防止传递给插件方法。保留键使用 ``_trusted_`` 前缀,避免与 LLM 生成的
# 业务参数冲突。
TRUSTED_CONVERSATION_ID_KEY = "_trusted_conversation_id"
TRUSTED_CLAIMED_SENDER_ID_KEY = "_trusted_claimed_sender_id"
TRUSTED_CHANNEL_SESSION_ID_KEY = "_trusted_channel_session_id"
TRUSTED_GATEWAY_CLIENT_INFO_KEY = "_trusted_gateway_client_info"
TRUSTED_IS_DRY_RUN_KEY = "_trusted_is_dry_run"
# 群组上下文保留键FR25-P0-2 扩展):群组场景下消息操作(如置顶、卡片更新)
# 需要群组 ID 定位会话,由服务端从入站管道解析的 ``channel_group_id`` 强制
# 注入,防止 LLM 伪造群组定位。
TRUSTED_GROUP_ID_KEY = "_trusted_group_id"
# FR-25 可信上下文保留键集合,用于批量剥离。
# 由工具包装器(``wrap_channel_tool``)注入到工具参数字典中,
# ``MessageOperationExecutor`` 提取后从参数中移除,``ChannelToolExecutor``
# 在普通工具路径中剥离以防止保留键泄露给插件方法。保留键使用
# ``_trusted_`` 前缀,避免与 LLM 生成的业务参数冲突。
TRUSTED_RESERVED_KEYS = frozenset(
{
TRUSTED_CONVERSATION_ID_KEY,
TRUSTED_CLAIMED_SENDER_ID_KEY,
TRUSTED_CHANNEL_SESSION_ID_KEY,
TRUSTED_GATEWAY_CLIENT_INFO_KEY,
TRUSTED_IS_DRY_RUN_KEY,
TRUSTED_GROUP_ID_KEY,
}
)
@dataclass(frozen=True)
class TrustedContext:
"""可信上下文FR25-P0-2
聚合入站管道解析出的可信字段,由 ``ChannelToolExecutor`` 在工具调用前
注入到 ``_trusted_*`` 保留键,供 ``MessageOperationExecutor`` 提取并
构建可信消息操作上下文FR-25。字段与 ``MessageOperationExecutor``
所需可信字段对齐,并扩展渠道定位字段(``channel_type`` / ``account_id``
/ ``peer_id`` / ``chat_type`` / ``topic_id``)以支持更完整的上下文
注入。
所有字段均可空,适配非渠道 Agent Run无可信会话与未声明字段渠道的
降级场景;由消费方按 FR-25 规则校验必填性。
字段:
conversation_id: 会话 IDFR-25 核心可信字段,非渠道 Agent Run
为 None
claimed_sender_id: 客户端声明的发送者 IDFR-25由服务端校验
channel_session_id: 渠道会话 IDFR-25
channel_type: 渠道类型FR25-P0-2 扩展,定位渠道适配器)。
account_id: 渠道账户 IDFR25-P0-2 扩展,定位渠道账户)。
peer_id: 对端 IDFR25-P0-2 扩展,定位会话对端)。
chat_type: 会话类型(``"p2p"`` | ``"group"``FR25-P0-2 扩展)。
topic_id: 话题 IDFR25-P0-2 扩展,不支持话题的渠道为 None
group_id: 群组 IDFR25-P0-2 扩展,群组场景下定位群会话)。``p2p``
会话为 None``group`` 会话由入站管道从 ``channel_group_id``
解析后服务端强制注入,供消息操作(如置顶、卡片更新)定位群组。
"""
conversation_id: str | None = None
claimed_sender_id: str | None = None
channel_session_id: str | None = None
channel_type: ChannelType | None = None
account_id: str | None = None
peer_id: str | None = None
chat_type: Literal["p2p", "group"] | None = None
topic_id: str | None = None
group_id: str | None = None
@dataclass(frozen=True)
class TrustedMessageContext:
"""可信消息上下文。
描述服务端强制注入的发送者身份与所有者标记,确保渠道侧无法伪造
发送者。同时携带网关客户端信息与 dry-run 标记,用于可信注入边界
FR-25的上下文传递。
字段:
sender_id: 发送者 ID服务端强制注入
is_owner: 是否为会话所有者(服务端强制注入,默认 False
gateway_client_info: 网关客户端信息(可选)。
is_dry_run: 是否为 dry-run 模式(默认 False
"""
sender_id: str
is_owner: bool = False
gateway_client_info: dict[str, Any] | None = None
is_dry_run: bool = False
def __post_init__(self) -> None:
"""校验 sender_id 非空。
``sender_id`` 必须非空,在构造时即抛出 ``ValidationError``,避免
空发送者身份被注入到渠道消息FR-25 / INV-8
"""
if not self.sender_id:
raise ValidationError("sender_id", "must not be empty")
@dataclass(frozen=True)
class MessageOperationContext:
"""消息操作上下文。
描述消息操作的执行上下文,携带可信消息上下文、操作类型、渠道消息 ID
与渠道会话 ID用于消息操作edit / recall / pin 等)的可信注入与
上下文传递。
字段:
trusted_context: 可信消息上下文。
operation: 操作类型edit / recall / pin 等)。
channel_msg_id: 渠道消息 ID。
channel_session_id: 渠道会话 ID可选
group_id: 群组 ID可选FR25-P0-2 扩展)。群组场景下的消息操作
(如置顶、卡片更新)按需消费以定位群会话;``p2p`` 会话为 None。
由服务端从入站管道解析的 ``channel_group_id`` 经可信注入链路
强制注入,防止 LLM 伪造群组定位。
"""
trusted_context: TrustedMessageContext
operation: str
channel_msg_id: str
channel_session_id: str | None = None
group_id: str | None = None
def __post_init__(self) -> None:
"""校验 operation 与 channel_msg_id 非空。
``operation`` 与 ``channel_msg_id`` 必须非空,在构造时即抛出
``ValidationError``,避免空操作类型或空消息 ID 导致操作无法定位
目标消息FR-25 / INV-8
"""
if not self.operation:
raise ValidationError("operation", "must not be empty")
if not self.channel_msg_id:
raise ValidationError("channel_msg_id", "must not be empty")