checkpoint: complete recoverable V2 pre-separation baseline

Complete the selective V2 checkpoint with its minimal AgentBus, object-storage, replay persistence, and validated-workbench shared dependency closure.
This commit is contained in:
鲨鱼辣椒 committed 2026-08-20 17:09:00 +08:00
1 parent 7330ac853b
commit 694c4317a3
627 files changed
+130467 -885

No files matched your search

@@ -145,6 +145,10 @@ POST /api/open/agent-sessions
`X-DeerFlow-Open-API-Key` 鉴权,并通过 `X-Request-ID`、`idempotency_key` 和 metadata 做调用关联。
当前 TH Hotel 后端 `SuperAgentOpenApiClientImpl` 已发送 CSRF double-submit。CSRF token 由后端每次请求临时生成,不走环境变量,不作为长期 Secret 保存。
2026-08-10 对 `https://superagent.nianxx.cn` 的真实合成 smoke 证明:用户提供的 Curl 示例未携带
CSRF 时当前服务端返回 403;添加同值 `X-CSRF-Token` 与 `csrf_token` Cookie 后 session 创建成功。
因此示例文档的鉴权片段不能单独作为当前运行契约,后端 client 的 double-submit 行为必须保留。
```text
Authorization: Bearer <DEERFLOW_OPEN_API_KEY>
X-Request-ID: <stable-request-id>
@@ -189,6 +193,7 @@ TH Hotel 当前观测并处理的事件类型:
| `metadata` | 读取 Run、Thread、Profile 等调用元数据 |
| `messages` | 流式消息增量或中间消息 |
| `values` | 阶段性或最终聚合状态 |
| `message.final` | 未开启公开 Trace 时的核心最终回答,data 包含 `run_id` 与 `text` |
| `end` | SSE 正常结束标志 |
解析最终答案时,不要简单拼接所有 `messages`。当前实现从后期 `values.messages[]` 中选择:
@@ -210,18 +215,23 @@ content 非空
- `usage_metadata.total_tokens`
- 已出现的 SSE event types
如果没有收到 `end`,或无法找到最终 AI 回答,应视为协议失败,不要伪造成成功结果。
Trace 开启时仍要求公开 `run.completed status=success`;Trace 关闭时,core `message.final` 负责提供最终
文本,收到 `end` 后必须再查询 `GET /runs/{run_id}`,只有权威状态为 `success` 才成功,并从其
`metadata.resolved_profile_id` / `metadata.resolved_profile_version_id` 补齐审计字段。如果没有收到
`end`、无法找到最终回答或无法确认 run 成功,应视为协议失败,不要伪造成成功结果。
### 4.5.1 2026-07-12 SSE 断流恢复要求
2026-07-12 导入的 `docs/import/20260712/OPEN_AGENT_API_JAVA_SSE_CLIENT.md` 已补充 Java 后端调用
SuperAgent Open API 的稳定性要求。后续 TH Hotel 的共享 SuperAgent Open API client 必须满足:
- 初始 `messages/stream?include_trace=true` 请求携带稳定 `X-Request-ID`。
- 初始 `messages/stream` 请求携带稳定 `X-Request-ID`。当前 Parsing Agent 与 Booking Business Agent 必须追加
`?include_trace=true`,显式 false 在调用前 fail closed;legacy Field Recovery 仍固定默认为 false。
- 同一业务 SourceMessage 的 `idempotency_key` 在所有尝试中保持不变。
- 初始 POST 成功后保存响应头 `Content-Location`,解析并保存 SuperAgent `run_id`。
- SSE 必须按帧解析 `event:`、`data:`、`id:` 和 heartbeat comment,并保存 `lastEventId`。
- 成功条件必须同时满足最终 AI 内容、`run.completed status=success`、顶层 `event: end`,且没有顶层 `error` 或 `run.failed`。
- 成功条件必须同时满足最终 AI 内容、顶层 `event: end`、权威 run success,且没有顶层 `error` 或
`run.failed`。权威 success 可来自公开 Trace 的 `run.completed`,无 Trace 时必须来自 run status 查询。
- EOF、Premature EOF、incomplete chunked response 不能当成功。
- 如果已有 `run_id`,断流后不得重新 POST 初始消息,应先查询 `GET /runs/{run_id}`,再通过 `GET /runs/{run_id}/events` 携带 `Last-Event-ID` 恢复。
- 恢复失败应记录为可诊断失败,不返回部分回答。
@@ -272,6 +282,130 @@ usageMetadata
- Provider 内部 Plan / Memory
- 未脱敏的个人信息
### 4.8 M012 Layer 3 字段 Recovery 同步等待
M012 新增一条与旧 V4 `task-results`、MCP submit、M007 AgentBus dispatch 均独立的后端出站链路:
```text
MANUAL_EML → QBD deterministic Parser
→ RecoveryRequestSet(仅 UNRESOLVED + RECOVERABLE 字段及最小锁定上下文)
→ SuperAgent 专用解析 Agent / installed fixed-channel-field-recovery Skill
→ 信息系统在 max-wait 内等待完整 SSE 成功结果
→ 严格 JSON-only RecoveryPatchSet
→ 本地 Validator / dependency resolver / projector
→ PostgreSQL invocation audit + atomic Assembly + EffectiveFactView artifact
```
运行配置使用 `booking.field-recovery.*`,默认关闭。启用时至少需要同时满足:
- `booking.postgres.enabled=true`;
- `booking.field-recovery.enabled=true`;
- `booking.field-recovery.open-api.base-url=https://superagent.nianxx.cn`(可按环境覆盖);
- `booking.field-recovery.open-api.api-key` 由解析 Agent 专属部署 Secret 注入;
- `booking.field-recovery.open-api.include-trace=false`;当前解析 Agent 外部应用策略禁用公开 Trace;
- 该 `df_open_...` token 对应的外部应用策略已绑定安装 Recovery Skill 的已发布 Profile,并开启 API exposure;
- `max-wait` 有界且不超过 10 分钟,请求和最终回答均受字符数上限保护。
公开 API 请求不传 `profile_id`。Profile 由 token 对应的外部应用策略选择;`external_subject_id` 只是
信息系统侧主体标识,Recovery 由 `source_message_id` 哈希稳定派生。通用 client factory 只复用
session/SSE transport;解析 Agent 与未来 Booking Business Agent 必须分别建立外部应用、Secret、
wrapper/config 和调用审计,不能共享 key。
真实合成 smoke 已确认该 token 可完成 session、无 Trace SSE、core `message.final`、`end` 与 run status
success,并解析到已发布 Profile/version;完整 `RecoveryRequestSet → RecoveryPatchSet` 业务输出和
PostgreSQL V3 事务链仍待测试/预生产联调,不能据此宣称字段 Recovery 已上线。
当前 checkpoint 只允许 `MANUAL_EML` 等待。`AGENTBUS` 仍在 WebSocket frame 线程同步进入 Booking
编排器,因此明确跳过该调用;只有先把 AgentBus 的 Booking 下游迁入受控 worker 后,才可在 worker
内等待解析 Agent。Provider 输出只是 patch 建议,不直接覆盖 Parser artifact、不进入 PMS/Opera,也不在本
checkpoint 提前喂给 Layer 4/5。
### 4.9 M012 Fixed-Channel Parsing Agent v1 durable 出站边界
新的QBD/LIANTAI共用Parsing Agent不复制4.8的`MANUAL_EML`同步例外。代码已完成专属
`booking.parsing-agent.*` properties、SuperAgent wrapper、adapter及CP4 pre-Context durable主链,但Port只
能由worker调用;AgentBus WebSocket callback、手工HTTP线程和前端请求线程都不得直接等待。
```text
SourceMessage + immutable public ParserResult
→ durable execution claim/lease/fence
→ complete Current/History + deterministic evidence registry
→ fixed-channel-parsing-agent-v1 AgentRequest
→ Parsing Agent专属external app/token + shared session/SSE transport
→ resolved Profile ID gate + published version audit
→ strict local decoder/semantic validator
→ deterministic local merger
→ normalized Agent result + authoritative Layer3 artifact
```
运行边界:
- Parsing Agent、Field Recovery和Booking Business三者只共享无身份transport factory;各自拥有key、wrapper、
config、hash subject与审计,禁止fallback。
- adapter要求`include-trace=true`并由配置校验防止关闭,限制UTF-8 request/message/response bytes与整体
deadline;History超限时 fail closed,绝不截断或摘要替代。
- Trace 模式必须收到公开`run.completed(status=success)`和顶层`end`。既有execution audit仍保留安全聚合;
PostgreSQL V13共用journal另在语义解析/去重前按实际接收顺序保存每条公开事件,并保存transport最终交给decoder
的完整答案。重复投递照录,失败/超时/断流时保留已收到部分。
- journal只记录Provider返回,不记录API Key、Authorization、Cookie、CSRF、数据库密码、请求头或出站完整请求;
不推导平台未返回的隐藏思考。
- expected Profile ID必须由部署配置提供并与run metadata精确一致;实际published version只记录,不参与任务放行。
Main Prompt和Skill不由API request绑定;其平台安装/发布证据仍是单独release gate。
- adapter仍只把raw JSON作为业务候选送到进程内validator;完整返回原文由共用journal作为运行证据保存,不写入
Parser artifact,也不改变Parser-only review或Layer 3业务边界。
- 当前`booking.parsing-agent.enabled/provider-enabled/worker-enabled=false`且production强制false;CP4 fake链
完成不代表真实Provider、scheduler或生产执行已经启用。
### 4.10 M012 Booking Business Agent V2 durable 出站边界
Layer 3/4 到 Layer 5 的正式运行路径复用既有 `booking.agent.open-api.*`、
`SuperAgentBookingBusinessOpenApiClient` 和共享 SSE transport,不创建第二套 Booking client、凭据或状态机。
Booking、Parsing、Field Recovery、AgentBus 与 Debug EML 只共享无身份 transport;Booking Agent 必须使用自己的
外部应用 Secret,禁止 key fallback。
```text
final Layer3ResultV2
→ Layer 4 + canonical BookingDecisionInputV2
→ 短事务保存 Layer 3/4/input、enqueue execution、标记 AWAITING_BOOKING_AGENT
→ commit
→ V11 worker claim(SKIP LOCKED + lease + fencing)
→ 无数据库事务:专用 Booking port 调用 SuperAgent
→ Profile/版本/大小/deadline + JSON-only CandidateDecision 严格校验
→ 短事务提交 Candidate 与成功 attempt audit
→ 后续 claim 从持久 Candidate 恢复 Layer 6
```
运行边界:
- 只有 `booking.postgres.enabled`、`booking.agent.enabled`、`booking.agent.provider-enabled` 和
`booking.agent.worker-enabled` 同时为 true,durable worker 才注册;默认值与 production profile 均保持关闭。
- Provider 调用前有“当前线程无 Spring transaction”的可执行保护。Provider 超时、断流、临时网络错误或非法
Candidate 不得回滚已经提交的 Parsing、Layer 3/4 和 input。
- 同一 processing run 只有一个 execution,幂等键为 `booking-v2:<canonical input sha256>`。到期 lease 可由
重启后的 worker 接管;已保存 Candidate 只恢复 Layer 6,不再调用 Provider。
- 超时、断流、HTTP 408/425/429/5xx 和临时 transport 错误按有限次数、上限退避重试;JSON、契约、逻辑或平台
Profile 版本、input hash、evidence/reference 和大小错误不可重试,直接形成安全 `FAIL_CLOSED` Risk 后进入 Layer 6。
- 每个真正发出的 Provider attempt 必须先有受控 invocation audit;记录 input/response hash、execution/attempt、
Provider session/run/profile/version、duration、event types 与 failure class。V13 journal再以该invocation/attempt为
关联保存Provider实际返回的公开事件与最终答案原文;出站完整request、Secret、Authorization、Cookie、CSRF和
数据库密码不进入journal。
- Booking 调用必须携带`include_trace=true`,显式 false 在调用前拒绝;成功必须同时具备公开
`run.completed(status=success)`和顶层`end`。既有`public_trace_events`继续作安全聚合,完整公开返回以journal
为权威;Provider返回不做摘要、截断、脱敏或去重。
- Candidate 只是 Layer 5 候选,必须由本地 decoder 与 Layer 6 Validator 校验;Agent 不得直接创建 TaskCard、调用
PMS/Opera 或改变 Layer 6 的业务职责。
历史 CP5 证据记录测试 Profile ID `85ab8334-4e1c-4716-8ec0-9c3c099cec9b`、发布版本 ID
`9fed48c0-1f53-4d5a-8ba0-52865c738d83`(v7)及一次真实 Candidate 调用。该证据不能替代目标部署环境的当前
发布核验;本次实现环境没有专用 key、PostgreSQL 连接和 live flags,未重新查询或修改平台。放行前必须用最小
合成数据重新验证 resolved Profile ID/version,并完成 QBD、普通 LianTai 各 New/Update/Cancel/Allotment 的八场景
真实联调。该矩阵只证明核心接线,不代表 Rooming List 全业务完成。
2026-08-14 RC6 后续已用单项合成 Trace/Extra Bed 关闭“当前 resolved 身份+RC6 严格 payload”薄门禁:Profile
仍为 `85ab8334-4e1c-4716-8ec0-9c3c099cec9b`,发布 version ID 为
`b91686f4-b8b8-4ac0-aeb4-b7a2f54a0a41`,严格 Candidate/Layer 6 验证 1/1 通过。八场景、PostgreSQL 和
AgentBus 双 Agent 全链仍是独立部署门禁。
## 5. AgentBus 对接
### 5.1 运行时配置
@@ -455,6 +589,10 @@ Replay 负责:
Replay 接口默认关闭,仅在本地、UAT 或受控生产运维场景开启。
开发测试 AgentBus EML replay 的身份策略另有一项隔离规则:`PRESERVE_IDENTITY` 保留 EML 的 message/conversation
身份用于幂等验证;`FRESH_DELIVERY` 每次同时生成独立 message 与 conversation 身份。后者用于真实双 Agent 回放,
避免同一 EML 的早期调试副本被后续运行误当作真实 History;该规则不改变真实 AgentBus 入站邮件的 conversation 身份。
### 5.7 AgentBus 入库后自动分发 SuperAgent
M007 已实现的自动分发链路不是 Debug EML,也不是 SourceMessage Replay。它只负责把 AgentBus 新入库邮件异步交给 SuperAgent Open API:
@@ -649,7 +787,12 @@ SuperAgent 建议覆盖:
- SSE 正常结束并解析最终回答。
- SSE 缺少 `end` 时失败。
- SSE 缺少最终回答时失败。
- SSE 缺少 `run.completed status=success` 时失败。
- Trace 模式缺少 `run.completed status=success`,或无 Trace 模式无法通过 run status 确认 success 时失败。
- Parsing/Booking 专用客户端的初始消息 URL 精确包含 `include_trace=true`,并拒绝显式 false 配置。
- 所有公开事件在业务解析前按原 `data` 内容与交付顺序进入journal;多行/空白不改写,重连重复投递照录;最终
交给decoder的答案另有`FINAL_ANSWER`记录。
- 出站API Key、Authorization、Cookie、CSRF、数据库密码和请求头不得进入journal;平台未返回的隐藏思考不补写。
- 无 Trace core `message.final` 能提取最终回答,并由 run metadata 补齐 Profile/version。
- SSE 断流后携带 `Last-Event-ID` 通过 `/runs/{run_id}/events` 恢复,且不重发初始 POST。
- HTTP 401 / 403 / 404 / 409 / 5xx 错误转换。
- 连接超时,以及 SSE 断流后的 run/events 恢复。
@@ -691,6 +834,17 @@ SuperAgent 返回的是 Provider 输出。即使未来返回结构化 JSON,也
真实邮件、附件 URL、客户姓名和联系方式都可能是敏感数据。测试夹具应使用合成数据。
## 9.1 2026-08-17 完整公开返回与生命周期日志(ADR-017)
- fixed-channel Parsing Agent 与 Booking Business Agent 的初始 message 请求必须带 `include_trace=true`;显式
false 在调用前拒绝。legacy Field Recovery 继续 no-Trace。
- 信息系统在测试与生产使用同一V13追加式journal:SuperAgent实际返回的session响应、每条公开事件、恢复run响应、
HTTP错误正文和最终答案,按原顺序、原内容保存,并记录双时间、event/session/run/execution/invocation/attempt。
- 既有安全Provider audit继续用于聚合诊断;完整返回以journal为权威。journal不参与Parser、Layer5、Layer6或任务卡。
- 开发回放的lifecycle V2按同一replay/processing run读取journal,复制与导出复用同一JSON。读取失败返回503,不
降级为残缺日志。
- 出站凭据/请求与未返回的隐藏思考排除。旧调用保持空journal;不得重发同一消息来“补日志”,否则会启动新run。
## 10. 接入前检查清单
接入 SuperAgent 前确认:
@@ -4,9 +4,9 @@
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.11 |
| 日期 | 2026-07-22 |
| 状态 | 当前代码契约已支持 V4 订单任务 + 多卡入站、V4 S10/S99 来源通知、REST 历史 V2 `ai_task_results[]` / V3 业务根兼容、旧 S000/S999 兼容、M011 Booking Excel 调 SuperAgent 前预处理增强和单酒店 hotel_id 后端解析;MCP `th_hotel_submit_task_results` 已收口为 M002 V4-only,不再接受 V2/V3 submit payload |
| 文档版本 | 0.17 |
| 日期 | 2026-08-17 |
| 状态 | 当前代码契约已支持 V4 订单任务 + 多卡入站、V4 S10/S99 来源通知、REST 历史兼容、M011 Booking Excel 预处理和单酒店 hotel_id 解析;MCP submit 已收口为 M002 V4-only;M012另有相互隔离且默认关闭的Field Recovery、fixed-channel Parsing Agent与Booking Business Agent出站边界,其中Parsing/Booking主线调用已强制接收安全公开Trace,运行开关仍默认关闭 |
| 适用范围 | SuperAgent 调用本系统查询上下文、查询邮件会话、提交 AI 任务结果 |
| 主要读者 | SuperAgent 对接方、后端、测试、运维 |
@@ -124,8 +124,8 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID,也不需要为
- Basic Information 必须先确认;业务卡逐卡确认或复核解阻,确认后永久锁定;V4 第一版不提供前端草稿。
- `route_code=S10/S99` 使用 V4 来源通知模型,不创建隐藏技术订单,不进入订单详情时间线,不阻塞普通订单;前端只展示和 ack。
- Account / Market / Source、Room Type、Rate Code 以本系统数据库目录稳定代码为准;SuperAgent 不应输出显示文案作为业务判断依据。
- Rate Code 第一阶段按当前酒店级 `RATE_CODE` 目录校验;2026-07-21 结论是暂不按 `basic_information.account_code` + event `target_order.booking_type`(GROUP / FIT)限定候选。SuperAgent 仍只输出稳定 `rate_code`,不输出价格、显示名或目录对象。
- Room Information 卡的 Nights、Breakfast、Group Booking Status、当前值 / 最终值 / 差异摘要由本系统后端展示模型提供;SuperAgent 不输出这些展示派生字段。
- Rate Code 第一阶段按当前酒店级 `RATE_CODE` 目录校验;M012 v20260810 的新输出固定为 21 个基础 code,旧组合码只在后端输入兼容时规范化,绝不作为新候选返回。暂不按 `basic_information.account_code` + event `target_order.booking_type`(GROUP / FIT)限定候选。SuperAgent 仍只输出稳定 `rate_code`,不输出价格、显示名或目录对象。
- Room Information 卡的 Nights、Breakfast、Breakfast Restaurant、Group Booking Status、当前值 / 最终值 / 差异摘要由本系统后端展示模型提供;SuperAgent 不输出这些展示派生字段。
开发阶段不维护 V2/V3 旧任务兼容,测试数据可重建;该策略仅限开发 / 测试阶段,不代表生产迁移方案。生产数据迁移策略不在当前 checkpoint 处理,后续上线前另开迁移方案。
@@ -156,6 +156,116 @@ Debug EML 是人工调试入口,不进入 AgentBus 生产 dispatch。M002 V4 s
字段契约、抽取规则和安全边界以 `docs/project/requirements/M011-booking-excel-pre-superagent-enrichment-v1.md` 为准。SuperAgent 生成最终 V4 结果时,仍必须按本文第 8 节的 `source_message + order_contexts[] + message_events[]` 契约回调本系统。
## 3.3 M012 Layer 3 字段 Recovery 出站说明
2026-08-10 起,Booking PostgreSQL 主线具备一条默认关闭的字段 Recovery 出站 Adapter。它由 TH
Hotel 后端创建 SuperAgent session、发送最小 `RecoveryRequestSet` 并在有界 deadline 内等待完整 SSE
结果,返回值必须严格反序列化为 JSON-only `RecoveryPatchSet`,再由本地规则校验和组装。
真实 Open Agent API 契约如下:
- Base URL 为 `https://superagent.nianxx.cn`,会话接口为 `POST /api/open/agent-sessions`,消息接口为
`POST /api/open/agent-sessions/{session_id}/messages/stream`。
- 认证使用外部应用创建的 `df_open_...` Bearer token;公开请求不传 `profile_id`。外部应用策略绑定
Profile 时固定调用该 Profile 的已发布版本,未绑定时才回退组织默认 Profile;目标 Profile 必须已发布
并开启 API exposure。
- `external_subject_id` 表示调用方外部用户/会话主体,不是 Agent 或 Profile ID。Recovery 以
`source_message_id` 的 SHA-256 派生稳定、非明文 subject;session/message 幂等键继续由 Recovery
idempotency key 派生。
- Recovery 使用 `booking.field-recovery.open-api.*` 专属连接与 Secret,不回退全局 Debug/AgentBus key。
通用 client factory 也被 Booking Business Agent 使用,但两个 Agent 各自拥有独立外部应用、token、
wrapper/config 与审计,不能互相回退。
- 当前服务端要求 Bearer 鉴权请求同时携带临时 CSRF double-submit header/cookie;项目 client 已实现,
Secret、CSRF 与 raw answer 均不得落日志或持久化。
- 解析 Agent 外部应用当前禁用公开 Trace,Recovery 的 `include-trace` 默认 false。无 Trace SSE 从 core
`message.final` 读取最终文本,必须收到顶层 `end`,随后查询 run status;只有 `status=success` 才接受,
并从 run metadata 补齐实际 `resolved_profile_id` / `resolved_profile_version_id`。这是已被新 Parsing Agent
取代的 legacy Recovery 兼容边界;自 2026-08-17 起,当前 Parsing Agent 与 Booking Business Agent 主线各自
强制 `include_trace=true`,不受该例外影响。
2026-08-10 已完成一次合成、隐私最小化的真实 transport/Profile-routing smoke:session 创建、无 Trace
SSE、最终事件、结束事件和 run success 均通过;未保存或输出 raw answer/key。该证据不覆盖完整
Recovery JSON contract、PostgreSQL V3 或 `MANUAL_EML` 端到端验收。
该链路不是本文其余章节描述的“SuperAgent 回调 TH Hotel”接口:它不使用 HMAC `task-results`,不使用
MCP submit,也不复用 M007 AgentBus dispatch。当前只从 `MANUAL_EML` 触发;`AGENTBUS` 必须在 Booking
下游 worker 化后才能启用等待。详细契约、开关、持久化和验收见
`docs/project/requirements/M012-layer3-field-recovery-superagent-integration-change-request-v1.md`。
## 3.4 M012 Layer 5 Booking Business Agent 出站说明
2026-08-10 建立的专用 transport 已在 2026-08-14 接入 V2 durable runtime。当前权威路径不再使用旧
`BookingAgentContinuationDispatcher` 同步链:后端先在短 PostgreSQL 事务中提交最终 Layer 3、Layer 4、
canonical `BookingDecisionInputV2`、唯一 `booking_agent_execution` 与 `AWAITING_BOOKING_AGENT`,再由 V11
worker claim lease/fence,并在无数据库事务时发送受控 `BookingBusinessAgentInputV1`、等待完整
SSE/Provider run。严格 Candidate 单独提交后,由后续 claim 恢复 Layer 6。它不在保存 Parsing 结果的事务、
HTTP/AgentBus WebSocket callback 中等待,也不新增浏览器、MCP 或第三方入口。
- Business 使用 `booking.agent.open-api.*` 和 `TH_HOTEL_BOOKING_BUSINESS_AGENT_OPEN_API_*` 专属配置;
API Key 只能通过专用部署 Secret 注入,不回退 Recovery、Debug EML、AgentBus 或全局 Open API key。
- 公开请求同样不传 `profile_id`,由 Business token 对应的外部应用策略选择已发布 Profile。
- `external_subject_id` 由 `source_message_id` 的 SHA-256 派生为
`th-hotel-booking-business-<hash>`,不再由部署提供固定主体,也不承担 Profile 路由。
- Business 必须使用 `include-trace=true`,初始消息请求固定为
`messages/stream?include_trace=true`;显式配置 false 时在调用 Provider 前 fail closed。Trace 成功必须同时
收到公开 `run.completed(status=success)` 与顶层 `end`,core `message.final` 不能替代完成证据。
- 平台公开 Trace 经安全投影进入 `public_trace_events` 供 invocation audit/回放使用;
`message.delta` / `message.final` 的文本只在内存中参与最终回答组装,不复制到公开轨迹。URL、Secret、
Authorization、Cookie 与 CSRF 脱敏并限长;V2 raw answer 和完整 request 仍不落库。
- Provider 输出仍只是候选。JSON-only、contract/profile/run/source/revision/input hash、evidence 和引用闭包均
由本地严格 decoder 校验,随后必须经过 Layer 6;不得直接创建任务。耗尽或不可重试错误形成安全
`FAIL_CLOSED` Risk,不回退本地业务分类。
- `booking.postgres.enabled`、`booking.agent.enabled`、`booking.agent.provider-enabled` 和
`booking.agent.worker-enabled` 四门同时成立才启动真实 worker;默认 false,production profile 显式固定 false。
- V11 execution 提供稳定 input-hash 幂等、有限重试/退避、重启恢复和 Candidate apply-once;每个 Provider
attempt 写受控 audit。V2 raw answer、完整 request、邮件正文与 Secret 不落审计。
2026-08-10 首轮真实合成 smoke 只验证了 Business token 的 session scope,message stream 当时因 Profile
API exposure 未开启返回 HTTP 403。2026-08-11 用户启用外部 API/流式接口并发布后,no-Trace 复测已通过
session/stream 200、非空 `message.final`、`end`、无 failure event 和 run `success`;实际
`resolved_profile_id=85ab8334-4e1c-4716-8ec0-9c3c099cec9b`,
`resolved_profile_version_id=1711d4ed-8d0d-46fa-9d1f-4bb2d61fde23`。测试期间未输出或保存 API
Key/raw answer。
上段是 2026-08-11 的历史 transport 证据,其占位 Prompt 结论已被 2026-08-14 CP5 取代:测试平台后来发布
正式 Booking v7(version `9fed48c0-1f53-4d5a-8ba0-52865c738d83`),并有一次正式
CandidateDecisionV2→严格 decoder→Layer 6 的合成真实 smoke。当前实现环境没有专用 key/PG/live flags,未重新
查询平台或执行 QBD/LianTai 八场景与 V1–V11 smoke,因此部署时仍须复核当前 resolved Profile/version;历史
CP5不能作为自动 runtime/production 放行。详细变更与放行清单见
`docs/project/requirements/M012-booking-business-agent-superagent-integration-change-request-v1.md`与ADR-015。
2026-08-14 后续 RC6 发布/绑定后的单项合成 Trace smoke 已完成当前身份复核:resolved Profile 仍为
`85ab8334-4e1c-4716-8ec0-9c3c099cec9b`,发布 version ID 为
`b91686f4-b8b8-4ac0-aeb4-b7a2f54a0a41`。严格 Candidate/Layer 6 验证 1/1 通过;默认 expected version gate
同步,但自动 runtime、完整场景矩阵和 production 仍关闭。
## 3.5 M012 Fixed-Channel Parsing Agent v1 出站说明
2026-08-12 起,代码中具备一条默认/production关闭、CP4已完成内部主链与fake验收的fixed-channel Parsing
Agent v1边界。它面向QBD/LIANTAI共用v1契约,不复用旧Field Recovery PatchSet或Booking Business
CandidateDecision;SourceMessage loader、公共Parser、durable execution/worker、local merge和Context已接通,
真实scheduler/Provider仍受CP5开关关闭。
- 使用`booking.parsing-agent.*`和`TH_HOTEL_BOOKING_PARSING_AGENT_*`专属配置;API key不回退任何现有
Agent/global key。只有Booking PostgreSQL和Parsing Agent两个开关同时开启时才注册wrapper/adapter。
- 公开请求仍不传`profile_id`;专属token对应external app选择已发布Profile。信息系统要求返回的实际
Profile ID与`expected-profile-id`精确一致,否则整份结果拒绝;实际发布version只进入运行审计,不参与放行。
- Current source message ID只以SHA-256派生external subject和metadata hash;稳定v1 request ID同时作为
session/message幂等根与`X-Request-ID`。完整AgentRequest JSON作为message唯一业务payload,History不截断。
- request/message/response均有UTF-8 bytes上限,超限不裁剪;外呼在独立有界executor中等待整体deadline,
队列满、超时或不可用均fail closed。Parsing Agent 必须使用`include_trace=true`,显式 false 在调用前拒绝;
完整`message.final + run.completed(status=success) + end`由共享 Open API transport保证。
- 平台公开轨迹通过既有安全 DTO 进入 Parsing execution audit/回放;`message.delta` / `message.final`文本不进入
可持久轨迹,URL/Secret/Cookie/CSRF脱敏并限长,raw answer与完整request继续不保存。
- Adapter只返回raw JSON给本地strict decoder/semantic validator;Provider不能直接形成effective facts。
已返回但因Profile/大小/metadata被拒绝时,只审计response SHA-256和安全session/run/Profile/model/token
metadata,不保存raw answer、完整request、Secret、Cookie、CSRF、附件或隐藏推理。
- `booking.parsing-agent.enabled/provider-enabled/worker-enabled`默认false,`application-prod.yml`显式固定false。真实Profile/app/token、
独立Main Prompt SHA、Skill package SHA/version、API exposure与合成smoke均属于CP5独立放行Gate。
详细运行契约见
`docs/project/requirements/M012-fixed-channel-parsing-agent-v1-runtime-integration-change-request-v1.md`。
## 4. 接口 1:查询订单上下文
### 4.1 请求
@@ -531,7 +641,7 @@ V4 普通业务包示例:
},
"arrival_date": "2026-07-26",
"departure_date": "2026-07-29",
"rate_code": "GRPA2-850UP",
"rate_code": "GRPA2",
"booking_scenario": "STANDARD",
"room_items": [
{
@@ -588,10 +698,10 @@ V4 字段说明:
| `message_events[]` | 普通业务必填 | 逐 event 入站,后端按数组顺序处理。 |
| `message_events[].event_type` | 是 | 第一版支持 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`TRACE_RESERVATION_NOTES`、`ROOMING_LIST`、`PAYMENT`。 |
| `message_events[].target_order` | 是 | `GROUP + GROUP_CODE`,或 `FIT + BOOKING_CODE / CONFIRMATION_NUMBER`。 |
| `message_events[].rate_code` | NEW_BOOKING 必填,可为 `null` | Rate Code 稳定 code;第一阶段只要求属于当前酒店 `ACTIVE` 的 `RATE_CODE` 目录。 |
| `message_events[].rate_code` | NEW_BOOKING 必填,可为 `null` | 基础 Rate Code 稳定 code;第一阶段只要求属于当前酒店 `ACTIVE` 的 21 项 `RATE_CODE` 目录。历史组合码可由后端输入兼容规范为基础码,但新 Agent 不应输出。 |
| `message_events[].manual_review` | 是 | 只能是 `null` 或布尔 `true`;`true` 必须能由当前对象中的未解决字段解释。 |
| Room Information 展示派生字段 | 不需要 | Nights、Breakfast、Group Booking Status、Adult、Block ID、Confirmation Number、当前订单值和差异摘要均由本系统后端查询或派生;SuperAgent 不输出。 |
| New Booking 最终订单展示名 | 不需要 | Group Block Name / Fit Name 是信息系统最终订单投影字段,可由用户在 V4 任务卡中确认前编辑;Group 默认来自 `target_order.locator_value` 且 `locator_type=GROUP_CODE`,Fit 默认来自 `guest_name ?? target_order.locator_value`;SuperAgent 仍只输出 `target_order.locator_value` 作为目标定位线索,系统不得回写修改该原始定位值。 |
| Room Information 展示派生字段 | 不需要 | Nights、Breakfast、Breakfast Restaurant、Group Booking Status、Adult、Block ID、Confirmation Number、当前订单值和差异摘要均由本系统后端查询或派生;SuperAgent 不输出。 |
| New Booking 订单标识与真实姓名 | 不需要 | 信息系统对 FIT/GROUP 均投影独立 `group_code` 与 `names_text`。Group Code 来源别名或 `GROUP_CODE` locator 只能进入 `group_code`;`guest_name` 只能进入真实姓名。缺失保持空,FIT 的 Booking Code / Confirmation Number locator 不得补到任一字段;SuperAgent 原始 `target_order.locator_value` 不被用户回写。 |
| `TRACE_RESERVATION_NOTES.trace_items[].department_code` | Trace 必填 | 第一版固定为 `FO` / `HSK` / `FO+HSK`,不接受自由文本;正式 Department 目录后续再扩展。 |
| `ROOMING_LIST` 专属业务字段 | 不需要 | 第一版只识别 Rooming List 事项并生成可确认任务卡;SuperAgent 不输出名单 rows、同住分组、附件 ID、Excel 或 PMS 导入参数。 |
| `PAYMENT.attachment_ids[]` | PAYMENT 必填 | 必须引用同包 `source_message.attachments[].id`;SuperAgent 不在 PAYMENT event 内复制附件名称、URL 或完整附件对象。第一版这些 ID 是只读业务事实,用户只确认卡片,不增删或替换附件集合;前端图片缩略图 / 大图预览和非图片下载由本系统根据这些 ID 匹配 SourceMessage 附件后提供。 |
@@ -601,7 +711,7 @@ V4 字段说明:
- 命中 SourceMessage 后保存 AI batch / transition,并按 `source_message + order_contexts[] + message_events[]` 处理。
- 普通业务包按 `source_message + order_ref` 创建 V4 订单任务,并创建 `SOURCE_MESSAGE_DISPLAY`、`BASIC_INFORMATION` 和业务事件卡。
- Basic Information 必须先确认;业务卡逐卡确认或复核解阻,确认后永久锁定;V4 第一版不提供前端草稿。
- `ROOM_INFORMATION` 卡只由 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING` 触发;New / Update / Cancel 的最终值、差异、Nights、Breakfast、Group Booking Status 和本地订单投影展示由本系统后端展示模型提供,不扩大 SuperAgent 输入契约。
- `ROOM_INFORMATION` 卡只由 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING` 触发;New / Update / Cancel 的最终值、差异、Nights、Breakfast、Breakfast Restaurant、Group Booking Status 和本地订单投影展示由本系统后端展示模型提供,不扩大 SuperAgent 输入契约。
- `ROOMING_LIST` 卡第一版只做事项确认;用户点击“确认卡片”表示已人工处理,不代表名单已解析、Excel 已生成或 PMS 已导入。确认不修改 Group Booking Status 或同订单其他卡片,不要求 SuperAgent 在 `ROOMING_LIST` event 中额外输出字段。
- `route_code=S10/S99` 创建 V4 来源通知,工作台可见,订单列表和订单详情不可见;来源通知只能 ack,不创建订单、不阻塞订单。
- V4 包级结构错误如果仍能通过 `source_message.source_message_id` 定位 SourceMessage,会返回成功接收并写入 `adapter_contract_error` transition;不创建订单任务、任务卡或来源通知。`source_message_id` 缺失或找不到 SourceMessage 时仍返回明确错误。