本次提交包含多项代码优化与规范修正: 1. 文档与注释优化:修正注释术语、补充注解与FR编号 2. 代码格式调整:统一空格、换行与缩进规范 3. 类型与接口完善:补充__all__导出、修正返回类型注解 4. 错误处理增强:新增领域错误类与校验逻辑 5. 依赖与导入调整:修复路径引用、统一时区导入 6. 协议与契约更新:完善接口文档与一致性注解
207 lines
8.9 KiB
Python
207 lines
8.9 KiB
Python
"""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")
|