-
v1.0.3 Stable
released this
2025-10-15 17:32:46 +08:00 | 8 commits to main since this release发布时间: 2025-10-15
重大功能:停止生成 & UI 优化
本版本实现了完整的停止生成功能,参考 Cherry Studio 的 PAUSED 状态设计,提供更好的用户体验。
核心功能
智能停止生成
- 点击停止按钮立即中断 AI 回复(响应时间 < 100ms)
- 保留已生成的内容,标记为"已停止"状态
- 区分用户主动停止和系统错误
- 停止后可立即继续对话
UI 体验优化
- 按钮文字从"确认"改为"发送"
- 停止后显示黄色"已停止"标签(而非红色"发送失败")
- 停止的消息可以复制、重新生成、删除
- 实时状态反馈(发送中 → 已停止 → 可操作)
状态管理增强
- 新增
paused消息状态 - 新增
paused流式事件类型 - 完整的 AbortController 信号传递链
- 流读取循环实时检查中止信号
技术实现
按钮事件修复
- 修复点击事件绑定问题(从三元表达式改为函数调用)
- 运行时动态判断状态,而非编译时
// Before: @click="store.state.isSending ? handleStopGeneration : handleSendMessage" // After: @click="handleButtonClick" const handleButtonClick = () => { if (store.state.isSending) { handleStopGeneration() } else { handleSendMessage() } }中止信号传递链
UI (点击停止) ↓ handleStopGeneration() ↓ store.stopGeneration() ↓ abortController.abort() ↓ chatService.sendMessageStream(signal) ↓ modelServiceManager.makeChatRequestStream(signal) ↓ while循环检查 signal.aborted ↓ reader.cancel() + 抛出 AbortError ↓ 状态设置为 'paused' ↓ UI 更新显示"已停止"流读取中止检查
while (true) { // 关键:每次读取前检查中止信号 if (signal?.aborted) { console.log('检测到中止信号,停止读取流') reader.cancel() throw new DOMException('用户中止操作', 'AbortError') } const { done, value } = await reader.read() if (done) break // 处理数据... }错误处理优化
catch (error) { const isAborted = error instanceof Error && error.name === 'AbortError' if (isAborted) { // 用户主动停止 - 标记为 paused,保留内容 assistantMessage.status = 'paused' assistantMessage.error = undefined onChunk({ type: 'paused', messageId: assistantMessage.id }) // 关键:更新消息列表,触发 UI 刷新 state.messages = [...chatService.getMessages(currentTopicId)] } else { // 真实错误 - 标记为 error assistantMessage.status = 'error' assistantMessage.error = error.message } }Bug 修复
Emoji 测试
为验证发布脚本对 emoji 的处理(例如某些 emoji 属于 4 字节 unicode,可能触发服务器端 collation 问题),在此插入若干 emoji 供测试:
- 表情类:
- 物品/动作:
- 动物/自然:
- 标志/符号:️ ✅ ❌
示例行(包含中文和 emoji):
测试:本行包含中文与 emoji,目的是验证脚本对 emoji 的过滤与回退逻辑。示例 emoji: ️
- 修复按钮点击无响应问题(事件绑定错误)
- 修复停止后仍显示"发送中..."状态
- 修复停止后消息列表不更新
- 修复 AbortError 被错误标记为失败
- 修复按钮文字显示"确认"而非"发送"
修改的文件
类型定义
/web/src/types/chat.ts- MessageStatus 添加
'paused'类型 - StreamEvent 添加
'paused'事件类型
- MessageStatus 添加
UI 组件
/web/src/components/Chat/ChatLayout.vue- 修复按钮点击事件绑定
- 按钮文字改为"发送"
- 添加"已停止"状态标签显示
- paused 状态消息显示操作按钮
服务层
-
/web/src/services/chatService.ts- 区分 AbortError 和其他错误
- 设置 paused 状态和事件
-
/web/src/services/modelServiceManager.ts- 流读取循环中检查 signal.aborted
- 调用 reader.cancel() 中止读取
- 正确处理 AbortError
状态管理
/web/src/stores/chatStore.ts- 在 catch 块中更新消息列表
- 确保 UI 显示最新状态
使用示例
1. 用户发送:"请详细介绍 Vue 3 的新特性" 2. AI 开始回复,显示"发送中..." 3. 用户点击"停止"按钮 4. 立即响应: - 输出停止 - 标签变为"已停止"(黄色) - 显示已生成的内容 - 显示操作按钮 5. 用户可以: - 复制已生成的内容 - 重新生成完整回复 - 删除该消息 - 继续发送新消息设计亮点
- 参考 Cherry Studio - 借鉴成熟产品的设计理念
- 立即响应 - 停止操作 < 100ms 响应
- 内容保留 - 部分生成的内容依然有价值
- 状态区分 - paused vs error,语义更清晰
- 完整操作 - 停止的消息仍可进行各种操作
- 信号传递 - 完整的中止信号链,确保可靠性
用户体验对比
修复前
- 点击停止无反应
- 继续显示"发送中..."
- 显示 loading 动画
- 按钮文字为"确认"
修复后
- 点击立即停止
- 显示"已停止"(黄色)
- 隐藏 loading 动画
- 按钮文字为"发送"
- 可以操作停止的消息
- 立即可继续对话
相关文档
STOP_GENERATION_SUMMARY.md- 修复总结STOP_GENERATION_FIX.md- 详细技术文档STOP_GENERATION_PATCH.md- 补充修复说明STOP_GENERATION_TEST.md- 测试指南STOP_GENERATION_VERIFY.md- 快速验证清单
升级指南
# 拉取最新代码 git pull origin main # 安装依赖 cd web && npm install # 启动开发服务器 npm run dev # 测试停止功能 # 1. 发送消息 # 2. 在 AI 回复时点击"停止" # 3. 验证显示"已停止"标签 # 4. 验证可以继续对话验收标准
- 按钮点击有明显反应
- 流输出在 100ms 内停止
- 显示"已停止"而非"失败"
- 保留已生成内容
- 停止后可立即继续对话
- 可对停止的消息进行操作
- 无意外错误日志
下一步计划
- 停止后自动保存草稿
- 停止历史记录统计
- 批量停止多个会话
- 停止原因记录(用户主动/超时/错误)
- 性能监控和优化
v1.0.3 - 完美的停止体验,让对话更可控!
Downloads