实现AgentBus自动分发SuperAgent链路

This commit is contained in:
andy
2026-07-12 23:53:50 +08:00
parent c3dad8eae9
commit 53b530d0b3
42 changed files with 2512 additions and 135 deletions

View File

@@ -40,6 +40,7 @@
| `requirements/M004-debug-eml-superagent-upload-v1.md` | 当前有效 | M004 Debug EML 上传 SuperAgent 调试方案。 |
| `requirements/M005-hotel-context-unification-plan.md` | 当前有效 | M005 酒店上下文统一收口方案。 |
| `requirements/M006-system-admin-management-console-v1.md` | 草案 | M006 系统管理后台方案,覆盖用户、角色、权限、菜单、酒店和用户酒店授权维护。 |
| `requirements/M007-agentbus-superagent-auto-dispatch-v1.md` | 当前有效 | M007 AgentBus 新邮件入库后异步分发 SuperAgent 的后端 V1 方案,当前默认关闭,等待测试机联调。 |
## 集成契约

View File

@@ -177,7 +177,7 @@ groupCode
## 8. AgentBus 边界
- AgentBus 是消息入口适配器,不是 AI Provider。
- 实时 AgentBus 链路只`platform_source_message_inbox`
- 实时 AgentBus 入口必须先`platform_source_message_inbox`;如需调用 SuperAgent必须通过入库后的受控异步 dispatch / outbox 链路完成
- 不直接生成 `platform_message_event`、Evidence、Recognition、Case、Task、Operation、Receipt 或 OHIP 写入。
- 不自动发送 ACK、`task.result` 或客户回复。
- SourceMessage Inbox 到 MessageEvent / Evidence 必须通过受控 replay。

View File

@@ -287,7 +287,7 @@ idle
- Debug EML 页面是调试工具,不是 Message Notification 页面。
- Debug EML 页面写入的 SourceMessage `provider=DEBUG_EML_UPLOAD`,用于和 AgentBus 来源区分。
- Debug EML 页面第一版不创建订单和任务,所以上传成功后任务列表和订单列表不会因为这次上传自动新增业务数据。
- AgentBus 实时收到邮件后自动推 SuperAgent 当前还没做,不能用 Debug EML 页面代表生产实时链路。
- AgentBus 实时收到邮件后自动推 SuperAgent 已由 M007 后端 V1 实现,但默认关闭且不走 Debug 页面;不能用 Debug EML 页面代表生产实时链路。
## 11. 当前后置事项

View File

@@ -11,7 +11,7 @@
- `GET /api/source-messages/{id}`:查询单条 SourceMessage 安全摘要。
- `GET /api/source-messages/{id}/original`受控读取邮件原文、HTML 和媒体 URL并记录访问审计。
- `GET /api/system/agentbus-probe`:查看 AgentBus WebSocket 连接状态和安全计数器。
- AgentBus WebSocket 入站链路:默认关闭,开启后把业务 frame 写入 SourceMessage Inbox。
- AgentBus WebSocket 入站链路:默认关闭,开启后把业务 frame 写入 SourceMessage Inbox;如开启 M007则在入库后异步创建 SuperAgent dispatch run
- SuperAgent 任务结果接收接口:当前代码接收一个外部 `source_message_id` 下的 AI 任务结果,反查 SourceMessage Inbox 后写入 AI 过渡层、订单、任务和任务卡;支持 V3 结构化 `S10/S99` 和业务根基础解析,同时兼容旧 `S000/S999,source_message_id` 文本入口结果并创建只读特殊任务。
- Reservation 任务详情接口:返回任务字段、队列可处理状态和 OPERA 模拟操作摘要。
- Reservation 任务草稿保存和最终确认接口:按任务卡矩阵做第一版后端校验,确认后生成 `confirmed_payload_json`
@@ -27,6 +27,7 @@
- 真实 AI 识别服务实现、Case 完整模型、Operation、Receipt。
- 自动 ACK、`task.result` 或客户回复。
- 业务前端页面展示邮件原文。
- AgentBus SourceMessage 入库后自动分发 SuperAgent 虽然后端 V1 已实现,但默认关闭;未经测试机验收前不要在生产启用。
- OHIP / OPERA 或其他业务系统真实写操作。
- 普通任务切换订单接口。
- M002 V3 字段矩阵从当前扁平结构整体迁移到 0711 P0 新结构。
@@ -44,6 +45,7 @@
- 所有 Secret 都通过环境变量、部署平台 Secret 或密钥管理系统注入,不写入仓库、镜像、前端环境变量或普通配置文件。
- 生产默认不保存 AgentBus raw frame 样本。
- AgentBus 实时链路开启前,已经确认 WebSocket URL、Token、Bot Address、外部消息幂等键和断线重连语义。
- M007 自动分发开启前,必须先确认 SourceMessage 入库稳定、SuperAgent Open API Key 可用、SSE 断流恢复通过测试、dispatch worker 开关和回滚方式明确。
- 源邮件只读通知卡上线前,必须确认 `platform_hotel` 中存在且只存在一家 `ACTIVE` 酒店,并且已有 SourceMessage Inbox 数据的 `hotel_id` 与该酒店一致。旧 `S000/S999` 和新结构化 `S10/S99` 都沿用该酒店解析约束。
- 系统管理后台上线前,必须确认至少存在一个 `ACTIVE` 超级管理员账号,且该账号拥有 `SYSTEM_ADMIN_CONSOLE_ACCESS` 和各系统管理权限。
- 单酒店阶段上线前,必须确认 `platform_hotel` 中只有一家 `ACTIVE` 酒店;新增酒店可以存在但应保持 `DISABLED`
@@ -112,6 +114,14 @@
| `AGENTBUS_CONNECT_TIMEOUT` | 否 | 连接超时,默认 `15s`。 |
| `AGENTBUS_MAX_FRAME_BYTES` | 否 | 单个入站 frame 最大字节数,默认 `1048576`。 |
| `AGENTBUS_CAPTURE_ENABLED` | 否 | 是否把业务 frame 写入 SourceMessage Inbox。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_ENABLED` | 否 | AgentBus 新邮件入库后是否创建 SuperAgent dispatch 记录,默认关闭。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_WORKER_ENABLED` | 否 | 是否启动异步 worker 调用 SuperAgent Open API默认关闭。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_MAX_ATTEMPTS` | 否 | 单条 dispatch 最大尝试次数,建议默认 `3`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_BATCH_SIZE` | 否 | worker 每轮领取数量,建议默认 `10`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_LOCK_TTL` | 否 | worker 抢占锁有效期,建议默认 `5m`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_INITIAL_BACKOFF` | 否 | 首次失败后的重试等待时间,建议默认 `30s`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_MAX_BACKOFF` | 否 | 最大重试等待时间,建议默认 `15m`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_WORKER_FIXED_DELAY_MS` | 否 | worker 调度间隔毫秒,建议默认 `10000`。 |
注意:
@@ -119,6 +129,7 @@
- `AGENTBUS_CAPTURE_ENABLED=false` 时,业务 frame 会被忽略,不会写入 SourceMessage Inbox。
- `AGENTBUS_DEFAULT_HOTEL_ID` 是 M005 前旧变量,当前后端不再读取;系统酒店来自 `platform_hotel` 唯一 `ACTIVE` 酒店。
- 当前实现不发送 ACK、不发送 `task.result`、不自动回复客户。
- M007 自动分发即使开启,也只能在 SourceMessage 入库后通过 dispatch / outbox 异步调用 SuperAgent不能在 AgentBus WebSocket 回调内同步等待外部返回。
### 3.5 SuperAgent HMAC
@@ -158,13 +169,15 @@
| `DEBUG_EML_UPLOAD_PROD_ACCESS_KEY` | 是 | prod Debug EML 上传访问口令;生产通常不应启用该接口。 |
| `DEBUG_EML_UPLOAD_MAX_FILE_BYTES` | 否 | `.eml` 上传大小上限,默认 `10485760`。 |
| `DEBUG_EML_UPLOAD_SSE_HEARTBEAT_INTERVAL` | 否 | Debug EML 页面到后端的 SSE 心跳间隔,默认 `15s`;测试机如仍遇到空闲断流可调小到 `10s`。 |
| `DEBUG_EML_UPLOAD_SSE_REQUEST_TIMEOUT` | 否 | Spring MVC 异步请求总超时,默认 `1800s`当前用于保障 Debug EML SSE 不先于 SuperAgent read timeout 关闭。注意 Spring MVC async timeout 是应用级全局设置,后续如增加其他 async/SSE 接口需一起评估。 |
| `DEBUG_EML_UPLOAD_SSE_REQUEST_TIMEOUT` | 否 | Spring MVC 异步请求总超时,默认 `1800s`;用于保障 Debug EML 页面长流程不被后端 MVC 容器提前关闭。注意 Spring MVC async timeout 是应用级全局设置,后续如增加其他 async/SSE 接口需一起评估。 |
| `DEERFLOW_DEV_BASE_URL` / `DEERFLOW_TEST_BASE_URL` / `DEERFLOW_PROD_BASE_URL` | 否 | SuperAgent / DeerFlow Open API 基础地址,未配置时可兜底 `DEERFLOW_BASE_URL`。 |
| `DEERFLOW_DEV_OPEN_API_KEY` / `DEERFLOW_TEST_OPEN_API_KEY` / `DEERFLOW_PROD_OPEN_API_KEY` | 是 | SuperAgent Open API Key未配置时可兜底 `DEERFLOW_OPEN_API_KEY`。 |
| `SUPERAGENT_DEV_OPEN_API_ENABLED` / `SUPERAGENT_TEST_OPEN_API_ENABLED` / `SUPERAGENT_PROD_OPEN_API_ENABLED` | 否 | 是否启用真实 SuperAgent Open API 调用prod 默认关闭。 |
| `SUPERAGENT_DEBUG_EML_EXTERNAL_SUBJECT_ID` | 否 | Debug EML 创建 SuperAgent session 的 external subject id。 |
| `SUPERAGENT_AGENTBUS_EXTERNAL_SUBJECT_ID` | 否 | AgentBus 自动分发创建 SuperAgent session 的 external subject id。 |
| `SUPERAGENT_DEBUG_EML_CONNECT_TIMEOUT` | 否 | SuperAgent Open API 建连超时,默认 `15s`。 |
| `SUPERAGENT_DEBUG_EML_READ_TIMEOUT` | 否 | SuperAgent SSE 读取超时,默认 `180s`。 |
| `SUPERAGENT_DEBUG_EML_READ_TIMEOUT` | 否 | 旧版 RestClient 读取超时兼容变量;当前 JDK SSE 客户端不设置整段 SSE 固定读取超时,断流恢复由 run/events 机制处理。 |
| `SUPERAGENT_OPEN_API_SSE_RECOVERY_MAX_ATTEMPTS` | 否 | SSE EOF 后通过 `/runs/{run_id}/events` 恢复的最大尝试次数,默认 `5`。 |
| `ALIYUN_OSS_DEV_ENDPOINT` / `ALIYUN_OSS_TEST_ENDPOINT` / `ALIYUN_OSS_PROD_ENDPOINT` | 否 | 阿里云 OSS Endpoint未配置时可兜底 `ALIYUN_OSS_ENDPOINT`。 |
| `ALIYUN_OSS_DEV_BUCKET` / `ALIYUN_OSS_TEST_BUCKET` / `ALIYUN_OSS_PROD_BUCKET` | 否 | 阿里云 OSS Bucket未配置时可兜底 `ALIYUN_OSS_BUCKET`。 |
| `ALIYUN_OSS_DEV_ACCESS_KEY_ID` / `ALIYUN_OSS_TEST_ACCESS_KEY_ID` / `ALIYUN_OSS_PROD_ACCESS_KEY_ID` | 是 | 阿里云 OSS AccessKey ID未配置时可兜底 `ALIYUN_OSS_ACCESS_KEY_ID`。 |
@@ -181,7 +194,8 @@
- 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 结果,不创建订单、不创建任务、不调用任务结果通知接口。
- AgentBus 实时收到邮件后自动推 SuperAgent 当前未实现,不能把 Debug EML 链路等同于生产实时自动处理链路。
- AgentBus 实时收到邮件后自动推 SuperAgent 已由 M007 后端 V1 实现,不能把 Debug EML 链路等同于生产实时自动处理链路。
- Debug EML 和 AgentBus 自动分发复用同一个 SuperAgent Open API SSE 稳定客户端;上线前必须验证 `run.completed + end + final answer` 严格成功条件和 EOF 后 `/events` 恢复。
## 4. 数据库上线注意事项
@@ -207,6 +221,10 @@
- `server/src/main/resources/db/migration/V8__create_source_message_payload_duplicate.sql`
当前 M007 AgentBus 自动分发 SuperAgent 相关 migration
- `server/src/main/resources/db/migration/V20__create_superagent_dispatch_run.sql`
当前 M003 登录权限相关 migration
- `server/src/main/resources/db/migration/V9__create_identity_access_hotel_menu.sql`
@@ -295,8 +313,8 @@ Header: X-TH-Hotel-Access-Scene
AgentBus 是消息入口,不是 AI Provider。生产实时链路必须保持以下边界
- 只写 SourceMessage Inbox。
- 不自动调用 SuperAgent。
- WebSocket 回调内只做 SourceMessage Inbox 入库和轻量 dispatch 标记
- 如启用 M007只能在入库后通过受控异步 dispatch / outbox 调用 SuperAgent。
- 不创建 MessageEvent、Evidence、Case、Task、Operation、Receipt。
- 不调用 OHIP、ERP、支付系统等业务写接口。
- 不自动发送 ACK、`task.result` 或客户回复。
@@ -311,11 +329,14 @@ AgentBus 是消息入口,不是 AI Provider。生产实时链路必须保持
5. 观察 `/api/system/agentbus-probe`,确认连接状态、`sessionReady`、计数器和最近错误代码。
6. 用合成测试邮件验证 SourceMessage Inbox 是否写入。
7. 确认日志和监控没有泄露 raw frame、正文或附件 URL。
8. 如需开启 M007 自动分发,先保持 worker 关闭并确认 dispatch run 能正确创建,再打开 worker 处理少量合成邮件。
9. 验证 SuperAgent dispatch 成功不会直接创建订单或任务,业务任务仍只来自 SuperAgent 后续任务结果通知或 MCP 提交。
如果出现异常:
- 先关闭 `AGENTBUS_PROBE_ENABLED`,停止接收入站 frame。
- 如果只是想暂停入库但保留连接,可关闭 `AGENTBUS_CAPTURE_ENABLED`
- 如果只想暂停 M007 自动分发,优先关闭 `AGENTBUS_SUPERAGENT_DISPATCH_WORKER_ENABLED`;如需停止新建 dispatch再关闭 `AGENTBUS_SUPERAGENT_DISPATCH_ENABLED`
- 保留状态接口、应用日志和数据库记录用于排查,但不要导出真实邮件正文或附件 URL。
## 7. 上线后冒烟验证

View File

@@ -27,7 +27,7 @@ SuperAgent 和 AgentBus 不应被设计成同一个模块。
AgentBus
→ 接收 Email / LINE 等外部渠道消息
→ 保存 SourceMessage Inbox
→ 受控 Replay 为 MessageEvent / Evidence
→ 受控异步分发 / Replay
→ 调用 AI 能力端口
→ SuperAgent Provider Adapter
→ 保存 AI Capability Invocation
@@ -46,7 +46,7 @@ AgentBus
核心原则:
- 前端不直接调用 SuperAgent 或 AgentBus不接触任何 Provider Secret。
- AgentBus 实时链路只落来源事实,不直接生成 Case、Task、Operation 或客户回复。
- AgentBus 实时入口必须先落来源事实;如需推送 SuperAgent只能通过入库后的受控异步 dispatch / outbox 链路完成,不直接生成 Case、Task、Operation 或客户回复。
- SuperAgent 返回内容只能作为建议、证据或审计结果,不能直接改变业务最终状态。
- 业务写操作必须经过平台规则校验、权限控制、幂等控制和人工确认。
@@ -94,6 +94,8 @@ TH Hotel 当前 M001 相关代码中的可参考文件:
| SourceMessage 原文读取审计表 | `server/src/main/resources/db/migration/V2__create_source_message_original_access_audit.sql` |
SourceMessage Replay 到 MessageEvent / Evidence 尚未实现,需等 MessageEvent、Evidence 字段模型确认后再进入后续 checkpoint。
AgentBus SourceMessage 入库后自动分发 SuperAgent 后端 V1 已实现,默认关闭,详见
`docs/project/requirements/M007-agentbus-superagent-auto-dispatch-v1.md`
## 4. SuperAgent 对接
@@ -123,7 +125,7 @@ SUPERAGENT_EXTERNAL_SUBJECT_ID=your-project-superagent-probe
| `SUPERAGENT_PROBE_ENABLED` | 否 | 是否开放本项目自己的探针接口。生产默认关闭。 |
| `SUPERAGENT_PROBE_ACCESS_KEY` | 是 | 调用探针接口的本地访问密钥,不是 Provider API Key。 |
| `SUPERAGENT_CONNECT_TIMEOUT` | 否 | 建立连接超时。 |
| `SUPERAGENT_READ_TIMEOUT` | 否 | SSE 读取超时。 |
| `SUPERAGENT_READ_TIMEOUT` | 否 | 旧版 RestClient SSE 读取超时兼容变量;当前 JDK SSE 客户端不设置整段 SSE 固定读取超时,断流恢复由 run/events 机制处理。 |
| `SUPERAGENT_MAX_MESSAGE_CHARS` | 否 | 单次发送给 Provider 的消息长度上限。 |
| `SUPERAGENT_EXTERNAL_SUBJECT_ID` | 否 | 创建 Agent Session 时使用的外部主体标识。 |
@@ -139,15 +141,16 @@ POST /api/open/agent-sessions
→ 解析最终 answer、run、profile、model、token usage
```
状态变更请求需要 CSRF double-submit
2026-07-12 Open API 文档中Java SSE 调用使用 `Authorization: Bearer <DEERFLOW_OPEN_API_KEY>`
`X-DeerFlow-Open-API-Key` 鉴权,并通过 `X-Request-ID``idempotency_key` 和 metadata 做调用关联。
当前 TH Hotel 后端 `SuperAgentOpenApiClientImpl` 不发送 CSRF double-submit。
```text
X-CSRF-Token: <random-csrf-token>
Cookie: csrf_token=<same-random-csrf-token>
Authorization: Bearer <DEERFLOW_OPEN_API_KEY>
X-Request-ID: <stable-request-id>
```
CSRF Token 由客户端实例临时生成,不需要写入配置,也不能当作 Secret 长期保存
如果 SuperAgent 服务端后续重新要求 CSRF double-submit应先更新本文和 Open API client再开启 M007 worker
### 4.3 Session 请求示例
@@ -207,6 +210,23 @@ content 非空
如果没有收到 `end`,或无法找到最终 AI 回答,应视为协议失败,不要伪造成成功结果。
### 4.5.1 2026-07-12 SSE 断流恢复要求
2026-07-12 导入的 `docs/import/20260712/OPEN_AGENT_API_JAVA_SSE_CLIENT.md` 已补充 Java 后端调用
SuperAgent Open API 的稳定性要求。后续 TH Hotel 的共享 SuperAgent Open API client 必须满足:
- 初始 `messages/stream?include_trace=true` 请求携带稳定 `X-Request-ID`
- 同一业务 SourceMessage 的 `idempotency_key` 在所有尝试中保持不变。
- 初始 POST 成功后保存响应头 `Content-Location`,解析并保存 SuperAgent `run_id`
- SSE 必须按帧解析 `event:``data:``id:` 和 heartbeat comment并保存 `lastEventId`
- 成功条件必须同时满足最终 AI 内容、`run.completed status=success`、顶层 `event: end`,且没有顶层 `error``run.failed`
- EOF、Premature EOF、incomplete chunked response 不能当成功。
- 如果已有 `run_id`,断流后不得重新 POST 初始消息,应先查询 `GET /runs/{run_id}`,再通过 `GET /runs/{run_id}/events` 携带 `Last-Event-ID` 恢复。
- 恢复失败应记录为可诊断失败,不返回部分回答。
中文说明:该要求同时适用于 Debug EML 和 M007 AgentBus 自动分发链路。实现时应优先改造共享
SuperAgent Open API client避免调试链路和生产链路行为分叉。
### 4.6 平台能力端口
其他项目建议定义一个稳定端口,例如:
@@ -268,6 +288,8 @@ AGENTBUS_SAMPLE_DIR=var/agentbus-samples
AGENTBUS_MAX_FRAME_BYTES=1048576
AGENTBUS_MAX_SAMPLES=100
AGENTBUS_CAPTURE_ENABLED=true
AGENTBUS_SUPERAGENT_DISPATCH_ENABLED=false
AGENTBUS_SUPERAGENT_DISPATCH_WORKER_ENABLED=false
AGENTBUS_REPLY_MODE=NONE
AUTH_DEV_BOOTSTRAP_DEFAULT_HOTEL_ID=HOTEL-DEV
SOURCE_MESSAGE_DEV_ORIGINAL_READ_ACCESS_KEY=
@@ -289,6 +311,13 @@ SOURCE_MESSAGE_ORIGINAL_READ_ACCESS_KEY=
| `AGENTBUS_MAX_FRAME_BYTES` | 否 | 单个入站 frame 最大字节数。 |
| `AGENTBUS_MAX_SAMPLES` | 否 | 最多保留的本地样本数。 |
| `AGENTBUS_CAPTURE_ENABLED` | 否 | 是否写入 SourceMessage Inbox。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_ENABLED` | 否 | AgentBus 新邮件入库后是否创建 SuperAgent 自动分发记录,默认关闭。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_WORKER_ENABLED` | 否 | 是否启动 SuperAgent 自动分发 worker默认关闭。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_MAX_ATTEMPTS` | 否 | 单条 dispatch 最大尝试次数,默认 `3`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_BATCH_SIZE` | 否 | worker 每轮领取数量,默认 `10`。 |
| `AGENTBUS_SUPERAGENT_DISPATCH_LOCK_TTL` | 否 | worker 抢占锁有效期,默认 `5m`。 |
| `SUPERAGENT_AGENTBUS_EXTERNAL_SUBJECT_ID` | 否 | AgentBus 自动分发创建 SuperAgent session 的 external subject id。 |
| `SUPERAGENT_OPEN_API_SSE_RECOVERY_MAX_ATTEMPTS` | 否 | SSE 断流恢复最大次数,默认 `5`。 |
| `AUTH_DEV_BOOTSTRAP_DEFAULT_HOTEL_ID` | 否 | dev 初始化平台酒店M005 后 AgentBus 捕获运行时从 `platform_hotel` 唯一 `ACTIVE` 酒店解析系统酒店,不再依赖 `AGENTBUS_DEFAULT_HOTEL_ID`。 |
| `AGENTBUS_REPLY_MODE` | 否 | 调试回复模式。真实客户渠道应保持 `NONE`。 |
| `SOURCE_MESSAGE_DEV_ORIGINAL_READ_ACCESS_KEY` | 是 | dev 原文读取接口的临时受控访问 key后续可替换为正式权限体系。 |
@@ -327,6 +356,7 @@ GET /api/system/agentbus-probe
→ 忽略 session.ready / task.progress / task.result 等控制事件
→ 将业务 payload 映射为 CaptureSourceMessageCommand
→ 写入 SourceMessage Inbox
→ 如 M007 dispatch 配置开启且为新建 RECEIVED Inbox创建 SuperAgent dispatch run
```
实时链路禁止:
@@ -336,6 +366,7 @@ GET /api/system/agentbus-probe
- 自动回复客户。
- 直接创建 MessageEvent、Evidence、AI Recognition、Case、Task、Operation 或 Receipt。
- 直接调用 OHIP、ERP、支付系统等业务写接口。
- 在 WebSocket 回调事务内同步等待 SuperAgent 返回。
### 5.4 当前已确认的 Outlook Payload 关键字段
@@ -427,6 +458,31 @@ Replay 负责:
Replay 接口默认关闭仅在本地、UAT 或受控生产运维场景开启。
### 5.7 AgentBus 入库后自动分发 SuperAgent
M007 已实现的自动分发链路不是 Debug EML也不是 SourceMessage Replay。它只负责把 AgentBus 新入库邮件异步交给 SuperAgent Open API
```text
AgentBus 新业务 frame
→ SourceMessage Inbox RECEIVED
→ platform_superagent_dispatch_run PENDING
→ worker 调用 SuperAgent Open API
→ 保存 session_id / run_id / raw answer / parsed json / 状态
→ 等待 SuperAgent 后续通过 task-results 或 MCP 提交业务结果
```
第一版规则:
- 仅处理 `provider=AGENTBUS``capture_status=RECEIVED` 的新 SourceMessage。
- 重复 AgentBus 投递不重复创建 dispatch run。
- `provider=DEBUG_EML_UPLOAD` 不进入生产 dispatch。
- `FAILED` SourceMessage 不进入 dispatch。
- dispatch 成功不代表已经创建订单或任务。
- 任务创建仍由 SuperAgent 后续调用本系统任务结果通知接口或 MCP 写入工具触发。
当前表名为 `platform_superagent_dispatch_run`,详细字段、状态流转、错误分类和验收标准见
`docs/project/requirements/M007-agentbus-superagent-auto-dispatch-v1.md`
## 6. 其他项目最小落地顺序
### 阶段 1SuperAgent 连通性
@@ -481,7 +537,26 @@ AgentBus 入站业务 frame
- 重复外部消息不重复入库。
- 查询接口只返回安全摘要。
### 阶段 4手动 Replay
### 阶段 4自动分发 SuperAgent
目标:
```text
SourceMessage Inbox
→ SuperAgent dispatch / outbox
→ SuperAgent Open API
→ 保存 dispatch run
```
验收:
- 仅新建 `AGENTBUS` + `RECEIVED` SourceMessage 创建 dispatch。
- 重复邮件不重复 dispatch。
- Debug EML 不进入生产 dispatch。
- SuperAgent SSE 成功条件和断流恢复符合 2026-07-12 新文档。
- dispatch 成功不直接创建订单或任务。
### 阶段 5手动 Replay
目标:
@@ -497,7 +572,7 @@ SourceMessage Inbox
- Replay 失败有 attempt 记录。
- 响应不返回客户正文、HTML、附件 URL 或 Token。
### 阶段 5:业务接入 SuperAgent
### 阶段 6:业务接入 SuperAgent
目标:
@@ -534,7 +609,6 @@ MessageEvent
- Authorization
- Cookie
- CSRF Token
- Provider API Key
- AgentBus Token
- 邮件正文和 HTML
@@ -554,13 +628,15 @@ MessageEvent
SuperAgent 建议覆盖:
- 缺失 API Key 时启动或调用失败。
- CSRF Header / Cookie 不一致时转换为受控错误。
- Bearer API Key 缺失、错误或权限不足时转换为受控错误。
- 创建 Session 成功。
- SSE 正常结束并解析最终回答。
- SSE 缺少 `end` 时失败。
- SSE 缺少最终回答时失败。
- SSE 缺少 `run.completed status=success` 时失败。
- SSE 断流后携带 `Last-Event-ID` 通过 `/runs/{run_id}/events` 恢复,且不重发初始 POST。
- HTTP 401 / 403 / 404 / 409 / 5xx 错误转换。
- 连接超时和读取超时
- 连接超时,以及 SSE 断流后的 run/events 恢复
AgentBus 建议覆盖:
@@ -604,7 +680,7 @@ SuperAgent 返回的是 Provider 输出。即使未来返回结构化 JSON
接入 SuperAgent 前确认:
- [ ] 已获得 Open API Key 和允许访问的 Base URL。
- [ ] 已确认是否需要 CSRF double-submit。
- [ ] 已确认当前 Open API 鉴权方式;如需 CSRF double-submit,已同步更新后端 client
- [ ] 已确认 Session、Message、Run 的生命周期。
- [ ] 已确认 SSE 最终答案或结构化结果所在字段。
- [ ] 已定义 `AgentCapabilityPort` 和调用审计表。

View File

@@ -52,7 +52,7 @@
### 证据
- 已有 AgentBus 对接文档确认 Outlook 邮件 payload 包含 `source.external_message_id``source.external_conversation_id``body.html``body.text``inline_images[]``attachments[]` 等字段。
- 已有后端规范要求 AgentBus 实时链路只写 SourceMessage Inbox不直接生成 MessageEvent、Evidence、Case、Task、Operation 或 Receipt。
- 已有后端规范要求 AgentBus 实时入口必须先写 SourceMessage Inbox;后续如需调用 SuperAgent必须通过入库后的受控异步 dispatch / outbox 链路完成,不直接生成 MessageEvent、Evidence、Case、Task、Operation 或 Receipt。
- 🔶 Assumption业务人员后续会在某些业务功能中查看邮件原文但具体功能和页面还未确定。
## 3. Target Users & Personas
@@ -238,7 +238,7 @@ SOURCE_MESSAGE_ORIGINAL_READ
### Guardrail Metrics
- 列表接口、普通详情接口、日志、错误响应不得暴露完整正文、HTML、附件 URL、Token 或 Secret。
- AgentBus 实时链路不得直接创建 Case、Task、Operation、Receipt 或客户回复。
- AgentBus 实时入口不得在 WebSocket 回调内直接创建 Case、Task、Operation、Receipt 或客户回复M007 SuperAgent 自动分发也必须以 SourceMessage 入库后的异步 dispatch 为边界
## 7. User Stories & Requirements

View File

@@ -12,7 +12,7 @@
## 1. 文档定位
本文记录 Debug EML 上传链路的第一版后端设计。该能力用于在不依赖 AgentBus 实时自动处理的情况下,
本文记录 Debug EML 上传链路的第一版后端设计。该能力用于在不依赖 AgentBus 实时生产链路的情况下,
由调试页面上传 `.eml` 邮件文件,后端解析邮件、转存附件和内联图片到本系统阿里云 OSS
再组装成 SuperAgent 可处理的邮件输入并调用 SuperAgent Open API。
@@ -26,7 +26,7 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- 第一版只展示 SuperAgent 生成结果,不落业务订单和任务。
- 上传邮件仍要写入 SourceMessage Inbox。
- Debug 上传来源必须和 AgentBus 来源区分,建议 `provider=DEBUG_EML_UPLOAD`
- AgentBus 实时收到邮件后自动推 SuperAgent 当前未实现;现有 AgentBus 实时链路只负责写入 SourceMessage Inbox
- AgentBus 实时收到邮件后自动推 SuperAgent 已由 M007 后端 V1 实现M004 仍只代表人工 Debug 上传链路,不代表生产实时自动处理链路
- 使用真实阿里云 OSS不使用本地 mock OSS。
- 原始 `.eml` 文件本身也上传到阿里云 OSS便于后续调试追溯。
- 内联图片和普通附件都上传到阿里云 OSS。
@@ -82,7 +82,7 @@ Inbox 作为来源事实,但不创建订单、不创建任务、不写 AI 任
- 不做邮件多封批量上传。
- 不做 ZIP、MSG、PDF、图片 OCR 或 Excel 解析。
- 不做 SourceMessage Replay 到 MessageEvent / Evidence。
- 不做 AgentBus 实时邮件自动调用 SuperAgent该能力后续需要单独设计触发、幂等、限流和失败补偿。
- 不做 AgentBus 实时邮件自动调用 SuperAgent该能力由 M007 单独设计触发、幂等、限流、断流恢复和失败补偿。
- 不做普通任务切换订单。
- 不做 SuperAgent 查询接口 3、4。
- 不接入完整用户 / 权限体系。

View File

@@ -0,0 +1,245 @@
# M007 AgentBus SourceMessage 自动分发 SuperAgent 链路 V1
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 1.0 |
| 日期 | 2026-07-12 |
| 状态 | 后端 V1 已实现,等待测试机联调 |
| 适用范围 | AgentBus 实时邮件入库后,异步调用 SuperAgent Open API 的生产链路 |
| 主要读者 | 产品、后端、测试、运维、SuperAgent 对接方、后续协作 agent |
## 1. 背景和目标
M001 已完成 AgentBus 邮件来源事实入库M004 已完成 Debug EML 人工上传并调用 SuperAgent 的调试链路。当前缺口是:真实 AgentBus WebSocket 收到邮件并写入 SourceMessage Inbox 后,还没有生产链路自动把该邮件推送给 SuperAgent。
本 checkpoint 目标是补齐这条链路:
```text
AgentBus WebSocket 收到邮件
→ 写入 SourceMessage Inbox
→ 创建 SuperAgent dispatch / outbox 记录
→ 异步 worker 调用 SuperAgent Open API
→ 保存 session_id / run_id / raw_answer / parsed_json / 状态
→ 等待 SuperAgent 通过现有任务结果通知接口或 MCP 提交业务结果
```
中文说明AgentBus 仍然是消息入口SuperAgent 仍然是外部 AI / Agent 能力提供方。自动分发只负责把已入库 SourceMessage 交给 SuperAgent不直接创建订单、任务、OPERA 操作或客户回复。
## 2. 设计原则
- AgentBus WebSocket 回调内只做快速入库和轻量投递标记,不同步等待 SuperAgent。
- SourceMessage 捕获事务和 SuperAgent 外部调用事务分离,避免外部慢请求影响邮件入库。
- 使用 outbox / dispatch run 表记录状态、重试、幂等键和 SuperAgent run 信息。
- Debug EML 链路和生产自动分发链路复用 SuperAgent Open API client但运行记录表和 provider 必须区分。
- SuperAgent 返回内容只能保存为外部能力输出,不直接改变业务最终状态。
- 业务任务创建继续依赖 SuperAgent 后续调用本系统任务结果通知接口或 MCP 工具。
## 3. 触发规则
第一版只对以下 SourceMessage 创建自动分发记录:
| 条件 | 规则 |
| --- | --- |
| 来源 provider | 必须是 `AGENTBUS` |
| 捕获状态 | 必须是 `RECEIVED` |
| 幂等结果 | 仅 `SourceMessageCaptureResult.newlyCreated=true` 时触发 |
| 重复投递 | 不重复创建 dispatch如 payload changed只记录 SourceMessage 重复诊断 |
| Debug EML | 不参与生产自动分发 |
| FAILED Inbox | 不分发,保留入库失败原因供排查 |
中文说明:后续如果需要对历史 SourceMessage 补发 SuperAgent应单独设计人工 replay / backfill 接口,不在本 checkpoint 内隐式补发。
## 4. SuperAgent Open API 稳定性要求
2026-07-12 导入的 `OPEN_AGENT_API_JAVA_SSE_CLIENT.md` 对 Java SSE 调用提出新的强约束。本项目后续 Open API client 必须满足:
- 请求 `messages/stream?include_trace=true` 时生成稳定 `X-Request-ID`
- 同一业务 SourceMessage 的 `idempotency_key` 在所有尝试中保持不变。
- 初始 POST 成功后保存响应头 `Content-Location`,解析并保存 SuperAgent `run_id`
- SSE 必须按帧解析 `event:``data:``id:` 和 heartbeat comment。
- 成功条件必须同时满足:最终 AI 内容、`run.completed status=success`、顶层 `event: end`,且没有顶层 `error``run.failed`
- EOF、Premature EOF、incomplete chunked response 不能当成功。
- 断流后如果已有 `run_id`,不得重新 POST 初始消息;应先查询 `GET /runs/{run_id}`,再通过 `GET /runs/{run_id}/events` 携带 `Last-Event-ID` 恢复。
- 恢复失败应记录为可诊断失败,不返回部分回答。
中文说明:这条规则同时适用于 Debug EML 和 AgentBus 自动分发。实现时应优先改造共享 SuperAgent Open API client避免两条链路行为不一致。
## 5. 数据模型建议
新增表建议命名为 `platform_superagent_dispatch_run`,作为 SourceMessage 到 SuperAgent Open API 的生产分发运行记录。
核心字段建议:
| 字段 | 中文说明 |
| --- | --- |
| `id` | 内部主键 ID |
| `hotel_id` | SourceMessage 所属酒店 ID |
| `source_message_id` | 本系统内部 SourceMessage Inbox ID |
| `source_provider` | 来源 provider第一版主要为 `AGENTBUS` |
| `source_channel` | 来源 channel例如 `OUTLOOK``EMAIL` |
| `external_message_id` | AgentBus 邮件外部消息 ID |
| `external_conversation_id` | AgentBus 邮件会话 ID |
| `dispatch_source` | 分发来源代码,第一版为 `AGENTBUS_REALTIME` |
| `idempotency_key` | 发送给 SuperAgent 的业务幂等键,同一 SourceMessage 固定 |
| `request_id` | 本系统生成的调用关联 ID同时写入 `X-Request-ID` |
| `dispatch_status` | `PENDING``RUNNING``SUCCEEDED``RETRYABLE_FAILED``FAILED``IGNORED` |
| `attempt_count` | 已尝试次数 |
| `max_attempts` | 最大尝试次数 |
| `next_attempt_at` | 下次可重试 UTC 时间 |
| `locked_until` | worker 抢占锁过期 UTC 时间 |
| `superagent_session_id` | SuperAgent Open API session ID |
| `superagent_run_id` | SuperAgent run ID |
| `superagent_run_uri` | SuperAgent run 查询路径或 URI |
| `last_event_id` | 最后完整处理的 SSE event id |
| `superagent_raw_answer` | SuperAgent 最终原始回答 |
| `superagent_parsed_json` | 能解析为 JSON 时保存的结构化结果 |
| `superagent_trace_json` | 可安全保存的公开 trace 摘要 |
| `safe_error_code` | 安全错误代码 |
| `safe_error_summary` | 安全错误摘要不包含正文、HTML、附件 URL 或 Secret |
| `created_at` / `updated_at` | 记录创建和更新时间UTC |
约束建议:
```text
UNIQUE KEY uk_dispatch_source_message (source_message_id, dispatch_source)
KEY idx_dispatch_status_next_attempt (dispatch_status, next_attempt_at)
KEY idx_dispatch_external_message (hotel_id, external_message_id)
```
中文说明:`source_message_id + dispatch_source` 是本系统内的分发幂等边界。外部 `idempotency_key` 是给 SuperAgent 的幂等边界,两者都需要稳定。
## 6. 配置建议
第一版新增配置建议:
| 配置 | 默认值 | 中文说明 |
| --- | --- | --- |
| `agentbus.superagent-dispatch.enabled` | `false` | 是否在 AgentBus 新邮件入库后创建自动分发记录 |
| `agentbus.superagent-dispatch.worker-enabled` | `false` | 是否启动异步 worker 处理 dispatch |
| `agentbus.superagent-dispatch.max-attempts` | `3` | 单条 dispatch 最大尝试次数 |
| `agentbus.superagent-dispatch.batch-size` | `10` | worker 每轮领取数量 |
| `agentbus.superagent-dispatch.lock-ttl` | `5m` | worker 处理锁有效期 |
| `agentbus.superagent-dispatch.initial-backoff` | `30s` | 首次失败后的重试等待时间 |
| `agentbus.superagent-dispatch.max-backoff` | `15m` | 最大重试等待时间 |
| `superagent.open-api.agentbus-external-subject-id` | `th-hotel-agentbus-source-message` | AgentBus 自动分发创建 session 时使用的 external subject id |
| `superagent.open-api.sse-recovery-max-attempts` | `5` | SSE 断流恢复最大次数 |
中文说明:生产首次上线建议先开启 AgentBus 入库,确认稳定后再单独开启自动分发和 worker。Debug EML 使用的访问 key 和生产自动分发无关。
## 7. 消息组装
AgentBus 自动分发发送给 SuperAgent 的 message 第一版应基于 SourceMessage 原始 payload 构造,保持和 Debug EML 的 AgentBus-like payload 语义一致。
发送 metadata 建议包含:
```json
{
"source": "th-hotel-agentbus-realtime",
"dispatch_run_id": "内部 dispatch run ID",
"source_message_id": "内部 SourceMessage Inbox ID",
"external_message_id": "AgentBus external_message_id",
"external_conversation_id": "AgentBus external_conversation_id",
"hotel_id": "系统酒店 ID"
}
```
注意metadata 里的内部 SourceMessage ID 只用于本系统排查SuperAgent 后续任务结果通知中的 `source_message_id` 仍应使用 AgentBus `source.external_message_id`
## 8. 状态流转
```text
PENDING / RETRYABLE_FAILED
→ RUNNING
→ SUCCEEDED
RUNNING
→ RETRYABLE_FAILED
→ RUNNING
RUNNING / RETRYABLE_FAILED
→ FAILED
任意未启用或不应处理场景
→ IGNORED
```
失败分类建议:
| 当前错误代码 | 中文说明 | 是否可重试 |
| --- | --- | --- |
| `SUPERAGENT_DISPATCH_FAILED` | SuperAgent Open API 调用失败,具体 HTTP / SSE / run 失败原因写入安全摘要 | 是,直到超过 max attempts |
| `SOURCE_MESSAGE_PAYLOAD_NOT_FOUND` | SourceMessage 原始 payload 缺失 | 是,直到超过 max attempts通常需要人工排查数据 |
| `SUPERAGENT_DISPATCH_UNEXPECTED` | dispatch worker 内部非预期错误 | 是,直到超过 max attempts |
中文说明:如果已经获得 `superagent_run_id`,后续恢复不得重新发送初始 POST避免同一业务消息被执行两次。
## 9. 非目标范围
本 checkpoint 不做:
- 不创建 Reservation 订单。
- 不创建 Reservation 任务。
- 不调用 OPERA / OHIP。
- 不自动 ACK AgentBus。
- 不自动发送 `task.result`
- 不自动回复客户。
- 不做历史 SourceMessage 批量补发。
- 不做前端页面。
- 不改变 SuperAgent 任务结果通知接口的业务处理规则。
## 10. 验收标准
- AgentBus 新邮件入库成功后,在开启配置时创建一条 dispatch run。
- 重复 AgentBus 邮件投递不会创建第二条 dispatch run。
- Debug EML 不会进入生产 dispatch run。
- `FAILED` SourceMessage 不会触发 dispatch。
- worker 能领取 `PENDING` 记录并调用 SuperAgent Open API。
- SuperAgent 调用成功时保存 session、run、raw answer、parsed json、trace 摘要和 `SUCCEEDED` 状态。
- SuperAgent SSE 缺少 `end`、缺少最终内容或 `run.completed` 时不能成功。
- SSE EOF 后如果已有 `run_id`,使用 `/events` 恢复,不重发初始 POST。
- 恢复耗尽后记录安全错误摘要和可重试状态。
- 任务创建仍只由 SuperAgent 后续任务结果通知接口或 MCP 提交触发。
- 测试覆盖 AgentBus 触发、幂等、失败、不处理 Debug EML、SSE 严格成功条件和断流恢复。
## 11. 已实现代码范围
本次后端 V1 已落地:
- 新增 `platform_superagent_dispatch_run` 表和 `V20__create_superagent_dispatch_run.sql`
- 新增 `SuperAgentDispatchRunEntity`、Mapper、Repository、Service 和配置类。
- AgentBus 捕获 `AGENTBUS + RECEIVED + newlyCreated=true` 后,在配置开启时创建 dispatch run。
- worker 处理 `PENDING / RETRYABLE_FAILED`,调用共享 SuperAgent Open API client。
- Open API client 支持 `Content-Location``run_id`、SSE `id``Last-Event-ID``GET /runs/{run_id}``GET /runs/{run_id}/events` 恢复。
- Debug EML 继续复用共享 Open API client。
- dispatch 成功保存 session、run、last event id、raw answer、parsed json、trace 摘要和状态。
## 12. 后续目标模式建议
```text
进入目标模式,目标:实现 M007 AgentBus SourceMessage 自动分发 SuperAgent 链路 V1。
范围:
1. 按 docs/project/requirements/M007-agentbus-superagent-auto-dispatch-v1.md 实现 AgentBus 入库后的异步 SuperAgent dispatch / outbox。
2. 新增 platform_superagent_dispatch_run 表、Entity、Mapper、Repository、Service、ServiceImpl 和必要枚举 / DTO。
3. AgentBus 捕获新 SourceMessage 成功后,在配置开启时创建 dispatch run重复投递不重复创建。
4. 新增 worker 处理 PENDING / RETRYABLE_FAILED dispatch调用 SuperAgent Open API。
5. 改造 SuperAgent Open API client满足 20260712 SSE 稳定性要求严格成功条件、Content-Location/run_id、SSE id、Last-Event-ID、/runs 查询和 /events 恢复EOF 后不重发初始 POST。
6. Debug EML 继续复用改造后的 SuperAgent Open API client行为不回退。
7. 保存 SuperAgent session_id、run_id、last_event_id、raw answer、parsed json、trace 摘要、状态和安全错误摘要。
8. 更新集成文档、上线注意事项和配置说明。
9. 补充测试覆盖触发、幂等、失败、Debug EML 不触发、SSE 严格成功条件和断流恢复。
不做:
1. 不创建订单。
2. 不创建任务。
3. 不调用 OPERA / OHIP。
4. 不自动 ACK AgentBus。
5. 不自动发送 task.result 或客户回复。
6. 不做历史 SourceMessage 批量补发。
7. 不做前端页面。
完成后:
code review运行测试中文提交。
```