Skip to content

feat(app): collapsible reasoning cards - #46344

Open
4ebuRushka wants to merge 3 commits into
anomalyco:devfrom
4ebuRushka:feat/collapsible-reasoning
Open

4ebuRushka wants to merge 3 commits into
anomalyco:devfrom
4ebuRushka:feat/collapsible-reasoning

Conversation

@4ebuRushka

@4ebuRushka 4ebuRushka commented Aug 31, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #8789, Closes #14340, Closes #37115, Closes #21548. Partially addresses #28322. Refs #7866, #33906, #21515.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Render reasoning parts as collapsible cards instead of flat markdown. Visibility follows the existing "show reasoning summaries" setting: ON = cards, OFF = hidden as before (rows.ts/groupParts untouched).

  • Each reasoning part renders as a Collapsible card in BasicTool style: brain icon, Thinking title (ui.sessionTurn.status.thinking), 80-char live subtitle from the first line, max-height:320px scrollable body with copy button
  • Auto-open the active block while streaming (streaming && isLastPart); auto-collapse on completion and when the next block appears — the previous block in a reasoning→reasoning chain collapses immediately; shimmer and PacedMarkdown streaming gated by isLastPart
  • Manual choice wins: closing a card mid-stream keeps it closed, opening a completed card sticks; the choice is written to the existing parent toolOpen journal, so it survives list remounts (scrolling)
  • isLastPart via data.store.part[message.id].at(-1)?.id === part.id
  • Auto-scroll inside card: scrollRef/innerRef, autoFollow (pause >40px from bottom, resume at bottom), ResizeObserver + MutationObserver + continuous RAF tick while open && streaming && autoFollow
  • Long unbroken lines wrap (overflow-wrap: anywhere); ``` code blocks keep their own horizontal scroll without stretching the card

Open state comes from the existing parent toolOpen/onToolOpenChange journal (same mechanism as tool parts). No new settings, no new i18n keys, no migrations, no leftover stored preferences to clean up.

How did you verify your code works?

  • tsgo --noEmit -p packages/session-ui clean
  • bun test --cwd packages/session-ui src/components/message-part.test.ts 6 pass
  • i18n/parity: only the pre-existing dv failures (identical on clean dev)
  • oxlint on changed files: 0 errors
  • Rebased onto upstream/dev@c0f09afe; merge simulation shows 0 conflicts
  • Manual from test DB (previous revision; re-verify after rework): matrix showReasoningSummaries ON/OFF OK, streaming auto-opens, completed auto-collapses, reasoning→reasoning and reasoning→tool chains collapse correctly, shimmer only on active, inner scroll follows without wheel and pauses when user scrolls up
  • electron-vite dev HMR works, no TUI changes (session-ui not used by tui)

Screenshots / recordings

Compact collapsible cards interleaved with tool calls, streaming card auto-opens and auto-scrolls, history stays compact. Before: flat markdown prologue filling history.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. needs:title labels Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title feat(desktop,session-ui): collapsible reasoning cards doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@4ebuRushka 4ebuRushka changed the title feat(desktop,session-ui): collapsible reasoning cards feat(app): collapsible reasoning cards Aug 31, 2026
@github-actions github-actions Bot removed needs:title needs:compliance This means the issue will auto-close after 2 hours. labels Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Add collapsibleReasoning setting (default true) with persisted store,
i18n (62 locales) and UI toggles in both settings-general variants.
Render reasoning parts as collapsible cards in the style of tool calls
(brain icon, 80-char subtitle, TextShimmer only on active block,
max-height:320px scrollable body, copy button). Each reasoning part is
its own card with open/userInteracted state.

- Auto-collapse previous blocks in a chain: isLastPart via
  data.store.part[message.id].at(-1) — previous collapses immediately
  when next reasoning part appears, not at end of chain. Shimmer and
  PacedMarkdown streaming only on active (streaming && isLastPart).
- Auto-scroll inside card: scrollRef/innerRef signals, autoFollow flag
  (pause >40px from bottom, resume at bottom), ResizeObserver +
  MutationObserver + continuous RAF tick while open && streaming &&
  autoFollow — keeps tail visible during PacedMarkdown pacing and
  large gaps.
- Wire collapsibleReasoning through MessagePartProps -> Part ->
  message-timeline (settings.general.collapsibleReasoning()).

Complements anomalyco#45247 (/thinking toggle). Closes anomalyco#8789, anomalyco#14340, anomalyco#37115, anomalyco#21548,
partially anomalyco#28322. Refs anomalyco#7866, anomalyco#33906.

Co-authored-by: 4ebuRushka
Limit reasoning card to visible width and vertical scroll only.
Outer container overflow-x hidden, overflow-y auto with max-width 100%.
Reasoning markdown text uses overflow-wrap anywhere and word-break break-word with white-space normal so long lines wrap.
Keep pre and pre code as white-space pre with overflow-x auto so code blocks retain internal horizontal scroll without stretching the card.
… opt-in toggle

Variant B rework: remove the collapsibleReasoning setting entirely.

Reasoning parts always render as collapsible cards while

showReasoningSummaries is on, and stay hidden as before while it is off

(rows.ts/groupParts untouched).
@4ebuRushka
4ebuRushka force-pushed the feat/collapsible-reasoning branch from d71a9ab to cd36715 Compare September 17, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant