实现SuperAgent特殊入口结果处理
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## 1. 文档定位
|
||||
|
||||
本文记录后端侧提醒前端开发时必须注意的项目规范、业务规则、接口边界和安全要求。当前内容服务于 Reservation 任务详情、订单详情、任务列表、Message Notification 等第一版页面。
|
||||
本文记录后端侧提醒前端开发时必须注意的项目规范、业务规则、接口边界和安全要求。当前内容服务于 Reservation 任务详情、订单详情、任务列表、S000/S999 特殊只读任务、历史 Message Notification 等第一版页面。
|
||||
|
||||
## 2. 项目开发注意事项
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
- 用户可以修改任务字段内容;最终确认后,后端使用 `confirmed_payload_json` 作为 OPERA 模拟输入来源。
|
||||
- 同一订单下,前置任务未结束时,后续任务只能查看,不能编辑、确认或执行 OPERA 模拟操作。
|
||||
- 任务状态 `FAILED` 第一版视为结束状态,不阻塞后续任务;但失败的 OPERA 操作不能跳过,必须展示失败原因并允许重试。
|
||||
- Message Notification 挂临时订单,只读展示,不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
|
||||
- SuperAgent 新入口结果只会生成 `normal_task`、`manual_review` 或纯文本 `S000/S999`;`informational_message` 仅历史兼容,新页面不要再按新数据入口依赖它。
|
||||
- `S000` 表示纯信息类邮件,`S999` 表示无法形成业务素材包。后端会创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务,任务列表可见,订单列表不可见。
|
||||
- `SOURCE_MESSAGE_ONLY` 任务不允许编辑、确认、人工转换订单、执行 OPERA 或重试 OPERA;不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
|
||||
- 历史 Message Notification 挂临时订单,只读展示,不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
|
||||
- Fallback / manual_review 转为 New / Update / Cancel 时需要展示审计轨迹;登录权限底座已提供,具体业务审计 actor 迁移仍后置。
|
||||
- 普通任务切换订单接口已确认后置,前端第一版不要把普通任务拖拽或切换订单做成可提交能力。
|
||||
|
||||
@@ -39,10 +42,10 @@
|
||||
| `POST /api/auth/login` | 用户名密码登录 | 成功后返回 `access_token`、当前用户、可访问酒店、权限码和可见菜单;token 只放 `sessionStorage`,不要放 `localStorage`、URL、日志或错误上报。 |
|
||||
| `GET /api/auth/me` | 恢复当前登录态 | 前端启动后带 `Authorization: Bearer <access_token>` 调用;401 时清理 token 并进入登录页。 |
|
||||
| `POST /api/auth/logout` | 登出当前 session | 带 `Authorization: Bearer <access_token>`;成功后前端必须清理本地 token 和当前用户上下文。 |
|
||||
| `GET /api/reservation/orders` | 查询订单列表 | 默认返回全部订单状态;`open_task_count` 排除 `COMPLETED` 和 `FAILED`;用 `next_processable_task_id` 引导用户继续处理。 |
|
||||
| `GET /api/reservation/tasks` | 查询任务列表 / 工作台 | 用 `can_process` 和 `readonly_reason_code` 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL;已返回来源邮件会话摘要字段,并支持 `order_status` 按任务所属订单状态筛选。 |
|
||||
| `GET /api/reservation/orders/{orderId}` | 查询订单详情与任务时间线 | `include_tasks=false` 可只取订单摘要;时间线按后端队列顺序返回,前端不要自行按创建时间重排;`tasks[]` 已返回来源邮件会话摘要字段。 |
|
||||
| `GET /api/reservation/tasks/{taskId}` | 查询任务详情 | 以返回的可处理状态和只读原因控制按钮,不只看任务状态;`fields[]` 已包含 P0 字段元数据。 |
|
||||
| `GET /api/reservation/orders` | 查询订单列表 | 默认返回全部订单状态;`open_task_count` 排除 `COMPLETED` 和 `FAILED`;隐藏技术订单不返回,因此 S000/S999 不会在订单列表形成订单。 |
|
||||
| `GET /api/reservation/tasks` | 查询任务列表 / 工作台 | 用 `can_process` 和 `readonly_reason_code` 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL;已返回来源邮件会话摘要字段,并支持 `order_status` 按任务所属订单状态筛选;S000/S999 会以 `task_type=SOURCE_MESSAGE_ONLY` 返回。 |
|
||||
| `GET /api/reservation/orders/{orderId}` | 查询订单详情与任务时间线 | `include_tasks=false` 可只取订单摘要;时间线按后端队列顺序返回,前端不要自行按创建时间重排;`tasks[]` 已返回来源邮件会话摘要字段;隐藏技术订单详情不可作为普通订单页打开。 |
|
||||
| `GET /api/reservation/tasks/{taskId}` | 查询任务详情 | 以返回的可处理状态和只读原因控制按钮,不只看任务状态;`fields[]` 已包含 P0 字段元数据;`SOURCE_MESSAGE_ONLY` 详情字段列表和 OPERA 操作列表为空,并通过 `source_message_only_result` 返回 S000/S999 入口结果。 |
|
||||
| `PUT /api/reservation/tasks/{taskId}/draft` | 保存任务草稿 | 只保存草稿,不代表用户最终确认。 |
|
||||
| `POST /api/reservation/tasks/{taskId}/confirm` | 最终确认任务 | 后端会做第一版字段校验,通过后进入 `READY`。 |
|
||||
| `POST /api/reservation/tasks/{taskId}/manual-review-conversions` | Fallback 人工转换 | 只用于 manual_review / fallback,不用于普通任务切换订单。 |
|
||||
@@ -66,7 +69,7 @@
|
||||
| `GET /api/reservation/orders/{orderId}` | 补齐 `tasks[]` 每条任务的来源邮件会话摘要字段。 | `include_tasks=false` 可只取订单摘要;时间线顺序由后端按订单队列返回,前端不要自行按创建时间重排。`include_source_summary` 第一版不作为前端裁剪字段的强约束,前端暂不要依赖它减少返回字段。 |
|
||||
| `GET /api/reservation/tasks/{taskId}` | 补齐顶层来源邮件字段,并扩展 `fields[]` 元数据。 | 顶层来源字段用于打开邮件会话;`fields[]` 中的 `result_type`、`task_type`、`task_subtype`、`default_value_source` 用于前端字段分组、调试和白名单对齐。 |
|
||||
| `GET /api/source-messages/{sourceMessageId}/conversation` | 新增邮件会话详情接口,并补齐 `html_body_sanitized` / `html_render_mode`。 | 当前唯一推荐路径是这个接口;前端渲染邮件 HTML 时优先使用 `html_body_sanitized`;不要调用历史讨论过的 `/api/source-message-conversations/{externalConversationId}`。 |
|
||||
| `POST /api/system/debug/eml-superagent-runs` | 新增 Debug EML 上传到 SuperAgent 调试接口,并补齐独立 Debug 外部消息 ID、原始 Message-ID 保留和安全 HTML 字段。 | 只用于调试页面;请求为 multipart/form-data;必须传 `X-TH-Hotel-Debug-Upload-Key`,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报。 |
|
||||
| `POST /api/system/debug/eml-superagent-runs` | 新增 Debug EML 上传到 SuperAgent 调试接口,并补齐独立 Debug 外部消息 ID、原始 Message-ID 保留、安全 HTML 字段和 S000/S999 识别。 | 只用于调试页面;请求为 multipart/form-data;必须传 `X-TH-Hotel-Debug-Upload-Key`,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报;SuperAgent 返回 S000/S999 时不是 JSON 解析失败。 |
|
||||
|
||||
### 5.2 登录权限接入注意
|
||||
|
||||
@@ -123,6 +126,9 @@ POST /api/auth/logout
|
||||
- `next_processable_task_id` 是后端按同订单队列实时计算出的下一条可处理任务;前端可以用它做“继续处理”入口。
|
||||
- `display_order_key` 是前端优先展示的订单业务号或临时订单号;`group_code` 和 `confirmation_number` 只有在当前订单业务号类型匹配时返回。
|
||||
- 订单 ID、任务 ID、SourceMessage ID 在这些前端接口中按字符串返回,前端不要转换成 JavaScript number。
|
||||
- `SOURCE_MESSAGE_ONLY` 任务背后有隐藏技术订单用于满足后端任务外键,但订单列表不会返回该订单;任务列表中该类任务的 `display_order_key`、`temporary_order_no`、`group_code`、`confirmation_number` 可能为空,前端不要因此隐藏整条任务。
|
||||
- 任务列表里 `task_type=SOURCE_MESSAGE_ONLY`、`task_subtype=S000/S999` 的记录只展示邮件来源和 SuperAgent 入口结果,不展示处理按钮。
|
||||
- 任务详情里 `source_message_only_result` 仅对 `SOURCE_MESSAGE_ONLY` 返回,包含 `entry_result_code`、`entry_result_meaning`、`entry_result_description`、`entry_result_source_message_id` 和 `raw_answer`;普通任务该字段为空。
|
||||
|
||||
### 5.6 前端联调演示数据 seed 接口
|
||||
|
||||
@@ -159,7 +165,7 @@ Content-Type: application/json
|
||||
- 已完成 New Booking 任务和两条 OPERA 模拟成功记录。
|
||||
- OPERA 模拟失败任务,可在任务详情看到失败 attempt 和重试入口。
|
||||
- Fallback / manual_review 任务。
|
||||
- Message Notification 只读任务。
|
||||
- 历史 Message Notification 只读任务;S000/S999 特殊只读任务可通过 SuperAgent 回调或后续专用夹具补充。
|
||||
- 同一邮件会话下多封邮件、完整 HTML、附件外链和内联图片外链。
|
||||
|
||||
### 5.7 任务详情字段元数据接入注意
|
||||
|
||||
@@ -35,7 +35,7 @@ Debug EML 页面第一版只做一件事:
|
||||
| 执行状态区 | loading、成功、失败、耗时、本次 `debug_run_id` | 提交后禁用按钮,避免重复点击;失败时展示安全错误摘要。 |
|
||||
| SourceMessage 追溯区 | `source_message_id`、`source_provider`、`external_message_id`、`external_conversation_id` | 用于确认已写入 SourceMessage Inbox。 |
|
||||
| 邮件内容预览区 | `html_body_sanitized`、纯文本、附件列表、内联图片列表 | HTML 展示必须优先使用 `html_body_sanitized`。 |
|
||||
| SuperAgent 结果区 | `superagent_parsed_json`、`superagent_raw_answer`、`warnings[]` | JSON 可以格式化展示;raw answer 用于排查 SuperAgent 非 JSON 输出。 |
|
||||
| SuperAgent 结果区 | `superagent_parsed_json`、`superagent_raw_answer`、`warnings[]` | JSON 可以格式化展示;S000/S999 会被后端识别成结构化入口结果;raw answer 用于排查其他非 JSON 输出。 |
|
||||
| 调试 Payload 区 | `agentbus_like_payload` | 只用于调试展示,不让用户编辑后重新提交。 |
|
||||
|
||||
## 4. 接口
|
||||
@@ -120,7 +120,7 @@ export async function uploadDebugEml(input: {
|
||||
| `superagent_session_id` | string | SuperAgent session ID。 |
|
||||
| `superagent_run_id` | string | SuperAgent run ID。 |
|
||||
| `superagent_raw_answer` | string | SuperAgent 最终原始文本回答。 |
|
||||
| `superagent_parsed_json` | object/null | 后端尝试解析出的 JSON;解析失败时可能为空。 |
|
||||
| `superagent_parsed_json` | object/null | 后端尝试解析出的 JSON;S000/S999 会返回识别后的对象,其他解析失败时可能为空。 |
|
||||
| `warnings[]` | string[] | 安全或解析警告,可在页面顶部或结果区展示。 |
|
||||
| `status` | string | Debug run 状态。 |
|
||||
|
||||
@@ -143,6 +143,18 @@ export async function uploadDebugEml(input: {
|
||||
- `agentbus_like_payload.source.original_message_id` 是原始邮件 `Message-ID`。
|
||||
- `external_message_id` 是 Debug 链路生成的独立 ID,不等同于原始 `Message-ID`。
|
||||
- `superagent_parsed_json` 有值时优先展示格式化 JSON;没有值时展示 `superagent_raw_answer`。
|
||||
- 如果 SuperAgent 返回 `S000,source_message_id` 或 `S999,source_message_id`,后端会把它识别为特殊入口结果,不会作为 JSON 解析失败处理。前端可在结果区展示 `entry_result_code`、`entry_result_source_message_id`、`entry_result_meaning` 和 `entry_result_description`。
|
||||
|
||||
S000/S999 解析示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"entry_result_code": "S000",
|
||||
"entry_result_source_message_id": "mail-20260708-0001",
|
||||
"entry_result_meaning": "PURE_INFORMATION",
|
||||
"entry_result_description": "纯信息类邮件"
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 错误响应
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
| P0 | 邮件会话详情接口 `GET /api/source-messages/{sourceMessageId}/conversation` | 邮件会话详情页 | 已完成第一版 |
|
||||
| 联调 | 演示数据 seed 接口 `POST /api/system/reservation/demo-data` | 本地 / test 前端页面看效果 | 已完成;仅 dev/test 受控使用 |
|
||||
| 联调 | Debug EML 上传接口 `POST /api/system/debug/eml-superagent-runs` | Debug 页面上传 `.eml` 看 SuperAgent 结果 | 已完成第一版;仅 dev/test 受控使用 |
|
||||
| P1 | Message Notification 列表 / 详情接口 | 信息提醒页或订单详情只读卡片 | 未完成独立接口;可先通过任务列表 / 任务详情展示 `INFORMATIONAL_MESSAGE` |
|
||||
| P1 | S000/S999 特殊只读任务展示 | 任务列表、任务详情来源邮件查看 | 已完成后端第一版;通过任务列表 / 任务详情展示 `SOURCE_MESSAGE_ONLY`,不做独立 Message Notification 接口 |
|
||||
| P1 | 任务卡前端字段白名单元数据接口 | 字段白名单调试、版本对齐 | 未完成;若任务详情已透出完整元数据,可后置 |
|
||||
| 后置 | 普通任务切换订单接口 | 任务详情订单归属调整 | 未完成;已确认后置 |
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
| `POST /api/system/reservation/demo-data` | 已完成 | 仅本地 / test 联调可用 | 默认关闭,必须后端配置访问口令;不能作为生产页面接口。 |
|
||||
| `POST /api/system/debug/eml-superagent-runs` | 已完成第一版 | 仅 dev/test Debug 页面可用 | 默认关闭,必须后端配置访问口令、阿里云 OSS 和 SuperAgent Open API;第一版只展示 SuperAgent 结果,不创建订单和任务。 |
|
||||
| `GET /api/source-message-conversations/{externalConversationId}` | 未发现后端实现 | 不可以 | 历史讨论过的候选路径,当前不提供;前端统一使用 `GET /api/source-messages/{sourceMessageId}/conversation`。 |
|
||||
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 如需独立信息提醒页再新增;第一版可先用任务接口过滤。 |
|
||||
| `GET /api/reservation/message-notifications` | 未发现后端实现 | 不可以 | 第一版不做独立接口;新入口 S000/S999 已通过 `SOURCE_MESSAGE_ONLY` 任务展示。 |
|
||||
| `GET /api/reservation/task-card-field-whitelist` | 未发现后端实现 | 不可以 | 若任务详情 `fields[]` 已补齐 3.0 元数据,可后置。 |
|
||||
|
||||
## 3. 任务列表 / 工作台接口字段补齐
|
||||
@@ -86,7 +86,7 @@ GET /api/reservation/tasks
|
||||
| --- | --- | --- |
|
||||
| `hotel_id` | 否 | 酒店 ID。第一版如果只有单酒店,可为空。 |
|
||||
| `order_id` | 否 | 按订单过滤。 |
|
||||
| `task_type` | 否 | `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`、`INFORMATIONAL_MESSAGE`。 |
|
||||
| `task_type` | 否 | `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`、`INFORMATIONAL_MESSAGE`、`SOURCE_MESSAGE_ONLY`。其中 `INFORMATIONAL_MESSAGE` 仅历史兼容,新入口 S000/S999 使用 `SOURCE_MESSAGE_ONLY`。 |
|
||||
| `task_status` | 否 | 任务状态过滤。 |
|
||||
| `task_subtype` | 否 | 任务卡 subtype 过滤。 |
|
||||
| `order_status` | 否 | 按任务所属订单状态过滤,支持 `TEMPORARY`、`ACTIVE`、`ENDED`、`LOGIC_DELETED`;不传时保持当前行为。 |
|
||||
@@ -300,7 +300,7 @@ POST /api/system/reservation/demo-data
|
||||
| `tasks[]` | 生成的任务 ID、任务类型、任务 subtype 和任务状态。 |
|
||||
| `entrypoints` | 可直接访问的任务列表、订单列表、订单详情、任务详情、邮件会话详情 URL。 |
|
||||
|
||||
第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、Message Notification、邮件会话完整 HTML / 附件 / 内联图片。
|
||||
第一版 seed 覆盖:队列阻塞、已完成 OPERA 模拟、OPERA 失败可重试、Fallback 人工复核、历史 Message Notification 只读任务、邮件会话完整 HTML / 附件 / 内联图片。S000/S999 特殊只读任务可通过 SuperAgent 回调或后续专用夹具补充。
|
||||
|
||||
前端注意:不要把访问口令写入前端仓库、浏览器环境变量或构建产物;该接口只能由本地联调人员手动调用或由受控测试脚本调用。
|
||||
|
||||
@@ -502,11 +502,23 @@ GET /api/reservation/tasks/{taskId}
|
||||
- 如果后端已有更细的字段来源或适用场景元数据,可后续再扩展 `field_source`、`applicable_scenario`,不作为本轮 P0 阻塞项。
|
||||
- 前端已统一配置 `VITE_RESERVATION_HOTEL_ID`,并会在 `GET /api/reservation/orders`、`GET /api/reservation/tasks`、`GET /api/reservation/orders/{orderId}` 自动传 `hotel_id`。当前 `GET /api/reservation/tasks/{taskId}` 以及任务写操作 Controller 不接收 `hotel_id`;第一版先按 ID 定位,后续多酒店隔离 / 权限方案统一补齐。
|
||||
|
||||
## 9. Message Notification 列表 / 详情接口
|
||||
## 9. S000/S999 特殊只读任务与历史 Message Notification
|
||||
|
||||
当前状态:未发现后端独立 Message Notification 列表 / 详情接口。当前后端已经支持 `INFORMATIONAL_MESSAGE` 任务类型进入任务体系,第一版前端可以先通过 `GET /api/reservation/tasks?task_type=INFORMATIONAL_MESSAGE` 和 `GET /api/reservation/tasks/{taskId}` 展示信息提醒任务。仅当产品确认需要独立“信息提醒页”时,再新增本节接口。
|
||||
当前状态:后端不提供独立 Message Notification 列表 / 详情接口。SuperAgent 新入口返回 `S000,source_message_id` 或 `S999,source_message_id` 时,后端会创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务,第一版前端通过 `GET /api/reservation/tasks?task_type=SOURCE_MESSAGE_ONLY` 和 `GET /api/reservation/tasks/{taskId}` 展示。
|
||||
|
||||
建议路径:
|
||||
历史 `INFORMATIONAL_MESSAGE` 仍可通过任务列表 / 任务详情兼容展示,但新数据不要依赖它。
|
||||
|
||||
展示规则:
|
||||
|
||||
- `task_type=SOURCE_MESSAGE_ONLY`、`task_subtype=S000`:纯信息类邮件。
|
||||
- `task_type=SOURCE_MESSAGE_ONLY`、`task_subtype=S999`:无法形成业务素材包。
|
||||
- 任务列表可见,订单列表不可见。
|
||||
- 任务详情只允许查看来源邮件、会话、附件和 SuperAgent 原始返回。
|
||||
- 任务详情通过 `source_message_only_result` 返回 `entry_result_code`、`entry_result_meaning`、`entry_result_description`、`entry_result_source_message_id` 和 `raw_answer`。
|
||||
- 不显示编辑、确认、人工转换、执行 OPERA 或重试 OPERA 按钮。
|
||||
- 不参与订单任务执行顺序阻塞。
|
||||
|
||||
当前不建议新增路径:
|
||||
|
||||
```text
|
||||
GET /api/reservation/message-notifications
|
||||
@@ -529,13 +541,15 @@ GET /api/reservation/message-notifications/{taskId}
|
||||
{
|
||||
"task_id": "10009",
|
||||
"order_id": "20009",
|
||||
"task_type": "INFORMATIONAL_MESSAGE",
|
||||
"task_type": "SOURCE_MESSAGE_ONLY",
|
||||
"task_subtype": "S000",
|
||||
"task_status": "COMPLETED",
|
||||
"queue_participation": false,
|
||||
"readonly": true,
|
||||
"visible_reason": "FYI message without booking operation",
|
||||
"visible_reason": "S000 pure information entry result",
|
||||
"relevant_message_excerpt": "Noted with thanks.",
|
||||
"informational_message": "该消息仅作信息提醒,不需要执行 OPERA 操作。",
|
||||
"entry_result_code": "S000",
|
||||
"entry_result_description": "纯信息类邮件",
|
||||
"attachments": [],
|
||||
"source_message_id": "30009",
|
||||
"external_conversation_id": "thread-20260708-009",
|
||||
@@ -615,5 +629,5 @@ POST /api/reservation/tasks/{taskId}/order-binding
|
||||
- 订单列表、任务列表当前统一使用 `items + page` 分页结构;邮件会话详情不分页,返回同一会话全部邮件。
|
||||
- 邮件会话详情接口已优先使用 `GET /api/source-messages/{sourceMessageId}/conversation`。
|
||||
- 任务详情 `fields[]` 已由后端直接透出 P0 需要的 3.0 元数据;独立字段白名单接口后置。
|
||||
- Message Notification 是否独立成页面,还是只在订单详情中展示。
|
||||
- 独立 Message Notification 页面继续后置;新入口 S000/S999 第一版先在任务列表和任务详情展示。
|
||||
- 邮件会话全文读取的审计策略由后端内部处理;前端不保存原文读取 key。
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- `GET /api/source-messages/{id}/original`:受控读取邮件原文、HTML 和媒体 URL,并记录访问审计。
|
||||
- `GET /api/system/agentbus-probe`:查看 AgentBus WebSocket 连接状态和安全计数器。
|
||||
- AgentBus WebSocket 入站链路:默认关闭,开启后只把业务 frame 写入 SourceMessage Inbox。
|
||||
- SuperAgent 任务结果接收接口:接收一个外部 `source_message_id` 下的 AI 任务结果,反查 SourceMessage Inbox 后写入 AI 过渡层、订单、任务和任务卡。
|
||||
- SuperAgent 任务结果接收接口:接收一个外部 `source_message_id` 下的 AI 任务结果,反查 SourceMessage Inbox 后写入 AI 过渡层、订单、任务和任务卡;同时支持 `S000/S999,source_message_id` 文本入口结果并创建只读特殊任务。
|
||||
- Reservation 任务详情接口:返回任务字段、队列可处理状态和 OPERA 模拟操作摘要。
|
||||
- Reservation 任务草稿保存和最终确认接口:按任务卡矩阵做第一版后端校验,确认后生成 `confirmed_payload_json`。
|
||||
- Reservation OPERA 模拟骨架:已确认任务固定生成两条模拟操作,支持执行、失败重试、attempt 记录和任务审计列表。
|
||||
@@ -43,6 +43,7 @@
|
||||
- 所有 Secret 都通过环境变量、部署平台 Secret 或密钥管理系统注入,不写入仓库、镜像、前端环境变量或普通配置文件。
|
||||
- 生产默认不保存 AgentBus raw frame 样本。
|
||||
- AgentBus 实时链路开启前,已经确认 WebSocket URL、Token、Bot Address、外部消息幂等键和断线重连语义。
|
||||
- S000/S999 特殊入口结果上线前,必须确认 `AGENTBUS_DEFAULT_HOTEL_ID` 已配置且对应 SourceMessage Inbox 入库酒店一致。
|
||||
- 原文读取接口开启前,已经确认谁可以使用、在哪些场景使用、如何轮换访问 key。
|
||||
- 日志采集、错误响应和监控面板都不会展示邮件正文、HTML、附件 URL、Token、Cookie、客户姓名、邮箱、电话或支付信息。
|
||||
|
||||
@@ -128,7 +129,10 @@
|
||||
- 查询接口和任务结果通知接口使用同一套 Header、签名串、secret、timestamp 和 nonce 规则。
|
||||
- SuperAgent 侧也需要配置同一个 secret,并按原始请求体计算 SHA-256。
|
||||
- 当前第一版只支持一个 HMAC secret,secret 轮换需要协调部署窗口。
|
||||
- 任务结果通知接口里的 `source_message_id` 是外部来源消息 ID,对应 AgentBus `source.external_message_id`;正式请求必须带 `hotel_id`,后端用 `hotel_id + provider + channel + external_message_id` 反查内部 SourceMessage Inbox。
|
||||
- 任务结果通知接口 JSON body 里的 `source_message_id` 是外部来源消息 ID,对应 AgentBus `source.external_message_id`;正式 JSON 请求必须带 `hotel_id`,后端用 `hotel_id + provider + channel + external_message_id` 反查内部 SourceMessage Inbox。
|
||||
- 任务结果通知接口也支持 `text/plain` 的 `S000,source_message_id` 和 `S999,source_message_id`。这类请求不在 body 里带 `hotel_id`,后端使用 `AGENTBUS_DEFAULT_HOTEL_ID` 查询 SourceMessage Inbox。
|
||||
- `application/json` 和 `text/plain` 都必须使用原始请求体计算 SHA-256 并参与 HMAC 签名;SuperAgent 侧不能签名格式化后的 JSON 或二次拼接字符串。
|
||||
- S000/S999 会创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务和隐藏技术订单,任务列表可见,订单列表不可见,不允许编辑、确认、转换订单或执行 OPERA。
|
||||
- SuperAgent 查询上下文接口中的 `source_message_id`、`source_event_index` 第一版仅兼容接收,不参与查询和校验;不要依赖它们限制查询范围。
|
||||
|
||||
### 3.6 Debug EML / SuperAgent Open API / 阿里云 OSS
|
||||
@@ -162,6 +166,7 @@
|
||||
- Debug EML 写入 SourceMessage Inbox 时 `provider=DEBUG_EML_UPLOAD`,不能伪装为 AgentBus 来源。
|
||||
- Debug EML 写入 SourceMessage Inbox 时 `external_message_id` 是后端生成的 `debug-eml-run-{debugRunId}-{sha256前缀}`;原始邮件 `Message-ID` 只保存在 payload 的 `source.original_message_id`。
|
||||
- Debug EML 返回 `html_body_sanitized`、`html_sanitize_required`、`html_render_mode`,前端展示 HTML 时应优先使用清洗字段。
|
||||
- Debug EML 会识别 SuperAgent Open API 返回的 `S000/S999,source_message_id`,并在 `superagent_parsed_json` 中返回结构化入口结果;这不是 JSON 解析失败。
|
||||
- Debug EML 第一版只展示 SuperAgent 结果,不创建订单、不创建任务、不调用任务结果通知接口。
|
||||
- AgentBus 实时收到邮件后自动推 SuperAgent 当前未实现,不能把 Debug EML 链路等同于生产实时自动处理链路。
|
||||
|
||||
@@ -178,6 +183,7 @@
|
||||
- `server/src/main/resources/db/migration/V4__harden_reservation_task_queue_and_manual_conversion.sql`
|
||||
- `server/src/main/resources/db/migration/V5__add_reservation_task_draft_and_confirmation.sql`
|
||||
- `server/src/main/resources/db/migration/V6__create_reservation_opera_simulation_tables.sql`
|
||||
- `server/src/main/resources/db/migration/V11__add_reservation_order_visibility.sql`
|
||||
|
||||
当前 M004 Debug EML 相关 migration:
|
||||
|
||||
@@ -203,6 +209,7 @@
|
||||
- 入住日期、离店日期、酒店营业日属于酒店本地业务日期,不应因为 UTC 换算而自动前后偏移。
|
||||
- 执行 V4 前,如果目标库已有 M002 试运行数据,必须先检查 ACTIVE 订单业务号重复和同订单任务队列序号重复。
|
||||
- 执行 V5 / V6 前,如果目标库已有 M002 试运行数据,必须确认任务草稿、确认 payload 和 OPERA 模拟操作表允许从空数据开始补齐;不要手工伪造已确认 payload 或 attempt 历史。
|
||||
- 执行 V11 前,如果目标库已有手工造数或历史隐藏订单方案,必须确认是否需要回填 `order_visibility`;默认值 `VISIBLE` 会让历史订单继续出现在订单列表。
|
||||
|
||||
V4 前置检查 SQL:
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.3 |
|
||||
| 日期 | 2026-07-09 |
|
||||
| 状态 | 已增加邮件会话任务和受控正文查询接口 |
|
||||
| 文档版本 | 0.4 |
|
||||
| 日期 | 2026-07-10 |
|
||||
| 状态 | 已增加 S000/S999 特殊入口结果处理 |
|
||||
| 适用范围 | SuperAgent 调用本系统查询上下文、查询邮件会话、提交 AI 任务结果 |
|
||||
| 主要读者 | SuperAgent 对接方、后端、测试、运维 |
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
| 参数 | 当前联调值 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
| `TH_HOTEL_API_BASE_URL` | `http://8.138.234.141:18087` | 本系统后端基础地址;本地联调用 8080,部署环境改为实际网关或服务地址。 |
|
||||
| `HOTEL_ID` | `HOTEL-DEV` | 当前 dev profile 下 AgentBus 入库默认酒店 ID;调用五个 SuperAgent 接口时均应传入请求体 `hotel_id`。 |
|
||||
| `HOTEL_ID` | `HOTEL-DEV` | 当前 dev profile 下 AgentBus 入库默认酒店 ID;查询接口和 JSON 任务结果请求体应传入 `hotel_id`,S000/S999 文本结果使用本系统默认酒店。 |
|
||||
| `SUPERAGENT_CLIENT_ID` | `superagent-debug` | SuperAgent 调用方 ID,对应 Header `X-TH-Hotel-SuperAgent-Client-Id`。 |
|
||||
| `SUPERAGENT_HMAC_SECRET` | `th-hotel-superagent-debug-20260709-change-before-prod` | dev/test 联调临时 HMAC 密钥;生产上线前必须更换为新的高强度随机密钥。 |
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
| Header | 是否必填 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
| `Content-Type` | 是 | 固定 `application/json` |
|
||||
| `Content-Type` | 是 | 查询接口固定 `application/json`;任务结果通知接口支持 `application/json` 或 `text/plain` |
|
||||
| `X-TH-Hotel-SuperAgent-Client-Id` | 是 | SuperAgent 调用方客户端 ID |
|
||||
| `X-TH-Hotel-SuperAgent-Timestamp` | 是 | UTC ISO-8601 时间,例如 `2026-07-08T01:30:00Z` |
|
||||
| `X-TH-Hotel-SuperAgent-Nonce` | 是 | 每次请求唯一随机值,用于防重放 |
|
||||
@@ -81,14 +81,14 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
### 2.3 服务端校验顺序
|
||||
|
||||
1. 校验请求体大小。
|
||||
2. 校验 HMAC 相关 Header 是否存在。
|
||||
3. 校验 timestamp 是否在允许时间窗口内。
|
||||
4. 计算原始请求体 SHA-256。
|
||||
5. 使用共享 secret 重新计算 HMAC。
|
||||
6. 常量时间比较签名。
|
||||
7. 校验并记录 `client_id + nonce`,防止重放。
|
||||
8. 查询接口校验 `Content-Type` 是否为 `application/json`。
|
||||
9. 鉴权和协议校验通过后再解析业务 JSON。
|
||||
2. 查询接口校验 `Content-Type` 是否为 `application/json`;任务结果通知接口校验是否为 `application/json` 或 `text/plain`,不支持的媒体类型不消耗 nonce。
|
||||
3. 校验 HMAC 相关 Header 是否存在。
|
||||
4. 校验 timestamp 是否在允许时间窗口内。
|
||||
5. 计算原始请求体 SHA-256。
|
||||
6. 使用共享 secret 重新计算 HMAC。
|
||||
7. 常量时间比较签名。
|
||||
8. 校验并记录 `client_id + nonce`,防止重放。
|
||||
9. 鉴权和协议校验通过后再解析业务 JSON 或 S000/S999 文本结果。
|
||||
|
||||
## 3. SourceMessage ID 口径
|
||||
|
||||
@@ -437,10 +437,10 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID。任务结果通
|
||||
| Method | `POST` |
|
||||
| URL | `{TH_HOTEL_API_BASE_URL}/api/integrations/superagent/task-results` |
|
||||
| request_path | `/api/integrations/superagent/task-results` |
|
||||
| Content-Type | `application/json` |
|
||||
| 业务动作 | 接收 AI 任务结果,写入 AI 过渡层、订单、任务和任务卡 |
|
||||
| Content-Type | `application/json` 或 `text/plain` |
|
||||
| 业务动作 | 接收 AI 任务结果;JSON 写入业务订单和任务,S000/S999 创建只读特殊任务 |
|
||||
|
||||
### 8.2 请求体
|
||||
### 8.2 JSON 请求体
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -487,7 +487,7 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID。任务结果通
|
||||
| `ai_task_results[].source_event_index` | 是 | AI current 事件序号 |
|
||||
| `ai_task_results[].catalog_code` | 是 | Skill 目录代码 |
|
||||
| `ai_task_results[].skill_id` | 是 | Skill 标识 |
|
||||
| `ai_task_results[].result_type` | 是 | `normal_task`、`manual_review`、`informational_message` |
|
||||
| `ai_task_results[].result_type` | 是 | 新入口只接受 `normal_task`、`manual_review`;`informational_message` 仅历史兼容 |
|
||||
| `ai_task_results[].task_type` | 是 | AI 原始任务类型 |
|
||||
| `ai_task_results[].task_subtype` | 否 | 业务动作 subtype |
|
||||
| `ai_task_results[].case_keys` | 否 | 订单关联候选键 |
|
||||
@@ -495,7 +495,33 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID。任务结果通
|
||||
|
||||
正式联调时,后端通过 `hotel_id + source_provider(默认 AGENTBUS) + source_channel(默认 EMAIL) + source_message_id` 查找 `platform_source_message_inbox.external_message_id`。如果没有找到,返回 `SOURCE_MESSAGE_NOT_FOUND`。本地旧夹具允许在缺少 `hotel_id` 时使用内部数字 SourceMessage ID,但该兼容路径不作为 SuperAgent 正式契约。
|
||||
|
||||
### 8.3 成功响应
|
||||
`informational_message` 结构化任务仅用于历史兼容。新入口如果是纯信息类邮件或无法形成业务素材包,不要提交空数组,也不要生成 `informational_message`;应使用下面的 S000/S999 文本请求体。
|
||||
|
||||
### 8.3 S000/S999 文本请求体
|
||||
|
||||
纯信息类邮件:
|
||||
|
||||
```text
|
||||
S000,mail-20260708-0001
|
||||
```
|
||||
|
||||
无法形成业务素材包:
|
||||
|
||||
```text
|
||||
S999,mail-20260708-0001
|
||||
```
|
||||
|
||||
字段规则:
|
||||
|
||||
| 片段 | 中文说明 |
|
||||
| --- | --- |
|
||||
| `S000` | 纯信息类邮件,不需要形成业务任务。 |
|
||||
| `S999` | 入口阶段无法形成业务素材包,不需要进入业务执行。 |
|
||||
| `mail-20260708-0001` | 外部来源消息 ID,对应 SourceMessage Inbox 的 `external_message_id`。 |
|
||||
|
||||
第一版 S000/S999 不在 body 里传 `hotel_id`,后端使用系统默认酒店 `AGENTBUS_DEFAULT_HOTEL_ID` 查询 SourceMessage Inbox。命中后创建 `SOURCE_MESSAGE_ONLY` 只读特殊任务:任务列表可见,订单列表不可见,不允许编辑、确认、转换订单、执行 OPERA 或重试 OPERA,也不参与同订单任务执行顺序阻塞。
|
||||
|
||||
### 8.4 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -522,6 +548,33 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID。任务结果通
|
||||
}
|
||||
```
|
||||
|
||||
S000/S999 成功响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "req-004",
|
||||
"source_message_id": "mail-20260708-0001",
|
||||
"batch_id": "1900000000000000500",
|
||||
"idempotent_replay": false,
|
||||
"accepted_count": 1,
|
||||
"items": [
|
||||
{
|
||||
"source_event_index": 1,
|
||||
"array_index": 1,
|
||||
"ai_transition_id": "1900000000000000550",
|
||||
"order_id": "1900000000000000600",
|
||||
"task_id": "1900000000000000700",
|
||||
"system_task_type": "SOURCE_MESSAGE_ONLY",
|
||||
"task_card_type": "SOURCE_MESSAGE_ONLY",
|
||||
"task_status": "COMPLETED",
|
||||
"order_status": "TEMPORARY",
|
||||
"execution_order": 1
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
## 9. 错误响应
|
||||
|
||||
### 9.1 查询接口错误响应
|
||||
@@ -562,13 +615,13 @@ SuperAgent 不应知道或依赖内部 SourceMessage Inbox ID。任务结果通
|
||||
| `AUTH_SIGNATURE_INVALID` | 401 | 签名不匹配或服务端未配置 secret |
|
||||
| `AUTH_NONCE_REPLAY` | 409 | nonce 已被使用 |
|
||||
| `REQUEST_BODY_TOO_LARGE` | 413 | 请求体超过大小限制 |
|
||||
| `REQUEST_CONTENT_TYPE_UNSUPPORTED` | 415 | `Content-Type` 不是 `application/json` |
|
||||
| `REQUEST_BODY_INVALID` | 400 | JSON 不合法 |
|
||||
| `REQUEST_CONTENT_TYPE_UNSUPPORTED` | 415 | 查询接口 `Content-Type` 不是 `application/json`,或任务结果通知接口不是 `application/json` / `text/plain` |
|
||||
| `REQUEST_BODY_INVALID` | 400 | JSON 不合法,或 S000/S999 文本格式不符合 `结果码,source_message_id` |
|
||||
| `QUERY_KEY_REQUIRED` | 400 | 查询接口缺少可用业务 key |
|
||||
| `MESSAGE_CONVERSATION_QUERY_KEY_REQUIRED` | 400 | 会话查询缺少 `external_conversation_id` 或 `source_message_id` |
|
||||
| `OBJECT_NOT_FOUND` | 404 | 对象详情查询目标不存在 |
|
||||
| `MESSAGE_CONVERSATION_NOT_FOUND` | 404 | 外部邮件会话尚未写入 SourceMessage Inbox |
|
||||
| `HOTEL_ID_REQUIRED` | 400 | 五个 SuperAgent 接口缺少必填 `hotel_id` |
|
||||
| `HOTEL_ID_REQUIRED` | 400 | 查询接口和 JSON 任务结果缺少必填 `hotel_id`;S000/S999 使用系统默认酒店 |
|
||||
| `SOURCE_MESSAGE_NOT_FOUND` | 404 | 任务结果通知或会话锚点引用的外部来源消息尚未写入 SourceMessage Inbox |
|
||||
|
||||
## 10. HMAC 上线配置
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.2 |
|
||||
| 日期 | 2026-07-07 |
|
||||
| 文档版本 | 0.3 |
|
||||
| 日期 | 2026-07-10 |
|
||||
| 状态 | 第二版需求与后端阶段实现记录 |
|
||||
| 适用范围 | SourceMessage 之后的 AI 过渡层、订单挂靠、任务卡、人工确认、OPERA 模拟操作主流程 |
|
||||
| 主要读者 | 产品、后端、前端、测试、后续协作 agent |
|
||||
@@ -14,17 +14,18 @@
|
||||
|
||||
本文是 `M002-order-task-workflow-v1.md` 的第二版修正,目标是把本项目已经讨论确认的订单任务主流程,与 2026-07-06 导入的 AI 任务卡契约对齐。
|
||||
|
||||
本文定义业务边界、数据语义和后续实现约束。当前后端已经按拆分 checkpoint 实现了 AI 结果接收、订单任务基础流转、任务草稿保存、最终确认、审计列表、OPERA 模拟骨架、SuperAgent 查询上下文接口 1、2 的最小字段版,以及前端 P0 任务列表 / 订单详情查询接口;前端页面、真实 OPERA、普通任务切换订单、查询接口 3 和查询接口 4 仍未实现。
|
||||
本文定义业务边界、数据语义和后续实现约束。当前后端已经按拆分 checkpoint 实现了 AI 结果接收、S000/S999 特殊入口结果、订单任务基础流转、任务草稿保存、最终确认、审计列表、OPERA 模拟骨架、SuperAgent 查询上下文接口 1、2 的最小字段版,以及前端 P0 任务列表 / 订单详情查询接口;前端页面、真实 OPERA、普通任务切换订单、查询接口 3 和查询接口 4 仍未实现。
|
||||
|
||||
## 2. 本版核心修正
|
||||
|
||||
相对 V1,本版有以下修正:
|
||||
|
||||
- 增加 `AI 过渡层`:系统必须先保存 AI 原始输出,再生成订单、任务和任务卡。
|
||||
- 不再使用 `EXCEPTION` 作为底层结果类型,AI 第一版结果类型统一以 `normal_task`、`manual_review`、`informational_message` 为准。
|
||||
- 系统主任务类型收敛为 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`,另保留 `INFORMATIONAL_MESSAGE` 作为不参与执行队列的只读提醒任务。
|
||||
- 不再使用 `EXCEPTION` 作为底层结果类型,SuperAgent 结构化 JSON 新入口只使用 `normal_task` 和 `manual_review`;`informational_message` 仅保留历史兼容。
|
||||
- 新增 SuperAgent 纯文本入口结果 `S000,source_message_id` 和 `S999,source_message_id`:两者都生成只读 `SOURCE_MESSAGE_ONLY` 特殊任务,任务列表可见,订单列表不可见。
|
||||
- 系统主任务类型收敛为 `NEW_BOOKING`、`UPDATE_BOOKING`、`CANCEL_BOOKING`、`MANUAL_REVIEW`,另保留历史 `INFORMATIONAL_MESSAGE`,并新增 `SOURCE_MESSAGE_ONLY` 用于 S000/S999 特殊入口结果。
|
||||
- 除 `New Booking`、`Cancel Booking`、`Fallback/manual_review` 外,其他业务处理类卡片原则上都归到 `UPDATE_BOOKING` 下的不同任务卡。
|
||||
- `Message Notification` 也挂到临时订单下面,便于归档和详情查看,但不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
|
||||
- `Message Notification` / `INFORMATIONAL_MESSAGE` 只作为历史兼容路径;新数据中的纯信息类邮件由 `S000` 表达。
|
||||
- 任务卡后端完整规则以 `任务卡展示编辑矩阵.xlsx` 为权威来源,不在代码里随意扩展或重命名字段路径。
|
||||
- 前端展示 / 编辑白名单以最新导入的 `任务卡前端展示字段表 3.0.xlsx` 为准;该文件只约束前端展示和可编辑范围,不替代后端完整校验、确认写入和 OPERA 映射规则。
|
||||
- 系统必须同时保存 AI 原始 `task_type`、系统主任务类型、任务卡类型和业务动作 subtype。
|
||||
@@ -69,16 +70,27 @@ AgentBus / 未来其他入口
|
||||
→ 系统保存每条模拟操作结果、失败原因和重试记录
|
||||
```
|
||||
|
||||
特殊分支:
|
||||
|
||||
```text
|
||||
SuperAgent 返回 S000,source_message_id 或 S999,source_message_id
|
||||
→ 本系统按默认酒店 + external_message_id 反查 SourceMessage Inbox
|
||||
→ 创建隐藏技术订单 + SOURCE_MESSAGE_ONLY 只读任务
|
||||
→ 任务列表可见,订单列表不可见
|
||||
→ 不允许编辑、确认、转换、OPERA 模拟或重试
|
||||
```
|
||||
|
||||
中文说明:
|
||||
|
||||
- `SourceMessage Inbox` 是来源事实层,不表达订单、任务或业务结论。
|
||||
- AI 只输出 JSON,不直接写数据库、不直接创建真实任务卡、不直接写 OPERA。
|
||||
- 本系统负责保存 AI 原始 JSON、创建任务卡、接收用户修改、生成确认后的 payload、执行 OPERA 模拟并记录结果。
|
||||
- SuperAgent 不直连本系统数据库,只能通过本系统后端接口查询已有订单和任务上下文。
|
||||
- S000/S999 不是业务任务,也不是人工复核任务,只是来源邮件入口处理结论。
|
||||
|
||||
## 5. AI 输出接收边界
|
||||
|
||||
导入文档已经定义了 SuperAgent / Main Agent 应输出的核心业务结构,但还没有定义完整 HTTP 接口契约。
|
||||
导入文档已经定义了 SuperAgent / Main Agent 应输出的核心业务结构。当前正式 HTTP 接口同时支持结构化 JSON 和 S000/S999 纯文本入口结果。
|
||||
|
||||
AI 聚合输出的顶层结构应包含:
|
||||
|
||||
@@ -88,14 +100,14 @@ AI 聚合输出的顶层结构应包含:
|
||||
| `ai_task_results[]` | AI 拆分出的一个或多个任务结果,顺序必须保留 |
|
||||
| `extraction_warnings[]` | 抽取警告,不直接等同于业务任务 |
|
||||
|
||||
`ai_task_results[]` 中关键字段包括:
|
||||
结构化 JSON 的 `ai_task_results[]` 中关键字段包括:
|
||||
|
||||
| 字段 | 中文说明 |
|
||||
| --- | --- |
|
||||
| `source_event_index` | AI 拆分出的 current 事件序号,同一次来源消息内用于排序 |
|
||||
| `catalog_code` | Skill 目录代码,例如 S01、S02 |
|
||||
| `skill_id` | 具体 Skill 标识 |
|
||||
| `result_type` | AI 结果类型,第一版只使用 `normal_task`、`manual_review`、`informational_message` |
|
||||
| `result_type` | AI 结果类型,新入口只使用 `normal_task`、`manual_review`;`informational_message` 仅历史兼容 |
|
||||
| `task_type` | AI 原始任务类型,例如 `New Booking`、`Voucher Received` |
|
||||
| `task_subtype` / 业务动作 | 更细的业务动作,用于任务卡字段路由 |
|
||||
| `current_or_history` | 当前事件还是历史证据 |
|
||||
@@ -106,12 +118,27 @@ AI 聚合输出的顶层结构应包含:
|
||||
| `context_used` | AI 使用的上下文摘要 |
|
||||
| `extracted_fields` | 业务字段主体 |
|
||||
| `manual_review` | 人工复核结构化原因和证据 |
|
||||
| `informational_message` | 信息提醒内容 |
|
||||
| `informational_message` | 信息提醒内容,仅历史兼容 |
|
||||
| `additional_operations` | AI 建议的附加动作 |
|
||||
| `idempotency_key` | 幂等键,最终来源和生成规则待确认 |
|
||||
|
||||
HTTP 契约已在 `docs/project/requirements/M002-superagent-task-result-api-contract.md` 和 `docs/project/integrations/superagent-api-contract.md` 中补充。正式契约要求任务结果通知携带 `hotel_id + source_message_id`,其中 `source_message_id` 是外部来源消息 ID;后端会反查内部 SourceMessage Inbox ID 后再写入 `workflow_*` 表。
|
||||
|
||||
纯文本入口结果格式:
|
||||
|
||||
```text
|
||||
S000,source_message_id
|
||||
S999,source_message_id
|
||||
```
|
||||
|
||||
中文说明:
|
||||
|
||||
- `S000` 表示纯信息类邮件,不形成业务素材包。
|
||||
- `S999` 表示入口阶段无法形成业务素材包。
|
||||
- `source_message_id` 是外部来源消息 ID,对应 AgentBus `source.external_message_id`。
|
||||
- 第一版使用系统默认酒店反查 SourceMessage Inbox。
|
||||
- 命中 SourceMessage 后创建 `SOURCE_MESSAGE_ONLY` 只读任务,并挂到 `order_visibility=HIDDEN_SYSTEM` 的技术订单下。
|
||||
|
||||
## 6. AI 过渡层数据要求
|
||||
|
||||
系统接收 AI 输出后,应先写入 AI 过渡层,再创建任务卡。过渡层用于追溯、幂等、筛选、人工确认和 OPERA 参数组装。
|
||||
@@ -124,7 +151,7 @@ HTTP 契约已在 `docs/project/requirements/M002-superagent-task-result-api-con
|
||||
| `case_keys_json` | AI 给出的订单关联候选键 |
|
||||
| `extracted_fields_json` | AI 抽取的业务字段 |
|
||||
| `manual_review_json` | 人工复核信息 |
|
||||
| `informational_message_json` | 信息提醒内容 |
|
||||
| `informational_message_json` | 信息提醒内容,仅历史兼容 |
|
||||
| `attachments_json` | 附件和文件引用 |
|
||||
| `context_used_json` | AI 使用的上下文 |
|
||||
| `confirmed_payload_json` | 用户修改并确认后的最终参数 |
|
||||
@@ -137,9 +164,9 @@ HTTP 契约已在 `docs/project/requirements/M002-superagent-task-result-api-con
|
||||
| `source_event_index` | AI 事件序号 |
|
||||
| `catalog_code` | Skill 目录代码 |
|
||||
| `skill_id` | Skill 标识 |
|
||||
| `result_type` | AI 结果类型 |
|
||||
| `result_type` | AI 结果类型;S000/S999 内部保存为 `source_message_only` |
|
||||
| `ai_task_type` | AI 原始任务类型 |
|
||||
| `system_task_type` | 系统主任务类型 |
|
||||
| `system_task_type` | 系统主任务类型,S000/S999 为 `SOURCE_MESSAGE_ONLY` |
|
||||
| `task_card_type` | 任务卡类型 |
|
||||
| `task_subtype` | 业务动作 subtype |
|
||||
| `current_or_history` | 当前或历史标识 |
|
||||
@@ -159,15 +186,17 @@ HTTP 契约已在 `docs/project/requirements/M002-superagent-task-result-api-con
|
||||
|
||||
### 7.1 AI 结果类型
|
||||
|
||||
AI 第一版结果类型只接受:
|
||||
AI 新入口结构化 JSON 结果类型只接受:
|
||||
|
||||
| `result_type` | 中文说明 | 是否可直接 OPERA 模拟 |
|
||||
| --- | --- | --- |
|
||||
| `normal_task` | 可生成业务任务卡的正常任务 | 需用户确认后才允许 |
|
||||
| `manual_review` | 需要人工复核的结构化任务 | 不允许直接写 OPERA |
|
||||
| `informational_message` | 只读信息提醒 | 不允许写 OPERA |
|
||||
| `informational_message` | 只读信息提醒,仅历史兼容 | 不允许写 OPERA |
|
||||
|
||||
不使用 `exception_task` 和 `no_action`。原来讨论中的异常任务,在本版统一落为 `manual_review`;没有业务动作的信息提醒,统一落为 `informational_message`。
|
||||
不使用 `exception_task` 和 `no_action`。原来讨论中的异常任务,在本版统一落为 `manual_review`;没有业务动作的信息类邮件,新入口不再生成 `informational_message` JSON,而是返回 `S000,source_message_id`。
|
||||
|
||||
S000/S999 不属于结构化 `result_type`,它们是纯文本入口结果,系统内部保存为 `source_message_only` 过渡记录和 `SOURCE_MESSAGE_ONLY` 只读任务。
|
||||
|
||||
### 7.2 系统主任务类型
|
||||
|
||||
@@ -179,7 +208,8 @@ AI 第一版结果类型只接受:
|
||||
| `UPDATE_BOOKING` | 更新订单任务,下面承载多个不同任务卡 |
|
||||
| `CANCEL_BOOKING` | 取消订单任务 |
|
||||
| `MANUAL_REVIEW` | 人工复核或 Fallback 任务 |
|
||||
| `INFORMATIONAL_MESSAGE` | 信息提醒任务,只归档展示,不参与执行队列 |
|
||||
| `INFORMATIONAL_MESSAGE` | 信息提醒任务,只归档展示,不参与执行队列,仅历史兼容 |
|
||||
| `SOURCE_MESSAGE_ONLY` | S000/S999 来源消息入口结果任务,只读展示,不参与执行队列 |
|
||||
|
||||
### 7.3 AI 任务类型到系统任务和卡片的映射
|
||||
|
||||
@@ -193,16 +223,38 @@ AI 第一版结果类型只接受:
|
||||
| `Trace / Reservation Notes` | `UPDATE_BOOKING` | `TRACE_RESERVATION_NOTES` | Trace 或备注卡,可作为联动任务 |
|
||||
| `TA Recorder` | `UPDATE_BOOKING` | `TA_RECORDER` | TA Recorder 维护卡,通常由 Rooming List 派生 |
|
||||
| `Cancel Booking` | `CANCEL_BOOKING` | `CANCEL_BOOKING` | 取消 FIT、Group Block、Allotment / Control Block |
|
||||
| `Message Notification` | `INFORMATIONAL_MESSAGE` | `MESSAGE_NOTIFICATION` | 挂临时订单,只读展示,不参与执行队列 |
|
||||
| `Message Notification` | `INFORMATIONAL_MESSAGE` | `MESSAGE_NOTIFICATION` | 历史兼容路径;新纯信息类邮件改用 S000 |
|
||||
| `Fallback` | `MANUAL_REVIEW` | `FALLBACK_REVIEW` | 人工复核任务 |
|
||||
| `S000` 文本结果 | `SOURCE_MESSAGE_ONLY` | `SOURCE_MESSAGE_ONLY` | 纯信息类邮件,任务列表可见,订单列表不可见 |
|
||||
| `S999` 文本结果 | `SOURCE_MESSAGE_ONLY` | `SOURCE_MESSAGE_ONLY` | 无法形成业务素材包,任务列表可见,订单列表不可见 |
|
||||
|
||||
系统不得丢弃 AI 原始 `task_type`。任务落库时应同时保存 AI 原始任务类型、系统主任务类型、任务卡类型和业务动作 subtype。
|
||||
|
||||
## 8. Message Notification 处理规则
|
||||
## 8. S000/S999 和历史 Message Notification 处理规则
|
||||
|
||||
### 8.1 S000/S999 处理规则
|
||||
|
||||
`S000` / `S999` 是 SuperAgent 入口阶段返回的纯文本结果,不是结构化任务 JSON。
|
||||
|
||||
本系统处理规则:
|
||||
|
||||
- `S000` 表示纯信息类邮件。
|
||||
- `S999` 表示无法形成业务素材包。
|
||||
- 两者都按外部 `source_message_id` 反查 SourceMessage Inbox。
|
||||
- 第一版使用系统默认酒店,不要求请求体携带 `hotel_id`。
|
||||
- 创建 `SOURCE_MESSAGE_ONLY` 只读任务,`task_subtype` 分别为 `S000` 或 `S999`。
|
||||
- 创建 `order_visibility=HIDDEN_SYSTEM` 的技术订单,仅用于满足任务归属,不进入订单列表和订单详情。
|
||||
- 任务状态为 `COMPLETED`,`queue_participation=false`。
|
||||
- 任务列表可见;订单列表不可见。
|
||||
- 任务详情可查看来源邮件、会话、附件和 SuperAgent 原始返回。
|
||||
- 不允许保存草稿、最终确认、人工转换、普通切换订单、执行 OPERA 模拟或重试 OPERA。
|
||||
- 不阻塞任何订单任务,也不被任何订单任务阻塞。
|
||||
|
||||
### 8.2 历史 Message Notification 处理规则
|
||||
|
||||
`Message Notification` 用于感谢、知会、已收到、转发说明、信息同步等没有明确业务执行动作的消息。
|
||||
|
||||
本系统处理规则:
|
||||
该路径仅为历史兼容,新数据应由 SuperAgent 返回 `S000,source_message_id`。历史数据处理规则:
|
||||
|
||||
- 创建临时订单作为归档容器。
|
||||
- 创建只读信息提醒任务卡。
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
| --- | --- |
|
||||
| 文档版本 | 0.2 |
|
||||
| 日期 | 2026-07-07 |
|
||||
| 文档版本 | 0.3 |
|
||||
| 日期 | 2026-07-10 |
|
||||
| 状态 | 后端接口契约草稿 |
|
||||
| 适用范围 | SuperAgent / Main Agent 调用本系统提交 AI 任务结果 |
|
||||
| 主要读者 | 后端、SuperAgent 对接方、测试、后续协作 agent |
|
||||
|
||||
## 1. 文档定位
|
||||
|
||||
本文定义 SuperAgent / Main Agent 向本系统提交 `ai_task_results[]` 的第一版后端接口契约。
|
||||
本文定义 SuperAgent / Main Agent 向本系统提交 `ai_task_results[]` 结构化结果,以及提交 S000/S999 特殊入口结果的后端接口契约。
|
||||
|
||||
本文承接 `M002-order-task-workflow-v2.md`,只定义本系统入站接口、鉴权、幂等、请求响应和技术校验边界,不定义 SuperAgent 内部 prompt、Skill 实现、OPERA 真实接口或前端展示细节。
|
||||
|
||||
@@ -22,17 +22,19 @@
|
||||
| --- | --- |
|
||||
| Method | `POST` |
|
||||
| Path | `/api/integrations/superagent/task-results` |
|
||||
| Content-Type | `application/json` |
|
||||
| Content-Type | `application/json` 或 `text/plain` |
|
||||
| 响应格式 | `application/json` |
|
||||
| 一次请求范围 | 只能包含一个 `source_message_id` |
|
||||
| 业务动作 | 接收 AI 结果、写入 AI 过渡层、生成订单 / 任务 / 任务卡 |
|
||||
| 业务动作 | 接收 AI 结果或入口结果、写入 AI 过渡层、生成订单 / 任务 / 任务卡 |
|
||||
| 鉴权方式 | HMAC-SHA256 签名 |
|
||||
|
||||
中文说明:
|
||||
|
||||
- 该接口是服务到服务的入站接口,不给前端直接调用。
|
||||
- SuperAgent 不直连数据库,只能通过本接口提交任务结果。
|
||||
- SuperAgent 不直连数据库,只能通过本接口提交任务结果或入口处理结果。
|
||||
- 本接口只做技术校验和系统接收,不替代用户确认和 OPERA 模拟操作。
|
||||
- `application/json` 用于 `normal_task` / `manual_review` 结构化任务。
|
||||
- `text/plain` 用于 `S000,source_message_id` / `S999,source_message_id` 特殊入口结果。
|
||||
|
||||
### 2.1 SourceMessage ID 口径
|
||||
|
||||
@@ -114,13 +116,16 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
4. 计算原始请求体 SHA-256。
|
||||
5. 使用 HMAC secret 重新计算签名。
|
||||
6. 使用常量时间比较签名。
|
||||
7. 鉴权通过后再解析 JSON。
|
||||
7. 校验 `Content-Type` 是否为 `application/json` 或 `text/plain`,避免不支持的媒体类型消耗 nonce。
|
||||
8. 鉴权通过后再按 body 内容解析 JSON 或 S000/S999 文本。
|
||||
|
||||
日志和错误响应不得输出 secret、签名原文、完整请求体、邮件正文、附件 URL 或个人敏感信息。
|
||||
|
||||
## 4. 请求体
|
||||
|
||||
请求体沿用 AI 导入文档定义的聚合结构。
|
||||
### 4.1 JSON 结构化任务请求体
|
||||
|
||||
JSON 请求体沿用 AI 导入文档定义的聚合结构。
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -155,7 +160,7 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
}
|
||||
```
|
||||
|
||||
### 4.1 顶层字段
|
||||
### 4.2 顶层字段
|
||||
|
||||
| 字段 | 是否必填 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
@@ -166,16 +171,16 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
| `ai_task_results[]` | 是 | AI 拆分出的任务结果列表,必须保留数组顺序 |
|
||||
| `extraction_warnings[]` | 否 | 抽取警告;不直接等同于业务任务 |
|
||||
|
||||
第一版要求 `ai_task_results[]` 至少包含一条记录。没有业务动作时应由 AI 输出 `Message Notification` 或 `Fallback/manual_review`,而不是提交空数组。
|
||||
第一版要求 `ai_task_results[]` 至少包含一条记录。没有业务动作的纯信息类邮件不要提交空数组,也不要新生成 `informational_message`;应改用 `S000,source_message_id` 文本结果。
|
||||
|
||||
### 4.2 `ai_task_results[]` 字段
|
||||
### 4.3 `ai_task_results[]` 字段
|
||||
|
||||
| 字段 | 是否必填 | 中文说明 |
|
||||
| --- | --- | --- |
|
||||
| `source_event_index` | 是 | AI current 事件序号,建议从 1 开始 |
|
||||
| `catalog_code` | 是 | Skill 目录代码,例如 S01、S02 |
|
||||
| `skill_id` | 是 | Skill 标识 |
|
||||
| `result_type` | 是 | 只接受 `normal_task`、`manual_review`、`informational_message` |
|
||||
| `result_type` | 是 | 新入口只接受 `normal_task`、`manual_review`;`informational_message` 仅历史兼容 |
|
||||
| `task_type` | 是 | AI 原始任务类型 |
|
||||
| `task_subtype` | 否 | 业务动作 subtype;有则用于任务卡路由 |
|
||||
| `current_or_history` | 否 | 当前或历史标识 |
|
||||
@@ -186,10 +191,42 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
| `context_used` | 否 | AI 使用的上下文 |
|
||||
| `extracted_fields` | 否 | 业务字段主体 |
|
||||
| `manual_review` | 条件必填 | `result_type=manual_review` 时应提供 |
|
||||
| `informational_message` | 条件必填 | `result_type=informational_message` 时应提供 |
|
||||
| `informational_message` | 条件必填 | 仅历史兼容;新数据不再生成 |
|
||||
| `additional_operations` | 否 | 附加动作建议 |
|
||||
| `idempotency_key` | 否 | 可忽略;本系统第一版自行生成幂等键 |
|
||||
|
||||
### 4.4 S000/S999 文本结果请求体
|
||||
|
||||
当 SuperAgent 入口阶段没有结构化任务 JSON 时,可以直接提交纯文本 body:
|
||||
|
||||
```text
|
||||
S000,mail-20260708-0001
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```text
|
||||
S999,mail-20260708-0001
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
| 片段 | 中文说明 |
|
||||
| --- | --- |
|
||||
| `S000` | 纯信息类邮件,不形成业务素材包 |
|
||||
| `S999` | 入口阶段无法形成业务素材包 |
|
||||
| `source_message_id` | 逗号后面的值,外部来源消息 ID,对应 AgentBus `source.external_message_id` |
|
||||
|
||||
处理规则:
|
||||
|
||||
- 第一版使用系统默认酒店反查 SourceMessage Inbox,不要求文本 body 携带 `hotel_id`。
|
||||
- 后端按 `默认酒店 + AGENTBUS + EMAIL + external_message_id` 查询 SourceMessage。
|
||||
- 命中后创建 `SOURCE_MESSAGE_ONLY` 只读任务。
|
||||
- 任务列表可见,订单列表不可见。
|
||||
- 不允许编辑、确认、转换订单、执行 OPERA 或重试 OPERA。
|
||||
- 同一 SourceMessage 重复提交相同文本 body 返回幂等重放。
|
||||
- 同一 SourceMessage 已经存在不同 AI 结果请求时返回幂等冲突。
|
||||
|
||||
## 5. 技术校验边界
|
||||
|
||||
本接口只做技术校验,不做业务合法性判断。
|
||||
@@ -198,12 +235,13 @@ X-TH-Hotel-SuperAgent-Signature: sha256=<lowercase-hex-signature>
|
||||
|
||||
- 鉴权签名合法。
|
||||
- 请求体大小不超过限制。
|
||||
- JSON 可解析。
|
||||
- `hotel_id` 存在。仅本地旧夹具兼容缺少 `hotel_id` 且 `source_message_id` 为内部数字 ID 的调用。
|
||||
- JSON body 可解析;S000/S999 文本 body 必须符合 `结果码,source_message_id`。
|
||||
- JSON body 中 `hotel_id` 存在。仅本地旧夹具兼容缺少 `hotel_id` 且 `source_message_id` 为内部数字 ID 的调用。
|
||||
- S000/S999 文本 body 第一版使用系统默认酒店,不读取 `hotel_id`。
|
||||
- 顶层只有一个 `source_message_id`。
|
||||
- `source_message_id` 对应的外部来源消息已经写入 SourceMessage Inbox。
|
||||
- `ai_task_results[]` 是非空数组。
|
||||
- `result_type` 属于允许值。
|
||||
- JSON `result_type` 属于允许值。
|
||||
- `task_type` 属于当前系统可识别的稳定值或可进入 Fallback 处理。
|
||||
- 同一个请求内 `source_event_index` 和数组顺序可保存。
|
||||
- 关键字符串长度不超过数据库限制。
|
||||
@@ -246,6 +284,7 @@ sha256(
|
||||
|
||||
- 相同请求体重复提交时识别为幂等重放。
|
||||
- 同一个外部 `source_message_id` 解析到的内部 SourceMessage 如果提交了不同请求体,不会被误认为同一个批次。
|
||||
- S000/S999 文本 body 也使用同一批次幂等规则。
|
||||
|
||||
### 6.3 item 幂等键
|
||||
|
||||
@@ -296,7 +335,8 @@ sha256(
|
||||
| `case_keys` | `case_keys_json` | 保存订单候选键 |
|
||||
| `extracted_fields` | `extracted_fields_json` | 保存业务字段 |
|
||||
| `manual_review` | `manual_review_json` | 保存人工复核结构 |
|
||||
| `informational_message` | `informational_message_json` | 保存信息提醒 |
|
||||
| `informational_message` | `informational_message_json` | 仅历史兼容的信息提醒结构 |
|
||||
| `S000/S999` 文本结果 | `SOURCE_MESSAGE_ONLY` 只读特殊任务 | 保存入口阶段原始结果,不创建真实业务订单 |
|
||||
|
||||
系统主任务类型映射以 `M002-order-task-workflow-v2.md` 为准。
|
||||
|
||||
@@ -331,6 +371,35 @@ sha256(
|
||||
}
|
||||
```
|
||||
|
||||
S000 / S999 文本结果创建成功时,同样返回 `201 Created`。这类结果会创建只读特殊任务和隐藏技术订单,供任务列表展示和任务详情查看来源邮件;该隐藏技术订单不会出现在订单列表。
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "req-20260707-0003",
|
||||
"source_message_id": "mail-20260708-0001",
|
||||
"batch_id": "1900000000000005001",
|
||||
"idempotent_replay": false,
|
||||
"accepted_count": 1,
|
||||
"items": [
|
||||
{
|
||||
"source_event_index": 1,
|
||||
"array_index": 1,
|
||||
"ai_transition_id": "1900000000000006001",
|
||||
"order_id": "1900000000000007001",
|
||||
"task_id": "1900000000000008001",
|
||||
"system_task_type": "SOURCE_MESSAGE_ONLY",
|
||||
"task_card_type": "SOURCE_MESSAGE_ONLY",
|
||||
"task_status": "COMPLETED",
|
||||
"order_status": "TEMPORARY",
|
||||
"execution_order": 1
|
||||
}
|
||||
],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
前端通过任务详情查看该类任务时,字段列表和 OPERA 操作列表为空,按钮应全部只读;`source_message_only_result` 会返回 `entry_result_code`、`entry_result_meaning`、`entry_result_description`、`entry_result_source_message_id` 和 `raw_answer`。
|
||||
|
||||
### 8.2 幂等重放
|
||||
|
||||
相同请求体重复提交时返回 `200 OK`。
|
||||
|
||||
Reference in New Issue
Block a user