feat(dashboard): 对话栏架构升级 —— streamdown + 七态状态机 + 组件拆分#127
Merged
Conversation
- 新增 ChatStreamdown.tsx:封装 Streamdown,保留印章终端主题样式 - 新增 chat-streamdown-security.ts:禁用远程图片加载 - ChatThread.tsx:流式 assistant 消息用 ChatStreamdown 逐 token 渲染, 历史消息仍用 ChatMarkdown - 安装 streamdown ^2.5.0 + @streamdown/cjk + @streamdown/code Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 新增 tool-states.ts:定义七种 ToolState,含图标/颜色/展开态/pulse 动画 - ToolChip 从 done 布尔值改为 state 驱动,中间态有 pulse/spinner, 完成态绿色可展开,错误态红色高亮,审批态有 clock 图标 - 基于 AG-UI 消息自动推断工具状态(tool call → Running, tool result → Completed/Error) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
将 ChatThread.tsx 拆分为 7 个独立组件: - ChatErrorBanner.tsx — 错误横幅 - ChatHistoryPanel.tsx — 历史会话下拉面板 - ChatToolChip.tsx — 工具调用 chip(七态状态机) - ChatMessage.tsx — 单条消息渲染(user/assistant/tool) - ChatMessageList.tsx — 消息列表 + 自动滚动 + 空态/思考中 - ChatInput.tsx — 输入框 + 发送/停止 + 页面上下文胶囊 - ChatThread.tsx — 精简为 373 行的纯容器/编排层 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying inalpha-web with
|
| Latest commit: |
bd5975b
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e0e284ef.inalpha-web.pages.dev |
| Branch Preview URL: | https://feat-chat-streamdown-refacto.inalpha-web.pages.dev |
Contributor
|
commit: bd5975b
本轮复查基于上一条评论(commit d6eb69f)剩余的 1 项 medium 逐条核实: 必修(critical / major)无。 可选优化(medium)无遗留。核实结果:
其余部分(组件拆分、七态状态机接线、i18n 文案、fetch abort patch、 LGTM。 |
回应 PR #127 auto-review 的两个必修: **[critical] abort signal 形同虚设** - fetch 补丁里 stoppingRef 为真时 ctrl.abort() 后却用原始 init 发请求, signal 没挂上 → "点暂停后回复继续输出" bug 复发 - 修复:ctrl.abort() 后用 { ...init, signal: ctrl.signal } 发请求, 浏览器立即以 AbortError 拒绝,真正掐断续段 **[major] 打开对话栏不再自动聚焦** - Phase 3 拆分把 textarea 移进 ChatInput,但聚焦 effect 留在 ChatThread 用已失效的 inputRef → 每次打开要手动点一下才能打字 - 修复:ChatInput 接受 open prop,按 open 变化驱动聚焦; ChatThread 删掉死的 inputRef Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
回应 PR #127 auto-review 的 medium:七态里只有 3 个(Running/Completed/Error) 有生产者,另外 4 个(Pending/Denied/审批态)是为 mastra 未来上报中间状态 预留的定义。加注释明确区分,避免后来者误以为审批态已可用而踩空。 样式表保留(定义先行合理),等 mastra 上报生命周期细分时扩 inferToolState 即可点亮。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ChatHistoryPanel: t("historyLoading")(不存在的 key)→ t("loadingHistory")
- 工具七态文案从 TOOL_STATE_MAP 硬编码英文改走 next-intl:
新增 TOOL_STATE_I18N_KEY 映射,ChatMessageList 经 t() 解析后
注入 ChatMessage,中文 locale 不再显示裸 "Running"/"Completed"
- messages/{zh,en}.json 补 toolPending/toolError/toolDenied/
toolAwaitingApproval/toolResponded(toolRunning/toolDone 复用)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
已完成 / 历史消息走 ChatMarkdown(react-markdown),此前无 img 覆盖, markdown 里的 ![]() 会渲染成真实 <img src> 发起请求;注入的图片 beacon URL 会在重新渲染 / 重开历史会话时把 URL 参数渗出给第三方。 补 img 组件渲染 alt 占位而非 <img>,与 ChatStreamdown 的空白名单对齐。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
此前流式态走 ChatStreamdown(带 @streamdown/code 高亮 + cjk 排版),isStreaming 一翻转就切回 ChatMarkdown(纯等宽无高亮):agent 生成代码回复刚结束高亮即消失、 肉眼可见"闪一下",历史会话永远无高亮——Phase 1 引入高亮的卖点在实际停留时间 里基本不可见。 改为完成态 / 历史消息也走 ChatStreamdown(mode=static),与流式态共用同一条 渲染管线(高亮 + cjk + 空白名单图片拦截一致)。ChatMarkdown 随之成为死代码, 删除;react-markdown 已无任何消费方,从 package.json 移除(净减依赖)。 bundle 核实:streamdown 对 mermaid/shiki 走 import() 动态导入(dist chunk 实测), 二者按需 split 进异步 chunk,不进首屏 bundle;ChatStreamdown 顶层静态 import 只带入 streamdown 核心。上一轮 medium「bundle 体积」据此排除。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mirror29
added a commit
that referenced
this pull request
Jul 2, 2026
回应 PR #127 auto-review 的两个必修: **[critical] abort signal 形同虚设** - fetch 补丁里 stoppingRef 为真时 ctrl.abort() 后却用原始 init 发请求, signal 没挂上 → "点暂停后回复继续输出" bug 复发 - 修复:ctrl.abort() 后用 { ...init, signal: ctrl.signal } 发请求, 浏览器立即以 AbortError 拒绝,真正掐断续段 **[major] 打开对话栏不再自动聚焦** - Phase 3 拆分把 textarea 移进 ChatInput,但聚焦 effect 留在 ChatThread 用已失效的 inputRef → 每次打开要手动点一下才能打字 - 修复:ChatInput 接受 open prop,按 open 变化驱动聚焦; ChatThread 删掉死的 inputRef Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mirror29
added a commit
that referenced
this pull request
Jul 2, 2026
回应 PR #127 auto-review 的 medium:七态里只有 3 个(Running/Completed/Error) 有生产者,另外 4 个(Pending/Denied/审批态)是为 mastra 未来上报中间状态 预留的定义。加注释明确区分,避免后来者误以为审批态已可用而踩空。 样式表保留(定义先行合理),等 mastra 上报生命周期细分时扩 inferToolState 即可点亮。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
基于 Omnigent 调研,提取可复用的流式架构改进,分三个 Phase 渐进式升级 Dashboard 对话栏。
改动
Phase 1:streamdown 替换 react-markdown(
dae02d5)ChatStreamdown.tsx:封装 Streamdown,逐 token 渐进渲染 Markdownchat-streamdown-security.ts:禁用远程图片加载streamdown ^2.5.0+@streamdown/cjk+@streamdown/codePhase 2:工具调用七态状态机(
8a5d796)tool-states.ts:定义 Pending/Running/Completed/Error/Denied/Awaiting Approval/Responded 七种 ToolStatedone布尔值改为 state 驱动Phase 3:ChatThread 组件拆分(
0d4c14c)ChatErrorBanner.tsx— 错误横幅ChatHistoryPanel.tsx— 历史会话下拉面板ChatToolChip.tsx— 工具调用 chipChatMessage.tsx— 单条消息渲染ChatMessageList.tsx— 消息列表 + 自动滚动ChatInput.tsx— 输入框 + 发送/停止 + 页面上下文胶囊不做的事
/api/copilotkitAG-UI 桥保持不变)验证
pnpm typecheck(orchestration + dashboard)零错误🤖 Generated with Claude Code