1. 新增WeChatWocStreamConnectorAdapter,实现SSE长连接接收消息,支持热更新配置 2. 升级wechat_woc插件依赖bridge版本至1.5.0,开启both传输模式 3. 新增SSE相关常量与配置项,完善woc_bridge_client SSE实现 4. 重构RouteStage,复用会话缓存避免重复查询 5. 新增入站/出站全链路日志打点,优化异常场景日志输出 6. 实现入站幂等记录状态回写机制,独立事务避免死锁 7. 新增TransportManager重启恢复逻辑,自动恢复在线账号传输任务 8. 修复inbound_pipeline移除冗余persistence_port参数,注入idempotency仓储 9. 新增InboundContext.idempotency_record_id字段,传递幂等记录主键
168 lines
7.3 KiB
Python
168 lines
7.3 KiB
Python
"""入站管道上下文。
|
||
|
||
定义入站管道的可变局部上下文 ``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
|
||
# 入站消息幂等键(可选)。由 receive 阶段基于渠道类型 + 账户 ID + 原始事件
|
||
# 负载哈希派生,跨重试稳定,供幂等检查阶段去重,避免重复创建 agent_run。
|
||
idempotency_key: str | None = None
|
||
# 入站消息幂等记录主键(可选)。由 inbound-idempotency 阶段在创建
|
||
# in_progress 记录后填充,供 InboundMessageService 在管道成功/失败后
|
||
# 更新为 completed/failed 状态(C-5 状态回写,独立于管道事务)。
|
||
idempotency_record_id: int | 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
|
||
# 话题 ID(FR-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
|