Files
SuperBizAgent-java/mvp/issues/archived/ISS-013-chat-entry-decoupling-and-sse.md
T

83 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ISS-013 Chat 入口解耦与真正 SSE 收敛
**状态**:已被 ISS-014 吸收并归档(2026-07-22)
**吸收结果**:唯一 `/api/chat` named SSE、Chat Application Use Case、bounded executor、exact Run cancel 和前端单 consumer 已由 ISS-014 阶段 6A/6B 完成,最终 E2E 归入阶段 7。
**严重程度**:高
**发现时间**:2026-07-20
**关联**:ISS-011、ISS-012
---
## 背景
当前 Chat 入口同时提供 `/api/chat` 和 `/api/chat_stream`。`ChatController` 不仅处理 HTTP/SSE 协议,还直接承担会话创建、历史读取与回写、模型和工具获取、执行策略调用以及异常响应组装,入口职责已经明显超出协议适配层。
现有 `/api/chat_stream` 会等待完整答案生成后再按固定长度切片发送,并不是真正的流式生成。同步和伪流式入口还复制了大部分业务流程,增加了维护成本和行为不一致风险。
## 已确认问题
1. Chat 的会话、历史、模型、工具、执行和结果回写功能耦合在 `ChatController` 中,HTTP 层与应用用例边界不清晰。
2. `/api/chat` 与 `/api/chat_stream` 重复编排同一套 Chat 流程。
3. `/api/chat_stream` 只是对完整答案做事后分块,不具备模型生成过程中的真实增量输出能力。
4. Controller 直接获取 `ChatModel` 和 `ToolCallbackProvider`,将模型基础设施细节暴露到入口层。
5. SSE 使用 Controller 自建的无界缓存线程池,缺少统一生命周期和容量治理。
6. 当前入口错误响应存在 HTTP 状态、外层 `ApiResponse` 与内层 `ChatResponse` 状态不一致的问题。
## 目标
1. 将会话生命周期、历史管理、执行调用和结果回写从 Controller 分离,形成单一 Chat 应用用例入口。
2. 只保留一个 `/api/chat` 接口,并将其协议改为真正的 SSE。
3. SSE 在模型或诊断链路产生内容时增量发送,而不是等待完整答案后再切片。
4. 保留 `sessionId + runId` 作为一次 Chat Run 的稳定关联契约。
5. 在满足入口职责分离的前提下使用最少组件,不引入没有实际职责的接口、工厂或适配层。
## 设计约束
- Controller 只负责请求校验、协议转换和 SSE 生命周期,不负责选择模型、组装工具、管理历史或编排诊断流程。
- 同一次请求只能进入一个应用用例入口,禁止同步和流式路径各自维护一套业务逻辑。
- 真正 SSE 至少需要区分元数据、内容增量、完成和错误事件。
- `sessionId`、`runId` 必须在内容事件之前可获得,并用于日志、数据库和 Trace 对齐。
- 客户端断开、超时和执行失败必须显式终止后台执行并完成 Run 状态记录。
- 不保留旧 `/api/chat_stream` 或同步 `/api/chat` 的兼容分支,直接以新协议为准。
- 优先使用 Spring 管理的执行设施和现有服务能力,不创建无界线程池。
## 建议的最小边界
```text
POST /api/chat (SSE)
-> ChatController:请求与 SSE 协议
-> Chat 应用用例:会话、Run、历史和执行生命周期
-> 现有 Chat 执行能力:简单回答或诊断编排
```
这里的“应用用例”是职责边界,不要求预先拆出多层接口。只有出现独立变化原因或明确复用需求时才增加新组件。
## 验收标准
- [ ] 对外只保留一个 `POST /api/chat`,响应类型为 `text/event-stream`。
- [ ] 删除 `/api/chat_stream` 及同步 Chat 兼容路径。
- [ ] 首个内容事件在完整答案生成完成前发送,禁止通过固定字符切片伪造流式输出。
- [ ] SSE 事件包含稳定的 metadata、content、error、done 契约。
- [ ] Controller 不再直接依赖 `ChatModel`、`ToolCallbackProvider`,也不管理会话历史和 Run 持久化。
- [ ] 同一请求的 `sessionId + runId` 在 SSE、应用日志、`diagnosis_run`、`agent_step` 和 `tool_invocation` 中一致。
- [ ] 客户端断开、超时、模型失败和工具失败都有明确的资源清理与 Run 终态。
- [ ] 不存在 Controller 自建的无界线程池。
- [ ] 单元测试覆盖入口校验和 SSE 事件契约;端到端测试验证真实增量输出、断开清理及 Trace 对齐。
## 非目标
- 不在本 Issue 中重新设计 StateGraph 节点、Gatekeeper、Verifier 或证据协议。
- 不为未来可能出现的其他传输协议预建通用框架。
- 不引入多套 Command、Handler、Adapter、Factory 只为形式上的分层。
- 不保留旧同步接口或 `/api/chat_stream` 的兼容逻辑。
- 不以“完整答案分块发送”作为 SSE 验收通过条件。
## 相关文件
- `src/main/java/com/superbiz/agent/controller/ChatController.java`
- `src/main/java/com/superbiz/agent/service/ChatService.java`
- `src/main/java/com/superbiz/agent/service/session/SessionManager.java`
- `src/test/java/com/superbiz/agent/controller/ChatControllerTest.java`
- `src/test/java/com/superbiz/agent/service/ChatServiceGraphIntegrationTest.java`
- `mvp/architecture/current-mvp-architecture.md`