Skip to content

feat(ui): fold reasoning into the trow block and refine turn presentation#948

Merged
Astro-Han merged 6 commits into
devfrom
claude/conversation-flow-icons
May 27, 2026
Merged

feat(ui): fold reasoning into the trow block and refine turn presentation#948
Astro-Han merged 6 commits into
devfrom
claude/conversation-flow-icons

Conversation

@Astro-Han

@Astro-Han Astro-Han commented May 27, 2026

Copy link
Copy Markdown
Owner

Summary

Reworks how an assistant turn is presented in the conversation flow, in six atomic commits (commits 5–6 added in response to code review):

  1. Icons — adds thinking, skill, and read-file icons and remaps the tool-family icon table so each trow-block leading icon matches its tool. The thinking glyph is resized to fill the same icon box as its neighbours.
  2. Reasoning folds into the trow-block — reasoning now collapses into the same summary row as tool calls (reusing BasicTool) instead of rendering its own standalone thinking collapsible. A folded reasoning row no longer paints a duplicate icon, and the dead thinking-heading derivation (heading/clean/reasoningHeading/TextReveal) is removed.
  3. Interrupted-turn layout fix — an interrupted turn no longer draws a duplicate "interrupted" divider at the top, and its footer toolbar stays left-aligned like every other turn (the "interrupted" notice still shows in the footer meta line).
  4. Remove the now-dead reasoning-summaries setting — once reasoning always renders as a collapsible row, the General settings "show reasoning summaries" toggle became a no-op (renderable() ignores the flag). The toggle, its i18n copy, the persisted showReasoningSummaries field plus accessor, and the whole prop chain (message-timeline → SessionTurn → AssistantParts / AssistantMessageDisplay → renderable()) are removed.
  5. Render reasoning in AssistantMessageDisplay (review P2)groupParts() folds reasoning into the trow group, but this second turn renderer's trow branch kept only tool parts and never passed renderReasoning, so a reasoning-only or reasoning+tool message silently dropped its reasoning on that path. It now mirrors AssistantParts: the trow filter accepts reasoning and renders it via renderReasoning. New grouping.test.ts cases pin the shared folding (reasoning folds into a trow, groups with adjacent tools, empty reasoning filtered).
  6. Single tool-icon source (review P3) — tool icons were defined in three places (toolFamilyIcon, toolInfoForInput, and hard-coded strings in each tool component) and had already drifted for read/edit/write/apply_patch/skill. A new toolIcon() in tool-info.ts is the single source of truth; toolFamilyIcon delegates to it, toolInfoForInput returns it, and all 16 tool components pass toolIcon("…") to BasicTool. Icon values are unchanged, so rendering is identical; a reducer test pins the collapsed (trow) and expanded (tool-info) icons in lock-step so they cannot diverge again.

Why

Reasoning used to render as its own collapsible, which showed two stacked icons in the collapse bar when folded and duplicated the tool-call fold pattern with a parallel component. Folding reasoning into the existing trow-block removes the duplicate icon and the second code path. Separately, an interrupted turn drew a redundant top divider and right-shifted its footer toolbar, breaking alignment with normal turns. Finally, the fold made the "show reasoning summaries" setting meaningless — reasoning is always a collapsible row now — so the dead setting and its prop chain are cleaned up rather than left as confusing dead UI. Code review then surfaced two follow-ups, fixed in commits 5–6: a second turn renderer (AssistantMessageDisplay) was never updated when reasoning began folding into the trow, dropping reasoning on that path; and the tool icon was defined in three drifting places, so it is consolidated into one toolIcon() source.

Related Issue

None — scope and rationale are stated in Summary. Confirmed distinct from #943, which concerns a reasoning-attached retry notice, not the fold/layout presentation.

Human Review Status

Pending

Review Focus

  • reduceTrowBlock / toolFamilyIcon in session-turn-trow-block.tsx: reasoning is excluded from toolCount, and a reasoning-only block falls back to the thinking leading icon.
  • reasoning.tsx now renders through BasicTool — confirm a folded reasoning row shows exactly one icon.
  • session-turn.tsx interrupted-divider removal: confirm the footer meta still surfaces the "interrupted" notice after dropping the top divider and data-interrupted flag.
  • The removed showReasoningSummaries chain: confirm renderable() already ignored the flag (so reasoning renders unconditionally) and that nothing else read it before deletion.
  • AssistantMessageDisplay trow branch (commit 5): confirm it now accepts reasoning and passes renderReasoning, matching AssistantParts, so the second renderer no longer drops reasoning.
  • toolIcon() in tool-info.ts (commit 6): confirm it is the only place an icon name is chosen per tool, that toolFamilyIcon / toolInfoForInput / all tool components route through it, and that the lock-step reducer test would catch any future divergence.

Risk Notes

Presentation-only changes; no data, persistence schema, or API surface touched. The removed setting (showReasoningSummaries) was already a no-op after commit 2 — any value still in a user's persisted store is simply ignored on load (the withFallback accessor is gone), so no migration is needed. Commit 6 is a pure refactor: every tool's icon value is unchanged (the 16 components and toolFamilyIcon now resolve the same icon through toolIcon()), so rendering is identical and snapshots need no regeneration.

Skipped conditional checklist item:

  • Platform (macOS/Windows) — left unticked: no platform, packaging, updater, signing, path, shell, or permission surface was touched.

How To Verify

packages/ui typecheck (tsgo --noEmit): ok, no errors
packages/app typecheck (tsgo -b): ok, no errors (exit 0)
ui unit suite (bun test, 56 files): 707 pass / 0 fail
focused: trow-block reducer + grouping + typography-semantics = pass (toolFamilyIcon↔tool-info icon lock-step, reasoning folds into trow + groups with tools + empty filtered, reasoning-body line-height, renderable)
tool-icon: 16 tool components + toolFamilyIcon + toolInfoForInput all route through toolIcon() (grep: no hard-coded icon= in tools/)
no residual references to showReasoningSummaries / reasoningSummaries in app+ui source (grep clean)
snap session-trow (playwright): 1 passed — reasoning-only (1 trow-summary-icon), reasoning-with-tools, expanded reasoning body (non-mono); rendering unchanged by the setting removal

Screenshots or Recordings

Visual states are covered by the session-trow snapshot grid, regenerated in this change at docs/design/preview/screenshots/session-trow.png (via bun run snap session-trow), including the reasoning-only and reasoning-with-tools rows in collapsed and expanded form. The snapshot is a repo artifact and is not inlined here because the body cannot embed local files. The removed General setting is a one-row deletion in Settings → General with no dedicated snapshot.

Checklist

How to use this checklist:

  • Tick a box by replacing [ ] with [x]. Do not edit, add, or remove items.
  • The bot-applied label items can only be honestly ticked AFTER the PR is opened and the labeler / priority-triage bots have run — return to the PR description and tick them then.
  • Most items are required. The few that are conditional are explicitly marked (conditional); for those, leave unticked if they truly do not apply and explain why in Risk Notes. All other items must be ticked before requesting human review.
  • Type label — this PR carries exactly one of bug, enhancement, task, documentation. Type labels are author-added; the labeler bot does NOT assign them. Add the label in the GitHub UI, then tick this.
  • Routing labels — this PR carries at least one of app, ui, platform, harness, ci. The labeler bot assigns these on PR open based on changed paths. Confirm the bot's choice (or override if wrong), then tick this.
  • Priority label — this PR carries exactly one of P0, P1, P2, P3. The priority-triage bot suggests one on PR open. Confirm or override, then tick this.
  • Human Review Status above is set to Pending, Approved by @<reviewer>, or Not required: <reason> (default is Pending; "not required" is restricted to bot-authored low-risk PRs).
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant. Leave unticked only if none of those surfaces was touched.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Astro-Han, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 24 minutes and 45 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 389ed6d2-7fe0-4463-b0d6-a19b4b8811ba

📥 Commits

Reviewing files that changed from the base of the PR and between e40b39e and 8067756.

📒 Files selected for processing (40)
  • packages/app/e2e/snap/fixtures/trow-snap-fixture-data.ts
  • packages/app/e2e/snap/fixtures/trow-snap-fixture.tsx
  • packages/app/e2e/snap/session-trow.snap.ts
  • packages/app/src/components/settings-general.tsx
  • packages/app/src/context/settings.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/pages/session/message-timeline.tsx
  • packages/ui/src/components/assistant-turn-footer.tsx
  • packages/ui/src/components/icon.tsx
  • packages/ui/src/components/message-part.css
  • packages/ui/src/components/message-part/assistant-message-display.tsx
  • packages/ui/src/components/message-part/assistant-parts.tsx
  • packages/ui/src/components/message-part/grouping.test.ts
  • packages/ui/src/components/message-part/grouping.ts
  • packages/ui/src/components/message-part/message-router.tsx
  • packages/ui/src/components/message-part/parts/reasoning.tsx
  • packages/ui/src/components/message-part/registry.ts
  • packages/ui/src/components/message-part/tools/agent.tsx
  • packages/ui/src/components/message-part/tools/apply-patch.tsx
  • packages/ui/src/components/message-part/tools/bash.tsx
  • packages/ui/src/components/message-part/tools/edit.tsx
  • packages/ui/src/components/message-part/tools/glob.tsx
  • packages/ui/src/components/message-part/tools/grep.tsx
  • packages/ui/src/components/message-part/tools/list.tsx
  • packages/ui/src/components/message-part/tools/question.tsx
  • packages/ui/src/components/message-part/tools/read.tsx
  • packages/ui/src/components/message-part/tools/skill.tsx
  • packages/ui/src/components/message-part/tools/todowrite.tsx
  • packages/ui/src/components/message-part/tools/webfetch.tsx
  • packages/ui/src/components/message-part/tools/websearch.tsx
  • packages/ui/src/components/message-part/tools/worktree.tsx
  • packages/ui/src/components/message-part/tools/write.tsx
  • packages/ui/src/components/session-turn-trow-block.reducer.test.ts
  • packages/ui/src/components/session-turn-trow-block.tsx
  • packages/ui/src/components/session-turn.css
  • packages/ui/src/components/session-turn.tsx
  • packages/ui/src/components/timeline-playground.stories.tsx
  • packages/ui/src/components/tool-info.ts
  • packages/ui/test/typography-semantics.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/conversation-flow-icons

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added app Application behavior and product flows ui Design system and user interface P2 Medium priority labels May 27, 2026

@github-actions github-actions 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.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request refactors the rendering of reasoning parts to reuse the collapsible BasicTool shell, allowing them to fold into trow blocks as peer rows. It updates the typography of the reasoning body to use a sans-serif font family and quieter text color, updates several tool icons (e.g., changing glasses to read-file and code-lines to edit), and removes unused code such as the TextReveal component and interrupted state handling. Corresponding tests and snapshot tests have been updated to reflect these changes. I have no feedback to provide as there are no review comments.

Add three dedicated icons (thinking, skill, read-file) traced to the
20×20 viewBox at a fill consistent with the existing set, and point the
tool families at them: read→read-file, edit/write/apply_patch→edit,
skill→skill (previously glasses / code-lines / brain). Update the
trow-block leading-icon map and its reducer assertions in lock-step.
@Astro-Han Astro-Han force-pushed the claude/conversation-flow-icons branch from 574a3d1 to e6bdd72 Compare May 27, 2026 07:50
@Astro-Han Astro-Han added the enhancement New feature or request label May 27, 2026
@Astro-Han Astro-Han changed the title feat(ui): fold reasoning into the tool-call trow block feat(ui): fold reasoning into the trow block and refine turn presentation May 27, 2026
@github-actions

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown

Perf delta summary

Comparator: pass

Profile / Scenario interaction median interaction worst long task max tbt frame gap p95 frame gap max jank count cls status
default / homepage-cold 24 -> 24 (0) 48 -> 32 (-16) 69 -> 70 (+1) 19 -> 20 (+1) 16.8 -> 16.8 (0) 116.8 -> 166.7 (+49.9) 3 -> 4 (+1) 0 -> 0 (0) pass
default / long-session-input-lag 48 -> 48 (0) 48 -> 64 (+16) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.7 (-0.1) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-streaming-long 40 -> 40 (0) 64 -> 56 (-8) 0 -> 0 (0) 0 -> 0 (0) 16.7 -> 33.3 (+16.6) 33.3 -> 33.3 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-call-expand 40 -> 24 (-16) 40 -> 24 (-16) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.8 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / tool-default-open-heavy-bash 16 -> 16 (0) 24 -> 24 (0) 65 -> 67 (+2) 15 -> 25 (+10) 50 -> 50 (0) 133.2 -> 116.7 (-16.5) 3 -> 3 (0) 0.004 -> 0.004 (0) pass
default / terminal-side-panel-open 48 -> 48 (0) 48 -> 48 (0) 0 -> 0 (0) 0 -> 0 (0) 33.3 -> 33.3 (0) 33.4 -> 33.4 (0) 0 -> 0 (0) 0 -> 0 (0) pass
default / session-scroll-reading 16 -> 16 (0) 16 -> 24 (+8) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.8 (0) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass
low-end / session-scroll-reading-long 0 -> 0 (0) 0 -> 0 (0) 53 -> 53 (0) 3 -> 3 (0) 33.3 -> 33.3 (0) 50 -> 83.4 (+33.4) 0 -> 1 (+1) 0 -> 0 (0) pass
low-end / session-timeline-recompute 32 -> 32 (0) 40 -> 48 (+8) 0 -> 0 (0) 0 -> 0 (0) 33.3 -> 33.3 (0) 33.4 -> 33.4 (0) 0 -> 0 (0) 1.075 -> 1.075 (0) pass
low-end / concurrent-shimmer-extreme 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 0 -> 0 (0) 16.8 -> 16.7 (-0.1) 16.8 -> 16.8 (0) 0 -> 0 (0) 0 -> 0 (0) pass

Astro-Han added 2 commits May 27, 2026 16:07
Reasoning parts now collapse into the same trow-block summary row as
tool calls instead of rendering their own standalone thinking
collapsible. The trow reducer treats reasoning as a trow part
(toolCount excludes it, leading icon falls back to `thinking`), and the
reasoning renderer reuses `BasicTool` so a folded reasoning row no
longer paints its own duplicate icon.

Drop the now-dead thinking-heading derivation (`heading`/`clean`,
`reasoningHeading`, the `TextReveal` summary) and its CSS rule.
An interrupted assistant turn drew a duplicate "interrupted" divider at
the top of the turn and forced its footer toolbar to the right edge.
Drop the turn-level `interrupted` divider branch and the
`data-interrupted` footer flag (plus its right-aligning CSS rule) so the
toolbar stays left-aligned like every other turn; the "interrupted"
notice still shows in the footer meta line.
@Astro-Han Astro-Han force-pushed the claude/conversation-flow-icons branch from e6bdd72 to a226328 Compare May 27, 2026 08:08
Astro-Han added 3 commits May 27, 2026 16:27
Folding reasoning into the trow-block made the "show reasoning
summaries" toggle a no-op: renderable() now always renders a reasoning
part as a collapsible row regardless of the flag.

Remove the whole dead chain — the General settings toggle and its i18n
copy, the persisted showReasoningSummaries field plus accessor, and the
prop threaded through message-timeline → SessionTurn → AssistantParts /
AssistantMessageDisplay → renderable().
groupParts() folds reasoning into the trow group, but AssistantMessageDisplay's
trow branch only kept tool parts and never passed renderReasoning — so a
reasoning-only or reasoning+tool message silently dropped its reasoning. Align it
with AssistantParts: accept reasoning in the trow filter and render it through
renderReasoning.

Pin the shared grouping behavior in grouping.test.ts: reasoning folds into a
trow, groups with adjacent tools in one trow, and empty reasoning is filtered.
Tool icons were defined in three places — toolFamilyIcon (trow leading icon),
toolInfoForInput (expanded tool header), and hard-coded strings in each tool
component — and had already drifted: read/edit/write/apply_patch/skill showed a
different icon in the trow leading row than in the expanded tool-info header.

Add toolIcon() in tool-info.ts as the single source of truth. toolFamilyIcon
delegates to it, toolInfoForInput returns it, and all 16 tool components pass
toolIcon("…") to BasicTool instead of hard-coding an icon name. Icon values are
unchanged, so rendering is identical. A reducer test pins toolFamilyIcon and the
tool-info icon in lock-step so the collapsed and expanded views cannot diverge
again.
@Astro-Han Astro-Han merged commit c75256e into dev May 27, 2026
29 checks passed
@Astro-Han Astro-Han deleted the claude/conversation-flow-icons branch May 27, 2026 09:29
Astro-Han added a commit that referenced this pull request May 27, 2026
Bump PawWork desktop release version to 2026.5.28.

Changes since v2026.5.27:
- feat(ui): fold reasoning into trow block (#948)
- feat: align outbound HTTP headers with canonical OpenCode desktop (#940)
- feat(app): collapse notification settings to single tri-state control (#938)
- fix(ui): track List header surface via --list-surface (#954)
- fix(ui): render tooltip shortcut hints as plain sans glyphs (#955)
- fix(watcher): isolate macOS workspace roots
- fix(session): terminalize stale question blockers
- fix(session): unify transport error classification for stream disconnect recovery (#941)
- test: add route inventory guardrails
- ci: repair electron desktop build + install
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Application behavior and product flows enhancement New feature or request P2 Medium priority ui Design system and user interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant