fix(ui): retire duplicated host-accepted transient and keep tail rows on the reading measure - #5203
Open
UncertaintyDeterminesYou4ndMe wants to merge 2 commits into
Conversation
me2seeks
approved these changes
Sep 11, 2026
… on the reading measure - A durable local copy whose message id the transcript already renders as a Turn user row (primary prompt or admitted user timeline item) no longer renders a second time below the running status; the inline slot dropped it but the tail slot drew everything 'not inline', so the same text showed twice while a Turn was live - Tail and empty-session transient rows render inside a .maka-turn wrapper: the reading measure (max-width + centering) lives on .maka-turn, so rows placed directly under ChatMessageList stretched across the full window width while the identical component inside a Turn wrapped correctly - Extract the placement rule into transient-placement.ts with regression tests covering prompt-id matches, admitted user timeline items, distinct queued messages, and inline routing Fixes apache#5201
Contributor
Author
|
Rebased onto current |
UncertaintyDeterminesYou4ndMe
force-pushed
the
fix/issue-5201-transient-duplicate-measure
branch
from
September 12, 2026 15:39
188f899 to
ea5d565
Compare
…he third enqueue; not touched by this diff)
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.
Fixes #5201
Problem (from the issue)
While a Turn is live, the durable local copy of the just-sent user message could render twice — once as the live Turn's own user bubble, once at the transcript tail with a
Host acceptedchip — and the tail copy ignored the transcript reading measure, stretching across the full window width while the identical component inside a Turn wrapped correctly.Root cause
ChatViewroutes tail-turn transients into the live Turn only while the Turn has no user row yet (inlineTransientMessages). Everything "not inline" then rendered at the tail unconditionally — including a local copy the tail Turn already shows as its own user row.<TransientUserMessage>directly underChatMessageList(the transcript tail and the empty-session optimistic path) have no.maka-turnancestor, and the reading measure (max-width: var(--maka-reading-measure)+ centering, from fix(desktop): give the chat surface one reading measure #3997) is owned by.maka-turn.Changes
transient-placement.ts(new): the placement rule as pure, testable logic.turnRendersUserMessage()detects a message id the transcript already renders as a Turn user row (user.id, or ausertimeline item whosemessageIdmatches — the same id equality the inline slot has always relied on);selectTailTransientMessages()excludes inline-routed and already-rendered rows from the tail slot.chat-view.tsx: the tail slot uses the selector, and both tail/optimistic transient groups render inside a<section className="maka-turn">wrapper — the same wrapper the live-status placeholder next to them already uses, so geometry and spacing stay uniform.Deliberately preserved: a distinct message admitted into the live Turn while its prompt is already on screen (a queued second prompt) still renders at the tail — only true duplicates disappear.
Testing
transient-placement.test.ts(9 cases): prompt-id match, admitted user timeline item match, non-user id reuse, cross-turn matching, empty turns, inline routing exclusion, distinct queued message retention, no-turn pending state.packages/uidist suite: 422/428 pass. The 6 failures are allmermaid-render-cachetests and reproduce identically on pristinemainin this environment (verified by stashing this change and rebuilding) — pre-existing drift unrelated to this PR.apps/desktopstreaming-handoffsuite (the placement assertions over rendered markup, including the exactdata-transient-message-idcount checks): 21/21 pass on this change.transient-message-projection(7/7),message-queue-ui-state(4/4), andapp-shell-exact-turn-arm(2/2) also re-run green.Adversarial review notes (pre-PR)
falsewhen empty, soChatMessageList's "single null child" rule and the no-hero assertions are unaffected.[data-transient-message-id]node; the wrapper adds no anchor-bearing content.TransientUserMessagerender path (type-only imports in composer modules — untouched) and no CSS/e2e selector depends on the previous DOM shape of tail rows.