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

207 lines
8.9 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.

"""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: 服务用户 UIDdeprecated默认空串后续迭代移除
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")