Skip to content

chat: an opened thinking row prints its first line twice #1636

Closed

Description

@HugoXK

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.

Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: f1b0c1c8af10498cb45709de2bcf4589
Branch: dev/1636-chat-an-opened-thinking-row-prints-its-f
Base: 331dd62
At: 2026-10-29T05:01:30Z

Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.

A thinking row that is opened prints the same sentence twice: once as the grey preview inside the <summary>, once as the body text directly below it.

Written-by: FlyBot Lead

Reproduction (main 331dd620, the tree #1631 merged as)

core/src/client/cells.js (ThinkingRow, ~:133-146) puts the first line inside the summary:

h('details', { className: 'bt-think' },
  h('summary', null, h('span', { className: 'bt-think-caret', 'aria-hidden': true }, '›'), t('Thought it through'),
    peek ? h('span', { className: 'bt-think-peek' }, peek) : null),
  h('div', { className: 'bt-think-text' }, text))

details carries no open state and no onToggle, so .bt-think-peek is in the DOM in every state. core/src/client/styles.js (CONVERSATION_CSS, ~:890) only styles .bt-think[open] .bt-think-caret, and has no rule for the peek in the open state.

Reproduced against the real cells.js with an esbuild harness, reasoning text Looking at the store first\nThen the second line:

  • details props: ["className","children"]
  • summary text: ›Thought it throughLooking at the store first
  • body (div.bt-think-text) starts with the same Looking at the store first

So an opened row shows a truncated grey copy of its own first line above the full text.

Expected

Closed: unchanged — label plus the one-line peek, which is what #1624 asked for.
Opened: the summary shows the label only (no duplicated sentence), the body shows the reasoning once.

Fix (scope)

One CSS rule in CONVERSATION_CSS, e.g. .bt-think[open] .bt-think-peek{display:none} — or, if you prefer, conditional rendering on toggle; either way the closed state must render byte-identically to today.

Out of scope: turn-reasoning.js, the empty guard, "live draws no row", the peek's wording/charset (that is a separate improvement: fence lines, grapheme-safe truncation, ellipsis).

Acceptance

  • the open state's summary no longer contains the body's first line (one new test that sets/toggles the open state);
  • the existing core/test/thinking-row.test.js cases (closed state, 5 cases from #1631) still pass unchanged;
  • TZ=UTC ARCH_DOCS_BASE=<live main> npm run verify exits 0, ds-bot-patches check clean;
  • regenerate generated artifacts only if the source change requires it and say so in the PR.

Activity

  1. HugoXK commented on Oct 29, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: f1b0c1c8af10498cb45709de2bcf4589
    Reason: Released: merged as #1637 (merge 4f8ef0d)
    At: 2026-10-29T06:42:28Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions