feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
# WebUI `/api/chat/stream` 前端对接说明
|
|
|
|
|
|
|
|
|
|
|
|
本文档用于指导前端项目接入 LaodingBot 的流式聊天接口,并可直接作为提示词输入给 LLM,批量改造其他前端代码。
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 接口总览
|
|
|
|
|
|
|
|
|
|
|
|
- 方法: `POST`
|
|
|
|
|
|
- 路径: `/api/chat/stream`
|
|
|
|
|
|
- 请求头: `Content-Type: application/json`
|
|
|
|
|
|
- 响应类型: `text/event-stream`
|
|
|
|
|
|
- 协议: SSE (Server-Sent Events)
|
|
|
|
|
|
|
|
|
|
|
|
说明: 该接口为单次请求、多次推送。后端会持续推送 `data: <json>\n\n` 格式的事件。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 请求体
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"text": "请帮我分析当前目录",
|
|
|
|
|
|
"session_id": "sess_abc",
|
|
|
|
|
|
"user_id": "user_001"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
字段说明:
|
|
|
|
|
|
|
|
|
|
|
|
- `text` (string, required): 用户输入文本,去除空白后不能为空。
|
|
|
|
|
|
- `session_id` (string, optional): 会话 ID,不传时后端自动生成。
|
|
|
|
|
|
- `user_id` (string, optional): 用户 ID,不传时后端自动生成。
|
|
|
|
|
|
|
|
|
|
|
|
兼容字段:
|
|
|
|
|
|
|
|
|
|
|
|
- `sessionId` 等价于 `session_id`
|
|
|
|
|
|
- `userId` 等价于 `user_id`
|
|
|
|
|
|
|
|
|
|
|
|
## 3. SSE 事件格式
|
|
|
|
|
|
|
|
|
|
|
|
每条 SSE 消息只包含 `data` 字段,内容是 JSON:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
data: {"type":"thought","content":"我先判断是否需要调用工具","step":1}
|
|
|
|
|
|
|
|
|
|
|
|
data: {"type":"tool_call","content":"{\"input\":\"pwd\"}","step":1,"tool_name":"shell"}
|
|
|
|
|
|
|
|
|
|
|
|
data: {"type":"tool_result","content":"C:/Project/MyProject","step":1,"tool_name":"shell"}
|
|
|
|
|
|
|
|
|
|
|
|
data: {"type":"final","content":"当前目录是 C:/Project/MyProject","step":2}
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
事件字段:
|
|
|
|
|
|
|
|
|
|
|
|
- `type` (string): 事件类型
|
|
|
|
|
|
- `content` (string): 事件文本内容
|
|
|
|
|
|
- `step` (number, optional): ReAct 步骤编号
|
|
|
|
|
|
- `tool_name` (string, optional): 工具名
|
|
|
|
|
|
|
|
|
|
|
|
事件类型:
|
|
|
|
|
|
|
2026-03-14 01:41:51 +08:00
|
|
|
|
- `thought`: LLM 思考片段(可选透传)
|
|
|
|
|
|
- `tool_call`: 工具调用请求(可选透传)
|
|
|
|
|
|
- `tool_result`: 工具执行结果(可选透传)
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
- `final`: 最终回答
|
|
|
|
|
|
- `error`: 错误信息
|
|
|
|
|
|
|
2026-03-13 13:14:37 +08:00
|
|
|
|
说明:
|
|
|
|
|
|
|
2026-03-14 01:41:51 +08:00
|
|
|
|
- 默认情况下(`WEBUI_EXPOSE_REASONING=false`),WebUI 只向前端返回 `final` 和 `error`。
|
|
|
|
|
|
- 当设置 `WEBUI_EXPOSE_REASONING=true` 时,WebUI 会额外透传 `thought`、`tool_call`、`tool_result` 事件。
|
|
|
|
|
|
- 无论是否透传推理事件,`final` 都会分段累计推送,以便前端实现打字机效果。
|
2026-03-13 13:14:37 +08:00
|
|
|
|
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
## 4. 连接生命周期
|
|
|
|
|
|
|
|
|
|
|
|
- 正常结束: 收到 `type=final` 后结束渲染,连接可由浏览器自然关闭。
|
|
|
|
|
|
- 异常结束: 收到 `type=error`,前端应显示错误并结束当前轮次。
|
|
|
|
|
|
- 网络中断: 前端应允许用户重试,并保留已收到的事件记录。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 前端渲染建议
|
|
|
|
|
|
|
2026-03-13 13:14:37 +08:00
|
|
|
|
推荐前端仅处理两类结果:
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
|
|
|
|
|
|
- 答案区: 显示最后一个 `final`
|
|
|
|
|
|
- 错误区: 显示 `error`
|
|
|
|
|
|
|
2026-03-14 01:41:51 +08:00
|
|
|
|
如果开启了 `WEBUI_EXPOSE_REASONING=true`,建议额外提供“思考面板”:
|
|
|
|
|
|
|
|
|
|
|
|
- 思考区: 渲染 `thought`
|
|
|
|
|
|
- 工具区: 渲染 `tool_call` / `tool_result`
|
|
|
|
|
|
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
建议状态机:
|
|
|
|
|
|
|
|
|
|
|
|
- `idle`: 初始状态
|
|
|
|
|
|
- `streaming`: 请求中且持续接收事件
|
|
|
|
|
|
- `done`: 收到 `final`
|
|
|
|
|
|
- `failed`: 收到 `error` 或请求异常
|
|
|
|
|
|
|
|
|
|
|
|
## 6. TypeScript 对接示例 (fetch + ReadableStream)
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-03-14 01:41:51 +08:00
|
|
|
|
type StreamEventType = 'thought' | 'tool_call' | 'tool_result' | 'final' | 'error';
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
|
|
|
|
|
|
interface StreamEvent {
|
|
|
|
|
|
type: StreamEventType;
|
|
|
|
|
|
content: string;
|
|
|
|
|
|
step?: number;
|
|
|
|
|
|
tool_name?: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function streamChat(
|
|
|
|
|
|
payload: { text: string; session_id?: string; user_id?: string },
|
|
|
|
|
|
onEvent: (event: StreamEvent) => void,
|
|
|
|
|
|
signal?: AbortSignal,
|
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
|
const resp = await fetch('/api/chat/stream', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
|
signal,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.ok) {
|
|
|
|
|
|
throw new Error(`HTTP ${resp.status}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!resp.body) {
|
|
|
|
|
|
throw new Error('ReadableStream is not available');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const reader = resp.body.getReader();
|
|
|
|
|
|
const decoder = new TextDecoder('utf-8');
|
|
|
|
|
|
let buffer = '';
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
const { value, done } = await reader.read();
|
|
|
|
|
|
if (done) break;
|
|
|
|
|
|
|
|
|
|
|
|
buffer += decoder.decode(value, { stream: true });
|
|
|
|
|
|
|
|
|
|
|
|
// SSE message delimiter: blank line
|
|
|
|
|
|
let idx = buffer.indexOf('\n\n');
|
|
|
|
|
|
while (idx >= 0) {
|
|
|
|
|
|
const chunk = buffer.slice(0, idx).trim();
|
|
|
|
|
|
buffer = buffer.slice(idx + 2);
|
|
|
|
|
|
|
|
|
|
|
|
for (const line of chunk.split('\n')) {
|
|
|
|
|
|
const text = line.trim();
|
|
|
|
|
|
if (!text.startsWith('data:')) continue;
|
|
|
|
|
|
const raw = text.slice(5).trim();
|
|
|
|
|
|
if (!raw) continue;
|
|
|
|
|
|
|
|
|
|
|
|
const event = JSON.parse(raw) as StreamEvent;
|
|
|
|
|
|
onEvent(event);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
idx = buffer.indexOf('\n\n');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 给 LLM 的改造任务提示词模板
|
|
|
|
|
|
|
|
|
|
|
|
将下面模板发给 LLM,可用于自动改造其他前端项目:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
你要改造一个前端项目的聊天页面,把非流式接口 `/api/chat` 改为流式接口 `/api/chat/stream`。
|
|
|
|
|
|
|
|
|
|
|
|
后端协议约束:
|
|
|
|
|
|
1) 请求方法 POST,Content-Type=application/json
|
|
|
|
|
|
2) 请求体: { text, session_id?, user_id? }
|
|
|
|
|
|
3) 响应是 SSE 文本流,事件格式为 `data: <json>\n\n`
|
|
|
|
|
|
4) JSON 结构:
|
|
|
|
|
|
- type: thought | tool_call | tool_result | final | error
|
|
|
|
|
|
- content: string
|
|
|
|
|
|
- step?: number
|
|
|
|
|
|
- tool_name?: string
|
|
|
|
|
|
5) 收到 final 视为本轮完成;收到 error 视为失败
|
2026-03-14 01:41:51 +08:00
|
|
|
|
6) 默认不要假设前端一定会收到 thought/tool_call/tool_result;仅当 `WEBUI_EXPOSE_REASONING=true` 才会透传
|
feat: implement streaming chat, skill routing, and SAFe PI planning tools
- Add /api/chat/stream endpoint with Server-Sent Events (SSE) for real-time message streaming
* Implement StreamEvent types (thought, tool_call, tool_result, final, error)
* Add StreamEventCallback mechanism for event propagation
* Create StreamChatHandler in webui/bot with proper HTTP headers and flushing
- Implement LLM-based skill router for intelligent capability selection
* Add optional routerLLM client for semantic routing
* Implement routeSkillsWithLLM() to match user intent to available skills
* Add matchSkillsByName() for fuzzy skill matching
* Update buildUnifiedSystemPrompt() to use routed skills
- Add streaming support to ReAct pipeline
* Implement runUnifiedReActStream() for streaming thought/action/observation
* Emit StreamEvent at each ReAct step
* Support callback error handling in streaming mode
- Integrate three new DevOps tools
* tools/filedoc: Extract document content from file_id via OpenAI
* tools/giteaticket: Create Gitea issues from PI plan items with SAFe metadata
* tools/piplan: Publish PI planning blueprints with dependency tracking
- Add SAFe PI Planning skill
* Implement PM/SA/RTE (iron triangle) workflow
* Support for Feature, Enabler, and Dependency definition
* Automatic task decomposition and Gitea integration
- Create frontend integration documentation
* Complete SSE protocol specification
* TypeScript fetch + ReadableStream example
* LLM-ready refactoring template for other projects
- Simplify file handling
* Remove legacy file context structures and dual-mode processing
* Consolidate file operations into UploadAndCacheFiles()
* Remove FilePromptMode configuration and related complexity
- Update configuration
* Add Router model support (LLM_ROUTER_MODEL)
* Add Gitea configuration (BaseURL, Token, Owner, Repo)
* WebSearch and additional tool infrastructure
Tests: All 22 test packages passing, 8/8 webui tests including 3 new stream tests
2026-03-11 17:58:19 +08:00
|
|
|
|
|
|
|
|
|
|
你的改造要求:
|
|
|
|
|
|
1) 保留现有 UI 风格和组件结构,不做无关重构
|
|
|
|
|
|
2) 新增流式读取逻辑,支持中途取消 (AbortController)
|
|
|
|
|
|
3) 将事件按 step 渲染到消息区
|
|
|
|
|
|
4) 兼容旧会话字段命名 (session_id / sessionId, user_id / userId)
|
|
|
|
|
|
5) 增加错误态与重试按钮
|
|
|
|
|
|
6) 不破坏原有上传、历史消息和输入框行为
|
|
|
|
|
|
7) 输出改动文件列表 + 每个文件的关键变更说明
|
|
|
|
|
|
|
|
|
|
|
|
请直接给出可运行代码补丁。
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 调试清单
|
|
|
|
|
|
|
|
|
|
|
|
- 检查响应头是否为 `text/event-stream`
|
|
|
|
|
|
- 检查每条事件是否以 `data:` 开头并以空行结尾
|
|
|
|
|
|
- 确认 `final` 和 `error` 都能正确结束当前轮次
|
|
|
|
|
|
- 验证弱网下不会丢失已收到的事件
|
|
|
|
|
|
- 验证用户快速连续提问时,旧流可被取消
|