ForcePilot/backend/package/yuxi/channels/application/context/inbound_context.py

161 lines
6.8 KiB
Python
Raw Normal View History

"""入站管道上下文。
定义入站管道的可变局部上下文 ``InboundContext``携带请求从 receive reply
各阶段产生的状态上下文为 ``@dataclass`` frozen阶段直接修改字段以
推进管道状态
"""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any
from yuxi.channels.contract.dtos.ack import AckPolicy
from yuxi.channels.contract.dtos.agent_run import (
AgentRoutingDecision,
ChannelContextNote,
ChannelFormatSpec,
)
from yuxi.channels.contract.dtos.channel import (
ChannelSession,
ChannelType,
UserIdentity,
)
from yuxi.channels.contract.dtos.command import CommandResult
from yuxi.channels.contract.dtos.common import (
MessageContent,
RawEvent,
)
from yuxi.channels.contract.dtos.mention import (
InboundMentionFact,
MentionContext,
MentionDecision,
)
from yuxi.channels.contract.dtos.pairing import DmDecision
from yuxi.channels.contract.dtos.route import RouteBinding
from yuxi.channels.contract.dtos.service_account import ServiceAccount
from yuxi.channels.contract.dtos.status import EventType
from yuxi.channels.contract.errors import Error
if TYPE_CHECKING:
from yuxi.channels.contract.ports.driven.transaction_port import TransactionContext
@dataclass
class InboundContext:
"""入站管道可变局部上下文。
携带入站请求从 receive reply 各阶段产生的状态阶段按顺序填充字段
字段按阶段分组便于追溯状态来源
事务边界§10.1``tx`` 字段由 ``InboundMessageService`` 在管道
执行前通过 ``TransactionPort.begin()`` 开启session-resolve 阶段的
``resolveConversation`` ``saveChannelSession`` 写操作共享此事务
上下文确保会话解析与渠道会话保存原子提交
命名等价说明6-P2-01``trace_id`` Agent ``turn_id`` 为同一
概念的不同命名均标识一次请求/会话回合的链路追踪 ID本上下文
``trace_id`` 字段即等价于 ``turn_id``
"""
# ---- 基础字段receive 阶段) ----
trace_id: str
request_id: str
channel_type: ChannelType
account_id: str
raw_event: RawEvent
# 运行来源(如 "channel" / "admin"),用于 Agent 上下文注入区分来源FR-10
source: str = "channel"
# 渠道插件清单 ID由 receive 阶段填充
plugin_id: str | None = None
# ---- signature-verify 阶段字段 ----
# Webhook 签名是否已验证通过,由 signature-verify 阶段填充。
# 适配器未实现验签时保持 False跳过验签验签通过时置 True。
signature_verified: bool = False
# ---- 事务上下文(由 InboundMessageService 注入session_resolve_stage 共享)----
tx: TransactionContext | None = None
# 事务提交后执行的副作用 hooks由各阶段注册、InboundMessageService 统一执行。
post_commit_hooks: list[Callable[[], Awaitable[None]]] = field(default_factory=list)
# ---- classify 阶段字段 ----
event_type: EventType | None = None
ref_channel_msg_id: str | None = None
status_payload: dict[str, Any] | None = None
peer_id: str | None = None
chat_type: str | None = None
# 话题 IDFR-10由 classify 阶段从原始事件提取,不支持话题的渠道为 None
topic_id: str | None = None
message_content: MessageContent | None = None
mention_context: MentionContext | None = None
mention_fact: InboundMentionFact | None = None
# Agent 路由决策FR-AgentCollab由 classify 阶段从 mention_context
# 构造,供下游 RouteStage 决定路由目标。None 表示无 Agent 提及。
agent_routing_decision: AgentRoutingDecision | None = None
# ---- security 阶段字段 ----
dm_decision: DmDecision | None = None
pairing_id: str | None = None
# 是否为管理员用户FR-15由 security 阶段根据账户级 admin_users 配置
# 判定,供 command-check 阶段校验 ADMIN 权限命令(/allowlist、/approve 等)。
is_admin: bool = False
# 是否为渠道访客 channel_guest 身份,由 identity-resolve 阶段判定,标识当前
# 请求来自未绑定服务账号的访客,供下游阶段决策鉴权与降级策略。
is_guest: bool = False
# ---- command-check 阶段字段 ----
command: CommandResult | None = None
is_silent: bool = False
mention_decision: MentionDecision | None = None
# ---- identity-resolve 阶段字段 ----
unified_identity: UserIdentity | None = None
# 渠道账户绑定的服务账号,由 service-account-resolve 阶段填充,携带服务账号
# uid 作为 Agent 执行的鉴权主体,满足会话归属与用户存在性校验。
service_account: ServiceAccount | None = None
# ---- session-resolve 阶段字段 ----
channel_session: ChannelSession | None = None
conversation_id: str | None = None
# ---- fence 代际字段agent-run-enqueue 阶段写入FR-23 ----
fence_generation: int | None = None
# ---- route 阶段字段 ----
route_binding: RouteBinding | None = None
current_uid: str | None = None
# ---- agent-run-enqueue 阶段字段 ----
agent_run_id: str | None = None
# ---- reply 阶段字段FR-24 分阶段 ACK ----
# ACK 决策结果ack | nack | pending
ack_decision: str = "pending"
# 解析后的 ACK 策略reply 阶段解析:插件声明 → 配置 → 默认值)
ack_policy: AckPolicy | None = None
# 幂等键(基于渠道类型 + 账户 ID + 原始事件负载哈希,跨重试稳定)
ack_idempotency_key: str | None = None
# 是否已 ACK幂等检查标记避免重复 ACK 副作用)
acked: bool = False
# 是否已 NACK与 ACK 互斥,避免 ACK/NACK 同时生效)
nacked: bool = False
# ---- 出站投递错误字段 ----
# 出站消息投递失败时的错误信息FR-24。reply 阶段向渠道侧投递出站
# 消息失败时填充,用于上层决策重试或降级;投递成功或未触发投递时为 None。
outbound_error: str | None = None
# ---- 降级标志字段 ----
degraded: bool = False
degraded_reason: Error | None = None
# ---- 可观测性字段BP-10 ----
# 渠道格式规范(包含 supported_formats由上下文富化逻辑写入供管道
# 日志_logStageExecution输出可观测性信息。
channel_format_spec: ChannelFormatSpec | None = None
# 渠道上下文注记(来自 channel_context_provider由上下文富化逻辑写入
# 供管道日志_logStageExecution输出可观测性信息。
channel_context_note: ChannelContextNote | None = None