"""AgentRun DTO。 定义 Agent 运行端口的命令与上下文值对象,包括 Agent 运行 ID、渠道格式 规格、Agent 运行上下文、渠道上下文注记与 Agent 运行命令。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库与契约层内部类型,用于 Agent 运行的命令传递与渠道上下文注入(FR-10 / FR-11)。集合字段使用 tuple 以 保证 frozen dataclass 的不可变语义。 """ from __future__ import annotations from dataclasses import dataclass from typing import Literal from yuxi.channels.contract.dtos.channel import ChannelType, UserIdentity from yuxi.channels.contract.dtos.command import CommandResult from yuxi.channels.contract.dtos.common import MessageContent, MessageFormat from yuxi.channels.contract.dtos.mention import MentionTarget from yuxi.channels.contract.dtos.pairing import DmDecision from yuxi.channels.contract.dtos.tools import ChannelTool from yuxi.channels.contract.errors import ValidationError @dataclass(frozen=True) class AgentRunId: """Agent 运行 ID。 标识一次 Agent 运行的唯一 ID,用于关联 Agent 执行链路与出站消息。 字段: value: Agent 运行 ID 字符串。 """ value: str @dataclass(frozen=True) class ChannelFormatSpec: """渠道格式规格。 描述渠道支持的消息格式规格,包括格式说明与支持的格式列表,用于 Agent 上下文注入以指导消息渲染。集合字段使用 tuple 以保证不可变。 字段: format_description: 格式说明。 supported_formats: 支持的格式列表(默认空 tuple)。 """ format_description: str supported_formats: tuple[MessageFormat, ...] = () @dataclass(frozen=True) class ChannelContextNote: """渠道上下文注记。 描述渠道上下文的注记信息,包括系统提示附录与上下文备注,用于 Agent 上下文注入以补充渠道特定信息。 字段: system_prompt_appendix: 系统提示附录。 context_remark: 上下文备注(可选)。 """ system_prompt_appendix: str context_remark: str | None = None @dataclass(frozen=True) class AgentRunContext: """Agent 运行上下文。 描述 Agent 运行的渠道上下文,包括渠道类型、账户 ID、对端 ID、群组 ID、 话题 ID、发送者 ID、渠道格式规格、渠道上下文注记、渠道工具列表、统一 用户身份、DM 安全决策与配对 ID,用于 Agent 上下文注入(FR-10)与渠道 工具注册(FR-11)。 渠道字段均为可选(默认空),以支持非渠道来源(如直接 API 调用)构造 上下文(FR-10)。``agent_id`` 由 ``AgentRunEnqueueStage`` 从 ``route_binding.agent_binding`` 提取,携带路由解析出的 Agent slug, 供 ``AgentRunAdapter`` 传递给 ``create_agent_run_view`` 创建运行。 ``channel_context_note`` 由 ``AgentRunEnqueueStage`` 调用插件方法 (``buildAgentContextNote``)生成,携带渠道特定的系统提示附录与上下文 备注。``channel_tools`` 由 ``AgentRunEnqueueStage`` 读取 ``agent_tools_enabled`` 开关后调用插件方法(``getChannelTools``)填充, 携带渠道原生工具声明,供 Agent 运行时合并到可用工具列表(FR-11)。 ``unified_identity`` 由 ``identity_resolve_stage`` 解析得到,携带 统一用户身份信息,用于 Agent 上下文注入身份维度。``dm_decision`` 与 ``pairing_id`` 由 ``security_stage`` 产出,分别携带 DM 安全决策结果 与在 ``pending_pairing`` 决策下生成的配对标识,供 Agent 运行感知 DM 安全处置状态。 字段: agent_id: Agent slug(默认空串),由路由绑定解析,用于创建 Agent 运行。 channel_type: 渠道类型(可选,默认 None)。 channel_account_id: 渠道账户 ID(默认空串)。 channel_peer_id: 对端 ID(默认空串)。 channel_group_id: 群组 ID(可选)。 channel_topic_id: 话题 ID(可选)。 channel_sender_id: 发送者 ID(可选)。 channel_format_spec: 渠道格式规格(可选)。 channel_context_note: 渠道上下文注记(可选,由插件方法生成)。 channel_tools: 渠道工具列表(默认空 tuple,由插件方法 ``getChannelTools`` 生成,FR-11)。非渠道来源或开关关闭时为空 tuple,不合并任何 渠道工具。 unified_identity: 统一用户身份(可选,默认 None),来源 ``identity_resolve_stage`` 解析结果,携带用户在渠道侧或外部 身份系统的身份信息,用于 Agent 上下文注入身份维度。 service_user_uid: 服务用户 UID(deprecated,默认空串,后续迭代移除)。 channel_user_identity: 渠道用户身份(可选,默认 None), ``unified_identity`` 的替代字段。 dm_decision: DM 安全决策(可选,默认 None),来源 ``security_stage`` 决策结果,携带 DM 消息处置决策(allow / deny / pending_pairing / whitelist),供 Agent 运行感知 DM 安全处置状态。 pairing_id: 配对 ID(可选,默认 None),来源 ``security_stage`` 在 ``pending_pairing`` 决策下生成的配对标识,用于关联后续配对 审批流程与审计。 多 Agent 协作链路字段(默认 None 表示非协作场景):``parent_run_id`` 标识父 AgentRun(委派发起方);``delegated_by_agent_id`` 标识委派发起的 Agent slug;``collaboration_id`` 关联同一协作链路的多个 AgentRun。 """ agent_id: str = "" channel_type: ChannelType | None = None channel_account_id: str = "" channel_peer_id: str = "" channel_group_id: str | None = None channel_topic_id: str | None = None channel_sender_id: str | None = None channel_format_spec: ChannelFormatSpec | None = None channel_context_note: ChannelContextNote | None = None channel_tools: tuple[ChannelTool, ...] = () unified_identity: UserIdentity | None = None # deprecated: 后续迭代移除,使用 channel_user_identity 替代 service_user_uid: str = "" channel_user_identity: UserIdentity | None = None dm_decision: DmDecision | None = None pairing_id: str | None = None parent_run_id: str | None = None delegated_by_agent_id: str | None = None collaboration_id: str | None = None @dataclass(frozen=True) class AgentRunCmd: """Agent 运行命令(FR-10 / FR-15)。 由 Agent 运行端口方法引用,描述一次 Agent 运行请求,携带会话 ID、 消息内容、上下文与追踪 ID,用于驱动 Agent 执行。 字段: conversation_id: 会话 ID。 message_content: 消息内容。 context: Agent 运行上下文(可选)。 trace_id: 追踪 ID(可选)。 source: 运行来源(如 "channel" / "api" / "admin" / "delegation"),用于 Agent 上下文注入区分来源(FR-10,可选,默认空串)。 command_result: 非静默命令执行结果(可选,FR-15),作为上下文 注入 Agent 运行,供 Agent 感知命令执行结果。 """ conversation_id: str message_content: MessageContent context: AgentRunContext | None = None trace_id: str | None = None source: Literal["channel", "api", "admin", "delegation"] = "" command_result: CommandResult | None = None def __post_init__(self) -> None: """校验必填字段非空。 ``conversation_id`` 与 ``message_content.text`` 必须非空, 在构造时即抛出 ``ValidationError``,adapter 不再做该校验(INV-8 / §7.3 端口契约前置条件)。 """ if not self.conversation_id: raise ValidationError("conversation_id", "must not be empty") if not self.message_content.text: raise ValidationError("message_content", "must not be empty") @dataclass(frozen=True) class AgentRoutingDecision: """Agent 路由决策。 描述入站消息中识别到的 Agent 路由决策,由 ClassifyStage 在 mention_context.target_agent_ids 非空时构造,供下游 RouteStage 决定路由目标(多 Agent 协作)。 字段: target_agent_id: 目标 Agent ID(必填)。 source: 触发路由的 MentionTarget(可选,默认 None)。 collaboration_id: 协作链路 ID(可选,默认 None)。 is_handoff: 是否为 Agent 移交(默认 False)。 """ target_agent_id: str source: MentionTarget | None = None collaboration_id: str | None = None is_handoff: bool = False def __post_init__(self) -> None: """校验必填字段非空。""" if not self.target_agent_id: raise ValidationError("target_agent_id", "must not be empty")