240 lines
8.6 KiB
Markdown
240 lines
8.6 KiB
Markdown
# TH Hotel MCP Submit Payload Mapping
|
||
|
||
## 1. 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档版本 | 0.3 |
|
||
| 日期 | 2026-07-22 |
|
||
| 状态 | 当前有效:M002 V4-only |
|
||
| 适用范围 | `th_hotel_submit_task_results` 的 M002 V4 payload adapter、schema validator 和一次提交规则 |
|
||
|
||
## 2. 核心原则
|
||
|
||
`th_hotel_submit_task_results` 只接收 M002 V4 任务结果包。MCP 层只做 transport 形态校验和 V4 根结构防错,不重新解释业务含义、不调用 Skill、不根据字段名猜测任务类型。
|
||
|
||
当前开发阶段已确认不维护 V2/V3 submit 兼容。旧 `source_message + message_events[] + case_candidates[]`、旧结构化 `S10/S99`、`source_message_id + ai_task_results[]` 都不会再通过 MCP submit 写入业务层。
|
||
|
||
目标链路:
|
||
|
||
```text
|
||
SuperAgent M002 V4 业务结果
|
||
-> MCP Submit Payload Adapter
|
||
-> ReservationAiTaskIntakeService V4 入站
|
||
-> V4 order task / V4 task card / V4 source notification
|
||
-> MCP tool result
|
||
```
|
||
|
||
实现位置:
|
||
|
||
```text
|
||
server/src/main/java/cn/nianxx/thhotel/integrations/mcp/superagent/service/SuperAgentMcpSubmitPayloadAdapter.java
|
||
server/src/main/java/cn/nianxx/thhotel/integrations/mcp/superagent/service/impl/SuperAgentMcpSubmitPayloadAdapterImpl.java
|
||
```
|
||
|
||
## 3. 支持的输入形态
|
||
|
||
| 形态 | 判断方式 | 处理方式 |
|
||
| --- | --- | --- |
|
||
| V4 普通业务包 | 根字段包含 `route_code=null`、`source_message`、`order_contexts[]`、`message_events[]` | MCP adapter 校验根结构和 V4 `source_message` 后原样透传;业务入站层创建 V4 订单任务和任务卡 |
|
||
| V4 来源通知包 | 根字段包含 `route_code=S10/S99`、`source_message`、空 `order_contexts[]`、空 `message_events[]` | MCP adapter 校验根结构和 V4 `source_message` 后原样透传;业务入站层创建 V4 来源通知 |
|
||
|
||
不再支持的输入形态:
|
||
|
||
| 旧形态 | 示例特征 | 当前处理 |
|
||
| --- | --- | --- |
|
||
| V3 业务根 | `case_candidates`、`extraction_warnings`、`unhandled_current_intents`、旧 `source_message.from` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
| V3 S10/S99 | `handler_type`、`result_type=source_message_review_notification`、旧 `source_message.received_at` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
| V2 任务结果 | 顶层 `source_message_id + ai_task_results[]` | 返回 `MCP_SUBMIT_V4_REQUIRED`,不调用业务写入 Service |
|
||
|
||
未知根字段会在 MCP 层被拒绝,错误码为 `MCP_SUBMIT_PAYLOAD_INVALID`。
|
||
|
||
## 4. V4 根结构
|
||
|
||
```json
|
||
{
|
||
"route_code": null,
|
||
"source_message": {},
|
||
"order_contexts": [],
|
||
"message_events": []
|
||
}
|
||
```
|
||
|
||
字段规则:
|
||
|
||
| 字段 | 规则 |
|
||
| --- | --- |
|
||
| `route_code` | 必须存在;普通业务为 `null`,来源通知为 `S10` 或 `S99` |
|
||
| `source_message` | 必须存在;结构见本文第 5 节 |
|
||
| `order_contexts[]` | 必须存在且为数组;普通业务至少一条,来源通知为空数组 |
|
||
| `message_events[]` | 必须存在且为数组;普通业务至少一条,来源通知为空数组 |
|
||
|
||
MCP adapter 不再映射 `source_event_index`。V4 `message_events[]` 的数组顺序就是业务处理顺序;业务层使用数组位置派生一基 event index。
|
||
|
||
## 5. source_message
|
||
|
||
```json
|
||
{
|
||
"source_message_id": "mail-20260722-0001",
|
||
"conversation_id": "thread-001",
|
||
"subject": "Update Booking",
|
||
"sender": "agent@example.test",
|
||
"sent_at": "2026-07-22T08:00:00Z",
|
||
"body": "Please update the booking.",
|
||
"body_content_type": "text/plain",
|
||
"attachments": []
|
||
}
|
||
```
|
||
|
||
字段规则:
|
||
|
||
| 字段 | 规则 |
|
||
| --- | --- |
|
||
| `source_message_id` | 必填非空;必须来自 AgentBus 原始 payload 的外部消息 ID,对应 `platform_source_message_inbox.external_message_id` |
|
||
| `conversation_id` | 可缺省;出现时必须为字符串或 `null` |
|
||
| `subject` | 必须出现,可为 `null` |
|
||
| `sender` | 必须出现,可为 `null` |
|
||
| `sent_at` | 必须出现,可为 `null`;时间点使用 UTC ISO-8601 |
|
||
| `body` | 必须出现,可为 `null`;当前邮件原文,不摘要、不翻译、不重排 |
|
||
| `body_content_type` | 必填;只能为 `text/plain` 或 `text/html` |
|
||
| `attachments[]` | 必填数组;附件结构见第 6 节 |
|
||
|
||
旧 V3 的 `from`、`cc`、`received_at`、`source_channel` 不再属于 MCP submit 契约。`hotel_id`、`source_provider`、`source_channel` 也不需要 SuperAgent 传入。
|
||
|
||
## 6. attachments
|
||
|
||
```json
|
||
{
|
||
"id": "att-1",
|
||
"name": "payment-slip.jpg",
|
||
"content_type": "image/jpeg",
|
||
"url": "https://upstream-storage.example/payment-slip.jpg",
|
||
"size": 251524
|
||
}
|
||
```
|
||
|
||
字段规则:
|
||
|
||
| 字段 | 规则 |
|
||
| --- | --- |
|
||
| `id` | 必填非空;包内稳定附件引用 |
|
||
| `name` | 必填非空;原始文件名 |
|
||
| `content_type` | 必填非空;MIME 类型 |
|
||
| `url` | 必填非空;上游文件 URL,普通 V4 task detail 不直接返回 |
|
||
| `size` | 可省略或为 `null`;有值时必须是数字 |
|
||
|
||
Payment 事件只能通过 `attachment_ids[]` 引用 `source_message.attachments[].id`,不能复制完整附件对象或按文件名猜测。
|
||
|
||
## 7. 成功示例
|
||
|
||
### 7.1 普通业务
|
||
|
||
```json
|
||
{
|
||
"route_code": null,
|
||
"source_message": {
|
||
"source_message_id": "mail-mcp-v4-business-001",
|
||
"conversation_id": "thread-mcp-v4-business-001",
|
||
"subject": "Group booking and payment",
|
||
"sender": "agent@example.test",
|
||
"sent_at": "2026-07-18T02:10:00Z",
|
||
"body": "Please create group GRP-MCP-V4-001 and note payment attached.",
|
||
"body_content_type": "text/plain",
|
||
"attachments": [
|
||
{
|
||
"id": "att-pay-1",
|
||
"name": "payment-slip.jpg",
|
||
"content_type": "image/jpeg",
|
||
"url": "https://upstream-storage.example/payment-slip.jpg",
|
||
"size": 251524
|
||
}
|
||
]
|
||
},
|
||
"order_contexts": [
|
||
{
|
||
"order_ref": "order-1",
|
||
"basic_information": {
|
||
"account_code": "QBD_TRAVEL",
|
||
"manual_review": null
|
||
}
|
||
}
|
||
],
|
||
"message_events": [
|
||
{
|
||
"order_ref": "order-1",
|
||
"event_type": "NEW_BOOKING",
|
||
"target_order": {
|
||
"booking_type": "GROUP",
|
||
"locator_type": "GROUP_CODE",
|
||
"locator_value": "GRP-MCP-V4-001"
|
||
},
|
||
"arrival_date": "2026-07-26",
|
||
"departure_date": "2026-07-29",
|
||
"rate_code": "GRPA2-850UP",
|
||
"booking_scenario": "STANDARD",
|
||
"room_items": [
|
||
{
|
||
"room_type_code": "RM2",
|
||
"room_count": 2
|
||
}
|
||
],
|
||
"manual_review": null
|
||
},
|
||
{
|
||
"order_ref": "order-1",
|
||
"event_type": "PAYMENT",
|
||
"target_order": {
|
||
"booking_type": "GROUP",
|
||
"locator_type": "GROUP_CODE",
|
||
"locator_value": "GRP-MCP-V4-001"
|
||
},
|
||
"attachment_ids": ["att-pay-1"],
|
||
"manual_review": null
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 7.2 S99 来源通知
|
||
|
||
```json
|
||
{
|
||
"route_code": "S99",
|
||
"source_message": {
|
||
"source_message_id": "mail-mcp-v4-s99-001",
|
||
"conversation_id": "thread-mcp-v4-s99-001",
|
||
"subject": "Cannot form material package",
|
||
"sender": "guest@example.test",
|
||
"sent_at": "2026-07-18T02:10:00Z",
|
||
"body": "The input does not contain enough business material.",
|
||
"body_content_type": "text/plain",
|
||
"attachments": []
|
||
},
|
||
"order_contexts": [],
|
||
"message_events": []
|
||
}
|
||
```
|
||
|
||
## 8. 错误码
|
||
|
||
| 错误码 | 中文说明 |
|
||
| --- | --- |
|
||
| `MCP_SUBMIT_V4_REQUIRED` | MCP submit 收到的不是 M002 V4 根结构,通常是旧 V2/V3 payload |
|
||
| `MCP_SUBMIT_PAYLOAD_INVALID` | 已具备 V4 根字段,但字段类型、未知字段或 V4 `source_message` / `attachments` 结构不符合 MCP transport 校验 |
|
||
| `SOURCE_MESSAGE_NOT_FOUND` | V4 `source_message.source_message_id` 无法匹配 SourceMessage Inbox |
|
||
| `SOURCE_MESSAGE_AMBIGUOUS` | 同一系统酒店下外部 `source_message_id` 匹配多条 Inbox |
|
||
| `ADAPTER_CONTRACT_ERROR` | V4 包或 event 通过 MCP transport,但不满足业务入站契约,业务层记录 adapter contract error |
|
||
|
||
MCP adapter 校验失败时不会调用业务写入 Service,不会创建 AI batch、V4 order task、V4 card、V4 source notification 或旧任务。
|
||
|
||
## 9. 诊断
|
||
|
||
MCP 入站诊断表仍保存:
|
||
|
||
- `arguments_json`:SuperAgent 调用 MCP tool 的原始 arguments。
|
||
- `adapted_payload_json`:MCP adapter 后交给业务入站层的 payload;V4-only 模式下通常与 arguments 相同。
|
||
- `mapping_diagnostics_json`:当前 V4-only 模式下为空对象;旧 V3 事件 ID 映射已经废弃。
|
||
- `safe_error_code` / `safe_error_summary`:安全错误摘要。
|
||
|
||
排障时先对比 `arguments_json` 和 `adapted_payload_json`。如果二者均为 V4 且业务层返回 `ADAPTER_CONTRACT_ERROR`,说明问题在 SuperAgent V4 业务契约内容或业务校验;如果错误为 `MCP_SUBMIT_V4_REQUIRED`,说明 SuperAgent 仍在按旧 schema 输出。
|