完善 Debug EML 上传调试链路

This commit is contained in:
andy
2026-07-09 15:25:26 +08:00
parent fcb30d460a
commit 6d2b3e8ccd
13 changed files with 615 additions and 56 deletions

View File

@@ -12,6 +12,7 @@
| --- | --- |
| `backend-to-frontend-notes.md` | 后端提醒前端的注意事项,包含项目开发、业务规则、接口使用和安全边界。 |
| `frontend-to-backend-api-requests.md` | 前端提醒后端需要增加或补齐的接口,包含建议入参和返参草案。 |
| `debug-eml-page-integration-guide.md` | Debug EML 页面前端对接指南,包含页面结构、上传接口、响应展示、错误处理和安全注意事项。 |
## 3. 当前字段来源分工

View File

@@ -63,7 +63,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 调试接口。 | 只用于调试页面;请求为 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 字段。 | 只用于调试页面;请求为 multipart/form-data必须传 `X-TH-Hotel-Debug-Upload-Key`,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报。 |
### 5.2 来源邮件会话字段说明
@@ -159,15 +159,21 @@ hotel_id: HOTEL-TEST
run_label: 可选调试标签
```
页面级对接细节请优先阅读 `docs/project/frontend-backend/debug-eml-page-integration-guide.md`
前端注意:
- 该接口只用于 dev/test 调试页面,不是生产普通业务页面接口。
- 接口会解析 `.eml`,上传原始邮件、内联图片和附件到本系统阿里云 OSS替换 HTML 内 `cid:` 图片,再写入 SourceMessage Inbox。
- SourceMessage 来源 provider 固定为 `DEBUG_EML_UPLOAD`,用于和 AgentBus 入库邮件区分。
- 当前 AgentBus 实时收到邮件后自动推 SuperAgent 还没有做;这个接口是人工 Debug 上传链路,不代表实时生产链路。
- `external_message_id` 是后端生成的 Debug 独立 ID格式类似 `debug-eml-run-{debugRunId}-{sha256前缀}`;原始邮件 `Message-ID` 保存在 `agentbus_like_payload.source.original_message_id`
- 邮件会话解析支持 `References``In-Reply-To``Thread-Index`,但 Debug EML 的 `external_message_id` 不使用原始 `Message-ID` 做幂等。
- `agentbus_like_payload.schema_version` 固定为 `debug-eml-upload-v1`,前端可用于调试展示和版本判断。
- 第一版只返回 SuperAgent 结果,不创建订单、不创建任务、不调用任务结果通知接口。
- `X-TH-Hotel-Debug-Upload-Key` 只能由调试人员在受控环境手动提供,不能放入 `VITE_*`、源码、构建产物、URL query、localStorage、错误上报或普通日志。
- 返回的 `uploaded_media[]``original_eml_oss_url``html_body_with_oss_urls` 可能包含 OSS URL前端不要写入普通日志、埋点、错误上报或 URL query
- 返回的 `html_body_sanitized` 复用邮件会话详情的安全策略,前端展示 HTML 时优先使用;`html_body_with_oss_urls` 只作为调试原始处理结果,不建议直接渲染
- 返回的 `uploaded_media[]``original_eml_oss_url``html_body_with_oss_urls``html_body_sanitized` 可能包含 OSS URL前端不要写入普通日志、埋点、错误上报或 URL query。
- `superagent_parsed_json` 为空时,前端展示 `superagent_raw_answer``warnings[]`,不要假定 SuperAgent 总能返回 JSON。
## 6. 不给前端直接调用的接口

View File

@@ -0,0 +1,241 @@
# Debug EML 页面前端对接指南
## 1. 文档定位
本文给前端 Debug 页面开发使用,说明 `.eml` 邮件上传到 SuperAgent 调试链路应该做什么、调用哪个接口、如何组织请求、如何展示返回结果,以及哪些安全边界不能越过。
相关背景文档:
- `docs/project/requirements/M004-debug-eml-superagent-upload-v1.md`
- `docs/project/frontend-backend/backend-to-frontend-notes.md`
## 2. 页面目标
Debug EML 页面第一版只做一件事:
上传单封 `.eml` 邮件,后端解析邮件、上传原始邮件 / 内联图片 / 附件到本系统阿里云 OSS替换 HTML 中的 `cid:` 图片,写入 SourceMessage Inbox然后调用 SuperAgent Open API并把 SuperAgent 返回结果展示给调试人员。
第一版明确不做:
- 不创建 Reservation 订单。
- 不创建 Reservation 任务。
- 不调用 SuperAgent 任务结果通知接口。
- 不触发 AgentBus 实时链路。
- 不做批量上传。
- 不提供 Debug run 历史列表或详情查询。
- 不在生产普通业务页面开放。
## 3. 页面建议结构
建议页面分为以下区域:
| 区域 | 展示 / 操作 | 说明 |
| --- | --- | --- |
| 上传配置区 | `hotel_id`、Debug 上传口令、`run_label``.eml` 文件选择、提交按钮 | Debug 上传口令只能由调试人员临时输入不能写进前端源码、环境变量、localStorage 或 URL。 |
| 执行状态区 | 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 输出。 |
| 调试 Payload 区 | `agentbus_like_payload` | 只用于调试展示,不让用户编辑后重新提交。 |
## 4. 接口
```text
POST /api/system/debug/eml-superagent-runs
Content-Type: multipart/form-data
Accept: application/json
Header: X-TH-Hotel-Debug-Upload-Key: <调试上传口令>
```
注意:
- 该接口只有在后端 `debug.eml-upload.enabled=true` 时存在;如果后端未开启,前端可能收到 `404`
- 请求必须使用 `FormData`
- 前端不要手动设置 `Content-Type`,让浏览器自动生成 multipart boundary。
- `X-TH-Hotel-Debug-Upload-Key` 不能进入 `VITE_*`、源码、构建产物、localStorage、URL query、错误上报或普通日志。
请求参数:
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `file` | File | 是 | `.eml` 邮件文件。前端文件选择器建议 `accept=".eml,message/rfc822"`。 |
| `hotel_id` | string | 是 | 酒店上下文 ID本地 / test 可使用当前前端配置的 `VITE_RESERVATION_HOTEL_ID`。 |
| `run_label` | string | 否 | 调试标签,例如 `frontend-debug-smoke`,方便后端日志和数据库排查。 |
前端调用示例:
```ts
export async function uploadDebugEml(input: {
baseUrl: string
hotelId: string
debugUploadKey: string
file: File
runLabel?: string
}) {
const form = new FormData()
form.append('file', input.file)
form.append('hotel_id', input.hotelId)
if (input.runLabel?.trim()) {
form.append('run_label', input.runLabel.trim())
}
const response = await fetch(`${input.baseUrl}/api/system/debug/eml-superagent-runs`, {
method: 'POST',
headers: {
Accept: 'application/json',
'X-TH-Hotel-Debug-Upload-Key': input.debugUploadKey,
},
body: form,
})
const data = await response.json()
if (!response.ok) {
throw data
}
return data
}
```
## 5. 成功响应
成功状态码:`201 Created`
核心字段:
| 字段 | 类型 | 前端用途 |
| --- | --- | --- |
| `debug_run_id` | string | 展示本次调试运行 ID。 |
| `source_message_id` | string | 展示 SourceMessage 内部 ID可用于后续排查。 |
| `source_provider` | string | 固定为 `DEBUG_EML_UPLOAD`。 |
| `external_message_id` | string | Debug 独立外部消息 ID格式类似 `debug-eml-run-{debugRunId}-{sha256前缀}`。 |
| `external_conversation_id` | string | 邮件会话 ID可能来自 `References` / `In-Reply-To` / `Thread-Index`。 |
| `original_eml_oss_url` | string | 原始 `.eml` OSS URL只在受控调试页面展示。 |
| `original_eml_sha256` | string | 原始 `.eml` SHA-256。 |
| `uploaded_media[]` | array | 原始邮件、内联图片和附件列表。 |
| `html_body_with_oss_urls` | string | 替换 `cid:` 后的 HTML作为调试原始处理结果展示不建议直接渲染。 |
| `html_body_sanitized` | string | 后端清洗后的 HTML前端预览邮件正文时优先使用。 |
| `html_sanitize_required` | boolean | 当前为 `true`,提醒前端不要直接信任原始 HTML。 |
| `html_render_mode` | string | 当前可能为 `SANITIZED_HTML``TEXT_ONLY`。 |
| `agentbus_like_payload` | object | 后端发送给 SuperAgent 的结构化 payload。 |
| `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解析失败时可能为空。 |
| `warnings[]` | string[] | 安全或解析警告,可在页面顶部或结果区展示。 |
| `status` | string | Debug run 状态。 |
`uploaded_media[]` 字段:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `media_type` | string | `ORIGINAL_EMAIL``INLINE_IMAGE``ATTACHMENT`。 |
| `file_name` | string | 文件名。 |
| `content_type` | string | MIME 类型。 |
| `size_bytes` | number | 文件大小。 |
| `external_url` | string | OSS URL。 |
| `external_media_id` | string | 调试链路媒体 ID例如 `cid:inline-001`。 |
| `object_key` | string | OSS 对象路径。 |
关键展示规则:
- 邮件正文 iframe / 富文本预览优先使用 `html_body_sanitized`
- `html_body_with_oss_urls` 可以放在“原始处理 HTML”折叠面板中不作为默认渲染内容。
- `agentbus_like_payload.source.original_message_id` 是原始邮件 `Message-ID`
- `external_message_id` 是 Debug 链路生成的独立 ID不等同于原始 `Message-ID`
- `superagent_parsed_json` 有值时优先展示格式化 JSON没有值时展示 `superagent_raw_answer`
## 6. 错误响应
错误响应结构:
```json
{
"error_code": "DEBUG_UPLOAD_KEY_INVALID",
"message": "Debug 上传访问口令缺失或错误。"
}
```
常见错误:
| HTTP 状态 | `error_code` | 前端建议 |
| --- | --- | --- |
| `400` | `REQUEST_FIELD_REQUIRED` | 提示缺少必填字段,检查文件、`hotel_id` 或请求参数。 |
| `400` | `EML_FILE_REQUIRED` | 提示请选择 `.eml` 文件。 |
| `400` | `EML_FILE_TOO_LARGE` | 提示文件超过后端限制;当前默认上限通常为 10MB以环境配置为准。 |
| `400` | `INVALID_FILE_TYPE` | 提示只支持 `.eml`。 |
| `401` | `DEBUG_UPLOAD_KEY_INVALID` | 提示调试上传口令缺失或错误。 |
| `404` | 无固定结构 | 后端未开启 Debug EML 接口或路径错误。 |
| `422` | `EML_PARSE_FAILED` | 提示邮件文件无法解析。 |
| `502` | `OSS_UPLOAD_FAILED` | 提示 OSS 上传失败,调试人员联系后端排查。 |
| `502` | `SUPERAGENT_OPEN_API_FAILED` | 提示 SuperAgent 调用失败SourceMessage 可能已经写入。 |
| `500` | `DEBUG_EML_RUN_FAILED` | 提示 Debug 链路内部失败。 |
错误展示原则:
- 页面只展示 `message``error_code`
- 不展示请求 header、上传口令、完整邮件正文、完整 HTML、OSS 签名 URL 或 Provider 原始错误。
- `SUPERAGENT_OPEN_API_FAILED` 时,不要把页面理解为“邮件上传没有发生”;后端可能已经完成 OSS 上传和 SourceMessage 写入。
## 7. 前端状态流转
建议页面状态:
```text
idle
→ validating
→ uploading
→ waiting_superagent
→ succeeded
→ failed
```
实现建议:
- 文件未选择、`hotel_id` 为空、Debug 上传口令为空时禁用提交按钮。
- 提交后禁用文件选择和提交按钮,避免重复上传。
- SuperAgent 调用可能耗时较长,页面 loading 文案不要只写“上传中”,建议写“正在解析邮件并等待 SuperAgent 返回”。
- 成功后保留本次响应在页面内存中;当前没有 Debug run 查询接口,刷新页面后需要重新上传。
- 再次上传同一封 `.eml` 会生成新的 `external_message_id` 和新的 SourceMessage前端不要按原始 `Message-ID` 去重。
## 8. 安全与日志
前端必须遵守:
- 不把 Debug 上传口令写入源码、`.env``VITE_*`、localStorage、sessionStorage、URL query、错误上报或普通日志。
- 不把 `uploaded_media[].external_url``original_eml_oss_url`、邮件 HTML、附件 URL 写入普通日志或埋点。
- 不在生产普通业务菜单暴露该页面。
- 不允许前端直接调用 SuperAgent、AgentBus、OSS、数据库或 OPERA。
- 不使用 Debug EML 页面结果改变订单、任务或 OPERA 状态。
## 9. 联调前置条件
后端环境需要具备:
- `DEBUG_EML_UPLOAD_*_ENABLED=true`
- `DEBUG_EML_UPLOAD_*_ACCESS_KEY` 已配置。
- 阿里云 OSS endpoint、bucket、access key、public base URL 已配置。
- `SUPERAGENT_*_OPEN_API_ENABLED=true`
- SuperAgent / DeerFlow Open API base URL 和 API key 已配置。
前端需要具备:
- 可配置后端 `BASE_URL`
- 可配置或输入 `hotel_id`
- 调试人员临时输入 Debug 上传口令。
- 准备一封 `.eml` 样例邮件。
## 10. 与其他页面的关系
- Debug EML 页面是调试工具,不是 Message Notification 页面。
- Debug EML 页面写入的 SourceMessage `provider=DEBUG_EML_UPLOAD`,用于和 AgentBus 来源区分。
- Debug EML 页面第一版不创建订单和任务,所以上传成功后任务列表和订单列表不会因为这次上传自动新增业务数据。
- AgentBus 实时收到邮件后自动推 SuperAgent 当前还没做,不能用 Debug EML 页面代表生产实时链路。
## 11. 当前后置事项
- Debug run 历史列表 / 详情查询接口未做。
- Debug run 取消或超时轮询接口未做。
- 批量上传未做。
- 前端白名单元数据独立接口未做。
- 用户身份 / 权限体系未接入;当前依赖调试上传口令保护。

View File

@@ -137,7 +137,10 @@
- Debug EML 上传接口会接收原始邮件、上传 OSS 并调用 SuperAgent风险和成本高于普通查询接口。
- Debug EML 上传 key、SuperAgent Open API Key、阿里云 OSS AccessKey 都不得进入前端源码、`VITE_*`、镜像、普通日志或文档真实值。
- 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 结果,不创建订单、不创建任务、不调用任务结果通知接口。
- AgentBus 实时收到邮件后自动推 SuperAgent 当前未实现,不能把 Debug EML 链路等同于生产实时自动处理链路。
## 4. 数据库上线注意事项
@@ -232,6 +235,7 @@ Header: X-TH-Hotel-Access-Scene
AgentBus 是消息入口,不是 AI Provider。生产实时链路必须保持以下边界
- 只写 SourceMessage Inbox。
- 不自动调用 SuperAgent。
- 不创建 MessageEvent、Evidence、Case、Task、Operation、Receipt。
- 不调用 OHIP、ERP、支付系统等业务写接口。
- 不自动发送 ACK、`task.result` 或客户回复。

View File

@@ -12,7 +12,7 @@
## 1. 文档定位
本文记录 Debug EML 上传链路的第一版后端设计。该能力用于在没有 AgentBus 实时入口的情况下,
本文记录 Debug EML 上传链路的第一版后端设计。该能力用于在不依赖 AgentBus 实时自动处理的情况下,
由调试页面上传 `.eml` 邮件文件,后端解析邮件、转存附件和内联图片到本系统阿里云 OSS
再组装成 SuperAgent 可处理的邮件输入并调用 SuperAgent Open API。
@@ -26,6 +26,7 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- 第一版只展示 SuperAgent 生成结果,不落业务订单和任务。
- 上传邮件仍要写入 SourceMessage Inbox。
- Debug 上传来源必须和 AgentBus 来源区分,建议 `provider=DEBUG_EML_UPLOAD`
- AgentBus 实时收到邮件后自动推 SuperAgent 当前未实现;现有 AgentBus 实时链路只负责写入 SourceMessage Inbox。
- 使用真实阿里云 OSS不使用本地 mock OSS。
- 原始 `.eml` 文件本身也上传到阿里云 OSS便于后续调试追溯。
- 内联图片和普通附件都上传到阿里云 OSS。
@@ -43,7 +44,12 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- HTML `cid:` 图片替换为 OSS URL。
- AgentBus-like payload 组装。
- SourceMessage Inbox 写入,`provider=DEBUG_EML_UPLOAD``schema_version=debug-eml-upload-v1`
- Debug EML 的 `external_message_id` 由后端生成,格式为 `debug-eml-run-{debugRunId}-{sha256前缀}`,避免同一封 `.eml` 多次上传被 SourceMessage 幂等覆盖。
- 原始邮件 `Message-ID` 不再作为 Debug EML 的 `external_message_id`,而是保存到 `agentbus_like_payload.source.original_message_id`
- EML 会话解析支持 `References` / `In-Reply-To` / `Thread-Index`;缺失时再回退到当前消息 ID 或 debug 会话 ID。
- SourceMessage 写入成功后先把 debug run 标记为 `SOURCE_CAPTURED`;即使后续 SuperAgent 调用失败,也保留 SourceMessage 和 OSS 原文追溯信息。
- HTML 正文复用邮件会话详情的 sanitize 策略,返回 `html_body_sanitized``html_sanitize_required``html_render_mode`
- `cid:` 图片替换支持大小写不敏感的 scheme并兼容常见的尖括号和 URL 编码尖括号形式。
- SuperAgent Open API client创建 session、发送 `messages/stream`、解析 SSE 最终回答。
- `platform_debug_eml_superagent_run` 持久化。
- Controller / Service / ServiceImpl / Repository / Mapper / Entity / DTO / Result 按当前后端目录规范落位。
@@ -57,6 +63,7 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- 后端可以解析邮件头、纯文本正文、HTML 正文、内联图片和附件。
- 后端可以把原始 `.eml`、内联图片和附件上传到阿里云 OSS。
- 后端可以把 HTML 正文中的 `cid:` 引用替换成 OSS URL。
- 后端可以返回清洗后的 HTML 字段,前端优先展示 `html_body_sanitized`
- 后端可以组装 AgentBus-like 邮件 payload保持和当前 SourceMessage Inbox / SuperAgent 输入口径接近。
- 后端可以写入 SourceMessage Inbox并明确标记来源为 Debug EML Upload。
- 后端可以调用 SuperAgent Open API 并解析最终返回。
@@ -74,6 +81,7 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- 不做邮件多封批量上传。
- 不做 ZIP、MSG、PDF、图片 OCR 或 Excel 解析。
- 不做 SourceMessage Replay 到 MessageEvent / Evidence。
- 不做 AgentBus 实时邮件自动调用 SuperAgent该能力后续需要单独设计触发、幂等、限流和失败补偿。
- 不做普通任务切换订单。
- 不做 SuperAgent 查询接口 3、4。
- 不接入完整用户 / 权限体系。
@@ -136,6 +144,9 @@ Header: X-TH-Hotel-Debug-Upload-Key: <DEBUG_EML_UPLOAD_ACCESS_KEY>
| `original_eml_sha256` | 原始 `.eml` 文件 SHA-256 |
| `uploaded_media[]` | 已上传 OSS 的内联图片和附件 |
| `html_body_with_oss_urls` | 替换 `cid:` 后的 HTML 正文 |
| `html_body_sanitized` | 复用邮件会话安全策略清洗后的 HTML 正文,前端调试展示优先使用 |
| `html_sanitize_required` | 固定提示前端 HTML 需要按安全策略展示 |
| `html_render_mode` | HTML 推荐渲染模式,当前优先返回 `SANITIZED_HTML` |
| `agentbus_like_payload` | 发送给 SuperAgent 的结构化邮件 payload包含 `schema_version=debug-eml-upload-v1` |
| `superagent_session_id` | SuperAgent Open API session ID失败时为空 |
| `superagent_run_id` | SuperAgent 返回的 run ID失败时为空 |
@@ -166,7 +177,7 @@ Debug 链路调用现有 `SourceMessageCaptureService.capture`,建议映射如
| `hotelId` | 请求参数 `hotel_id` |
| `provider` | `DEBUG_EML_UPLOAD` |
| `channel` | `EMAIL` |
| `externalMessageId` | 优先邮件 `Message-ID` 的规范化值;缺失时使用 `debug-eml-{sha256前缀}` |
| `externalMessageId` | Debug 链路生成值,格式为 `debug-eml-run-{debugRunId}-{sha256前缀}`;同一封 `.eml` 重复上传也会生成独立 SourceMessage |
| `externalConversationId` | 优先邮件 `In-Reply-To` / `References` / `Thread-Index` 可解析会话值;缺失时使用 `debug-eml-thread-{externalMessageId}` |
| `providerFrameId` | `debug_run_id` |
| `providerSessionId` | 可使用 `debug-eml-upload` 或后续当前用户 session 摘要 |
@@ -189,6 +200,12 @@ Debug 链路调用现有 `SourceMessageCaptureService.capture`,建议映射如
若新增 `ORIGINAL_EMAIL` 媒体类型,需要同步更新 SourceMessage 媒体枚举、接口文档和前端展示说明。
补充说明:
- 原始邮件 `Message-ID` 保存到 `payloadJson.source.original_message_id`,不参与 Debug EML SourceMessage 幂等键。
- 原始解析出的会话 ID 保存到 `payloadJson.source.original_conversation_id`,便于排查 Debug 会话和真实邮件头之间的关系。
- `Thread-Index` 仅作为 `References` / `In-Reply-To` 缺失时的会话 fallback不覆盖明确的邮件回复链。
## 8. AgentBus-like Payload 结构建议
第一版 payload 目标是让 SuperAgent 获得接近 AgentBus 邮件输入的结构,而不是完整复刻 AgentBus 协议。
@@ -198,8 +215,10 @@ Debug 链路调用现有 `SourceMessageCaptureService.capture`,建议映射如
"source": {
"channel": "EMAIL",
"provider": "DEBUG_EML_UPLOAD",
"external_message_id": "debug-eml-4f2c9a8b7d6e",
"external_conversation_id": "debug-eml-thread-4f2c9a8b7d6e",
"external_message_id": "debug-eml-run-1900000000000000001-4f2c9a8b7d6e",
"external_conversation_id": "debug-eml-thread-debug-eml-run-1900000000000000001-4f2c9a8b7d6e",
"original_message_id": "message-id-from-eml@example.com",
"original_conversation_id": "thread-index-or-reference-from-eml",
"sender": "sender@example.com",
"subject": "Booking Request",
"sent_at": "2026-07-09T01:30:00Z"