Skip to content

feat(web): chat 过程展示两层化 —— Adaptive Title 分层 + composer 常驻运行条 - #1145

Merged
chen-ran merged 3 commits into
mainfrom
feat/chat-adaptive-title
Sep 4, 2026
Merged

feat(web): chat 过程展示两层化 —— Adaptive Title 分层 + composer 常驻运行条#1145
chen-ran merged 3 commits into
mainfrom
feat/chat-adaptive-title

Conversation

@qqqqqf-q

@qqqqqf-q qqqqqf-q commented Sep 3, 2026

Copy link
Copy Markdown
Member

背景

chat view 运行中的过程展示有两个问题(对照演讲稿第 17 页 demo / Cursor / Claude Code 的设计语言):

  1. 组头没有分层:运行中只滚动最新一次调用("Reading x.ts"),段级聚合要等沉淀后才出现。
  2. 运行中的组头把 shimmer 打在整行上,没有「动词=阶段、计数=进度」的对比层级。

改动(对齐演讲 demo 的设计)

两层 Adaptive Title(tool-call-group.vue)

  • 运行中:组头 = muted 段级现在时动词(Exploring/探索中,只有动词带 shimmer)+ 深色裸计数 details(3 files, 1 search, 2 commands,随调用增长);其下 now 行滚动当前那一次调用(正文同大同色,translateY roll 动画;工具输入未流完时显示 pending 文案,与组内行措辞一致)。
  • 沉淀后:动词转过去时(Explored/已探索),计数定格,追加段级 diff 汇总(+284 −96,从每行自己的 display 数学累加)。
  • 展开组体时 now 行隐藏:capsule 内最后一行已携带同一信号,不重复渲染。
  • 单工具段保持原有具体 label(Run echo done),不叠段动词——否则 "Running Run ls" 式结巴,且与 now 行重复。
  • 计数按新的 fragment 种类拆分(files / searches 分开),不再用 browse 桶混算(避免"6 次搜索读成 6 个文件")。
  • GUI / 纯思考段路径不变;幽灵 Thinking:组 header 被单个 tool 的 running 状态永久劫持 + "Thought for 1s" 时长误导 #1106 ghost-"Thinking…" 门控语义保留,原测试用例全部保留(其中一条按新两层契约适配)。

i18n:三语同改。chat.process.phase.*(9 段动词 × ing/done)、chat.process.frag.*(裸计数)+ fragmentSeparator

未做(原计划在演进的):composer 常驻 runtime 条(Working+耗时+步数)——demo 里没有这个元素,第一版做了已被撤掉;token 用量需 stream 携带,留作后端后续项。

验证状态(如实)

  • ✅ 单测 10/10(两层结构、时态、diff 汇总、pending 文案、幽灵 Thinking:组 header 被单个 tool 的 running 状态永久劫持 + "Thought for 1s" 时长误导 #1106 回归、展开让位);src/pages/home + src/store/chat 区域 431 全过;全仓 pnpm lint 干净。
  • ✅ typecheck:CI report-only(既有 ~470 条 backlog),本改动文件零新增错误。
  • 实机渲染已自验(ego-browser 驱动本地 dev,admin 登录后发多工具任务):沉淀态 "Explored 2 files"、单工具 "Run echo done"、now 行滚动与 Thinking 切换、checkpoint 文本断组——均截图确认。运行中多工具组的「动词+计数增长」单帧受模型速度所限没抓到截图(逻辑由单测钉住)。
  • ⚠️ 视觉 happy path 仍建议人工 QA 过一遍(见下)。

Test plan

  • 发一个多步骤任务:组头动词(现在时)+ 计数增长,now 行滚动当前调用。
  • 展开运行中的组:now 行消失,组内行正常。
  • 结束:动词过去时 + 最终计数 + diff 汇总。
  • 单工具段:不出现段动词,保持具体 label。
  • 暗色 / zh / 窄面板各看一遍。

组头(运行中)从「只滚动最新一次调用」改为两层:上层=段级现在时动词
(Exploring/探索中,shimmer)+ 实时 bucket 计数,下层=now 行滚动当前调用
(复用 live-peek-line;展开组体时隐藏,避免一个状态两处渲染)。沉淀后组头
恢复最终聚合并追加段级 diff 汇总(+N/-N)。

composer dock 新增 runtime line:streaming 且未阻塞于审批/ask_user 时显示
工作中 + 已耗时 + 步数;跟随 composer 不随消息流滚走,回答「还活着吗」。
token 用量流里还没有,耗时+步数是诚实的客户端代理信号。

i18n 三语同改:新增 chat.process.phase.* 与 chat.runtime.working。
@qqqqqf-q
qqqqqf-q requested a review from a team as a code owner September 3, 2026 11:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e841e25673

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +80 to +82
const start = props.startedAt ?? selfStart
if (!start) return ''
const seconds = Math.max(0, Math.floor((now.value - start) / 1000))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use one clock for elapsed time

When the browser clock differs from the server clock, this produces a misleading duration because startedAt originates from the server's run.started_at, while now is taken from the client's Date.now(). A client clock that is five minutes ahead immediately displays 5m, while one that is behind remains at 0s; measure from a client-side receipt time or compensate for the server/client offset.

Useful? React with 👍 / 👎.

Comment on lines +14 to +16
<div
class="flex items-center gap-1.5 px-1.5 pb-1.5 text-xs text-muted-foreground select-none"
role="status"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the ticking clock outside the live status region

For screen-reader users, role="status" creates a polite live region, and the elapsed label inside it changes every second. That can cause the runtime status to be announced repeatedly for the entire turn; keep the stable working announcement in the status region while hiding the visual clock from assistive technology or placing it outside the live region.

Useful? React with 👍 / 👎.

qqqqqf-q and others added 2 commits September 3, 2026 10:11
第一轮实现没有照着第 17 页 demo 做,是自我想象的改写,已纠正:

- 撤掉 composer runtime 条(自创元素,demo 里没有;且英文有 1 steps 单复数
  bug)。composer-dock / chat-pane 恢复原状。
- 组头改两色分层:muted 段动词(ing/done 时态,只有它带 shimmer)+ 深色
  裸计数 details(12 files, 4 searches, 3 commands)。计数从 bucket 动词短语
  改为按 fragment 种类的裸名词,files/searches 拆分(browse 桶混算会导致
  「8 次搜索读成 8 个文件」)。
- 单工具段保持原有具体 label,不叠段动词(避免 Running Run ls 式结巴)。
- now 行从 live-peek-line 换成 demo 的滚动行:同正文大小、cop-title 色、
  translateY roll 动画;工具输入未流完时显示 pending 文案(与组内行一致)。
- i18n:phase 重构为 ing/done 对,新增 frag.* 与 fragmentSeparator,删 runtime。
@chen-ran
chen-ran merged commit 3ddc2f1 into main Sep 4, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants