修复Debug EML V4元数据与回归断言

This commit is contained in:
andy
2026-07-20 20:48:49 +07:00
parent 038fdc3c8d
commit c5b5ce6aab
5 changed files with 13 additions and 2 deletions

View File

@@ -194,6 +194,7 @@ SourceMessage 原文和邮件会话完整正文已迁移到登录权限体系:
- Debug EML 写入 SourceMessage Inbox 时 `provider=DEBUG_EML_UPLOAD`,不能伪装为 AgentBus 来源。
- Debug EML 写入 SourceMessage Inbox 时 `external_message_id` 是后端生成的 `debug-eml-run-{debugRunId}-{sha256前缀}`;原始邮件 `Message-ID` 不进入发给 SuperAgent 的主 payload需要排查时看原始 EML OSS 文件、Debug run 和 SuperAgent Open API metadata。
- Debug EML 返回的 `agentbus_like_payload` 是 AgentBus Outlook-like 主输入,会包含普通 `reply_policy.mode=manual``reply_policy.final_only=true`;不再包含 `schema_version``source.provider=DEBUG_EML_UPLOAD``debug_context` 或旧的 Debug 专属 `reply_policy.mode=debug_only`。Debug 来源区分仍依赖 SourceMessage `provider=DEBUG_EML_UPLOAD` 和 payload 表 `schemaVersion=debug-eml-upload-v1`;拿到 AgentBus 真实 `reply_policy.mode` 枚举后需统一替换占位值。
- Debug EML 调用 SuperAgent Open API 时metadata 中 `source=DEBUG_EML_UPLOAD` 只表示来源类型,`model_contract=M002_V4` 表示后续业务写入期望按 V4 契约处理profile 路由必须使用 `external_subject_id`,不要把 metadata.source 当 profile 名。
- 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 解析失败。结构化 `S10/S99` 可通过任务结果通知接口入站Debug EML 页面若要直接展示完整 V3 入口结构,前端展示仍需继续补齐。
- Debug EML 服务自身只展示 SuperAgent Open API 结果,不直接创建订单、不直接创建任务、不调用任务结果通知接口;如 SuperAgent 后续通过正式回调 / MCP 写入业务结果,必须按当前 M002 V4 契约创建 V4 order task / cards不再创建旧 `workflow_reservation_task`

View File

@@ -276,6 +276,7 @@ Debug 链路调用现有 `SourceMessageCaptureService.capture`,建议映射如
- 主 payload 不包含 `schema_version``source.provider=DEBUG_EML_UPLOAD``debug_context``original_message_id`,也不再使用旧的 Debug 专属 `reply_policy.mode=debug_only`
- SourceMessage Inbox 仍以 `provider=DEBUG_EML_UPLOAD` 和 payload 表 `schemaVersion=debug-eml-upload-v1` 区分 Debug 来源,不能伪装成 AgentBus 入库。
- Debug run ID、run_label、原始 Message-ID 和原始会话 ID 放入 SuperAgent Open API `metadata.debug_context`,只用于排查,不作为 SuperAgent 邮件业务主输入;原始 EML OSS URL 仅保存在本系统 Debug run / 受控响应中,不再透传给 SuperAgent metadata。
- SuperAgent Open API metadata 中 `source=DEBUG_EML_UPLOAD` 表示来源类型,`model_contract=M002_V4` 表示期望后续业务写入按 V4 契约处理profile 路由只看 `external_subject_id`,不要用 metadata.source 做 profile 判断。
## 9. SuperAgent Open API 调用口径

View File

@@ -1098,7 +1098,8 @@ public class DebugEmlSuperAgentRunServiceImpl implements DebugEmlSuperAgentRunSe
putIfNotNull(debugContext, "original_conversation_id", originalConversationId);
Map<String, Object> metadata = new LinkedHashMap<>();
metadata.put("source", "th-hotel-debug-eml-v4-upload");
metadata.put("source", "DEBUG_EML_UPLOAD");
metadata.put("model_contract", "M002_V4");
putIfNotNull(metadata, "debug_run_id", runId == null ? null : runId.toString());
putIfNotNull(metadata, "source_message_id", sourceMessageId == null ? null : sourceMessageId.toString());
putIfNotNull(metadata, "hotel_id", hotelId);

View File

@@ -228,7 +228,8 @@ class DebugEmlSuperAgentControllerTest {
.contains("\"mode\":\"manual\"")
.contains("\"final_only\":true");
org.assertj.core.api.Assertions.assertThat(superAgentRequest.metadata())
.containsEntry("source", "th-hotel-debug-eml-v4-upload")
.containsEntry("source", "DEBUG_EML_UPLOAD")
.containsEntry("model_contract", "M002_V4")
.containsKey("debug_context");
Long debugRunCount = jdbcTemplate.queryForObject("""

View File

@@ -1134,6 +1134,12 @@ class SuperAgentTaskResultControllerTest {
FROM workflow_reservation_task
WHERE source_message_id = ?
""", Long.class, source.inboxId());
Long legacyTaskCreatedOrderCount = jdbcTemplate.queryForObject("""
SELECT COUNT(*)
FROM workflow_reservation_order
WHERE source_message_id = ?
AND created_from_task_id IS NOT NULL
""", Long.class, source.inboxId());
Long v4OrderTaskCount = jdbcTemplate.queryForObject("""
SELECT COUNT(*)
FROM workflow_reservation_v4_order_task
@@ -1147,6 +1153,7 @@ class SuperAgentTaskResultControllerTest {
ORDER BY card_sort_order, source_event_index
""", String.class, source.inboxId());
assertThat(legacyTaskCount).isZero();
assertThat(legacyTaskCreatedOrderCount).isZero();
assertThat(v4OrderTaskCount).isEqualTo(1L);
assertThat(v4CardTypes).containsExactly(
"SOURCE_MESSAGE_DISPLAY",