Complete the selective V2 checkpoint with its minimal AgentBus, object-storage, replay persistence, and validated-workbench shared dependency closure.
11 KiB
M012 / Layer 3 字段 Recovery SuperAgent 接通 Change Request v1
| 项 | 内容 |
|---|---|
| 状态 | Implementation complete — deployment gated |
| 日期 | 2026-08-10 |
| 用户目标 | 信息系统调用 SuperAgent 平台的解析 Agent,并等待本次解析请求结果 |
| Checkpoint | M012-layer3-field-recovery-superagent-sync-v1 |
| 影响范围 | Backend / SuperAgent Adapter / PostgreSQL / Configuration / Test / Docs |
1. 背景
QBD Layer 3 已完成确定性 Parser、RecoveryRequestSet、provider-neutral
FieldRecoveryAgentPort、本地 RecoveryPatchValidator、dependency resolver、projector、
EffectiveFactView 与内存幂等测试,但尚未接通真实 SuperAgent provider,也没有数据库版
apply-once 与 provider 调用审计。
本变更建立第一个真实 transport 闭环。信息系统只在存在精确
UNRESOLVED+RECOVERABLE task 时调用专用解析 Agent,并在有界 deadline 内等待完整
RecoveryPatchSet;返回后仍由信息系统本地验证和组装,Agent 结果不直接成为业务事实。
2. 目标
- 在
integrations.ai.superagent实现FieldRecoveryAgentPort的真实 Adapter,复用现有 SuperAgent Open API session + SSE transport;解析 Agent 使用独立外部应用/API Key,不复用其他 Agent 凭据。 - 发送最小、JSON-only
RecoveryRequestSet,同步等待最终 SSE 成功结果,并严格解析为RecoveryPatchSet。 - 为整个 Provider 调用设置可配置总等待时间;超时必须中断/取消在途调用并 fail-closed。
- 在
th_hotel_bookingPostgreSQL schema 持久化请求 hash、Provider 安全元数据、成功/失败、 PatchSet 和最终 Assembly,提供“成功响应已落库后的 crash replay”与原子 apply-once。 - 在手工 EML 的 contracts-v1 主线中,于
PARSED_FACT_SET后执行 Recovery,保存RECOVERY_REQUEST、RECOVERY_ASSEMBLY、EFFECTIVE_FACT_VIEWartifact,再继续现有 Context。
3. 非目标
- 不在 AgentBus WebSocket callback 中同步等待 SuperAgent;首期
AGENTBUS来源不调用 Recovery。 - 不复用旧 V4
task-results、MCP submit、AgentBus SuperAgent dispatch 或 Layer 5 Booking Agent。 - 不让 Agent 下载/打开附件、读取邮件正文、完整行/工作簿、附件 URL、数据库或 207 行目录。
- 不让 Layer 4/5 在本 checkpoint 消费
EffectiveFactView;RateRoom、CandidateDecision、PMS/Opera 继续后置。 - 自动化测试不调用真实 SuperAgent,不提交 API Key、邮件或附件;人工联调只允许合成、隐私最小化 smoke,且不得输出或持久化 Provider raw answer。
- 不在本 checkpoint 接通 Booking Business Agent;只提供可复用 client factory,使其后续使用独立 外部应用、独立 token 和独立 wrapper/config 接入。
4. 调用与等待契约
MANUAL_EML
-> BookingPostgresMessageOrchestrator
-> Deterministic Parser / PARSED_FACT_SET
-> RecoveryRequestBuilder
-> 无 task:本地 baseline,不调用 SuperAgent
-> 有 task:SuperAgentFieldRecoveryAdapter
-> claim 持久 invocation idempotency key
-> POST agent session
-> POST messages/stream(解析 Agent 当前不请求公开 Trace)
-> 等待 core message.final + end
-> GET run status 确认 success 并补齐 resolved Profile 审计字段
-> 信息系统取得完整成功结果(总计不超过 max-wait)
-> JSON-only strict deserialize RecoveryPatchSet
-> 保存 provider success/failure 安全审计
-> RecoveryPatchValidator / dependency resolver / projector
-> PostgreSQL atomic apply-once
-> persist EffectiveFactView artifact
-> 继续既有 Context / Decision 流程
成功只表示取得完整 Provider answer、确认 Provider run 成功并通过本地 contract/assembly;不能表示订单、 任务或 PMS 动作成功。
5. 配置与部署门禁
建议配置前缀:booking.field-recovery。
| 配置 | 默认值 | 说明 |
|---|---|---|
enabled |
false |
总开关;默认不调用真实 Provider |
profile-version |
fixed-channel-field-recovery-qbd-v1 |
本地审计使用的 Agent 资产版本;不参与平台 Profile 路由 |
open-api.base-url |
https://superagent.nianxx.cn |
解析 Agent 外部应用使用的 Open Agent API 地址,可按环境覆盖 |
open-api.api-key |
空 | 解析 Agent 专属 df_open_... Secret;启用时必填,不回退其他 Agent key |
open-api.connect-timeout |
15s |
解析 Agent 专属客户端建连超时 |
open-api.sse-recovery-max-attempts |
5 |
SSE 断流后查询 run/events 的恢复次数 |
open-api.include-trace |
false |
是否请求公开 Trace;解析 Agent 外部应用当前禁用 Trace,Recovery 默认不得追加该参数 |
max-wait |
120s |
从 claim 到完整结果的整体 deadline,必须大于 0 且有上限 |
poll-interval |
100ms |
并发请求等待既有 invocation 完成的数据库轮询间隔 |
max-message-chars |
200000 |
Recovery JSON message 的纵深防御上限 |
max-response-chars |
200000 |
SuperAgent 最终 JSON answer 的纵深防御上限 |
Open Agent API 不接收 profile_id:df_open_... token 对应的外部应用策略决定已发布 Profile;
external_subject_id 只标识调用方主体,由信息系统基于 source_message_id 的 SHA-256 稳定派生,
不再作为部署路由配置。生产 profile 显式保持 booking.field-recovery.enabled=false,直至 token 所绑定
Profile/API exposure、Secret 注入、PostgreSQL migration、超时和审计验收完成。
当前平台即使使用 Bearer token 也要求每次请求携带临时 CSRF double-submit header/cookie;共享 client
已实现。解析 Agent 外部应用对 include_trace=true 返回 open_agent_trace_disabled,因此无 Trace 模式以
core message.final 读取最终答案、以顶层 end 确认流结束,再以 GET /runs/{run_id} 的
status=success 作为权威终态并读取 metadata.resolved_profile_*。Debug/AgentBus 或未来 Business Agent
是否请求 Trace 由各自独立 client settings 决定,不能套用 Recovery 配置。
6. 请求、响应与安全
- Request 仅包含 Java
RecoveryRequestSet的 snake_case JSON,不附带 Parser 全量对象或材料。 - Message 只增加稳定的 JSON-only 协议提示,不复制 Skill 业务规则;SuperAgent profile 必须安装
fixed-channel-field-recoverySkill。 - 解析 Agent、未来 Booking Business Agent 和现有 Debug/AgentBus 使用相互独立的外部应用/API Key; 只复用通用 session/SSE client factory,不共享 Agent 身份或 Profile 路由凭据。
- Response 必须是单个 JSON object;拒绝 Markdown fence、前后文本和未知字段。
RecoveryPatchValidator继续验证 request/attempt/idempotency/field/path/evidence/schema/candidate refs; Adapter 成功不能绕过本地 Validator。- 日志和错误只记录稳定 request/idempotency/profile/error code,不记录 raw token、完整 request/answer、 邮件、附件 URL、Authorization、Cookie、CSRF 或 API Key。
7. PostgreSQL 与幂等
新增 additive Flyway migration,建立专用 execution 表并扩展 artifact type 白名单。表至少保存:
- recovery request ID、idempotency key、source message ID/revision、observation hash;
- invocation 状态、request/response hash、Provider session/run/profile/model、token usage、耗时;
- 安全错误代码/摘要;
RecoveryPatchSetJSON 与最终AssemblyResultJSON;- created/started/completed/updated/retention UTC 时间。
同一 idempotency key 只有一个 invocation owner。并发调用读取既有状态并在同一总 deadline 内等待; 已成功的 PatchSet 直接 replay,不重复调用 Provider。Assembly 使用原子 compare-and-set 写入,重放返回 已存结果,不重复 overlay。
本版不自动接管进程崩溃遗留的 IN_PROGRESS owner:同 key 调用会在自身 deadline 内等待并
fail-closed,不会并发重发 Provider。生产放行前需为 stale IN_PROGRESS 配置监控/人工处置;后续若要
自动重试,应另加 owner lease/fencing token,而不能仅按时间无保护抢占。
8. 失败语义
| 场景 | 结果 |
|---|---|
| 开关关闭 / 来源不允许 / 无 task | 不调用 Provider,继续本地 baseline |
| 启用时配置缺失 | Spring 启动校验失败,不开放半配置运行实例 |
| request/response 超限 | AGENT_CALL_FAILED,保存安全错误 |
超过 max-wait |
取消在途调用,AGENT_CALL_FAILED,不得使用部分回答 |
| HTTP/SSE/恢复失败 | AGENT_CALL_FAILED,不得使用部分回答 |
| 非 JSON、未知字段或 DTO 无效 | Provider output failure,本地 fail-closed |
| Patch contract/identity/schema 无效 | Validator 拒绝,进入 review,不写 Parser observations/facts |
| 同 key 已完成 | replay 已存 PatchSet/Assembly,不重复外部调用或 overlay |
9. 测试与验收
- Adapter:成功 JSON、未知字段、Markdown/前后文本、Provider failure、timeout/cancel、请求/响应上限、metadata。
- Persistent store:首次 claim、existing replay、成功/失败 CAS SQL、assembly put-if-absent 控制流。
- Orchestrator:MANUAL_EML 在继续 Context 前同步完成 Recovery;AGENTBUS 不调用同步 Recovery。
- 配置:默认关闭、启用缺专用 API Key 失败、等待上限、凭据隔离、条件 bean、prod 显式关闭。
- 已运行 focused Maven tests 和后端全量 598 tests(0 failures、0 errors、3 skipped);PostgreSQL migration deployment smoke 仍是部署门禁。
- 已用用户提供的 key 完成一次合成、无 Trace 的真实 transport/Profile-routing smoke;session、SSE、
message.final、end和 run status success 均成功。该 smoke 未验证完整 Recovery JSON 业务契约, 不等价于MANUAL_EML → PostgreSQL端到端上线。 - 文档 drift 与
git diff --check作为最终仓库门禁。
10. 需求追踪
| 需求项 | 后端 | 测试 | 文档 | 当前状态 |
|---|---|---|---|---|
| SuperAgent Recovery Adapter | Complete | Complete | 本文 + integration docs | Implemented |
| 有界同步等待 / cancel | Complete | Complete | 本文 | Implemented |
| PostgreSQL invocation + apply-once | Complete | Unit complete;真实 PG smoke 待部署 | 本文 | Deployment gated |
| MANUAL_EML 主流程接线 | Complete | Complete | 本文 | Implemented |
| AgentBus listener 保持非同步调用 | Complete | Complete | 本文 + integration docs | Implemented |
| 配置与部署门禁 | Complete | Complete | 本文 + integration/security docs | Implemented;prod off |
11. 待联调项
- 真实 smoke 已确认该 token 可创建 session、调用已解析 Profile 并取得成功 run;仍需用完整
RecoveryRequestSet验证目标 Profile 已安装正确版本 Recovery Skill 且输出严格 PatchSet。 - 将用户提供的 API Key 通过
TH_HOTEL_BOOKING_FIELD_RECOVERY_OPEN_API_KEYSecret 注入测试环境;不得落盘。 - 确认测试环境允许的最大 SSE 运行时间;Base URL 已确认为
https://superagent.nianxx.cn,当前解析 外部应用禁用公开 Trace。 - 平台对同一
idempotency_key的跨 session 去重行为;信息系统仍以本地 execution 唯一键为准。 - 测试/预生产 PostgreSQL 执行 Flyway V3 与事务 smoke;当前开发机没有可用 PostgreSQL 运行时。
- stale
IN_PROGRESS告警与人工处置流程;自动 lease/fencing takeover 不在本 checkpoint。