# 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 输出。