The mid-stream reconnect path could render the just-sent user message below
the live streaming assistant response it triggered, because
`refreshSession()` appended `pending_user_message` at the end of
`S.messages` unconditionally while `loadSession()` correctly inserted
it before the first live assistant message. When the client went through
its reconnect/recovery path mid-turn (typical on iOS PWA screen
lock/resume) the live assistant tail rendered above the prompt.
Centralize every recovery/reconnect reinsertion through one
identity-aware helper (`_mergePendingSessionMessage`) that:
- inserts the owning user turn before its live assistant/Worklog tail,
- appends only when no live tail exists,
- deduplicates against the current tail user row,
- remains idempotent across repeated resume probes.
`refreshSession()` now calls the same helper instead of pushing at
the end. `loadSession()` continues to use the helper unchanged.
Adds `tests/test_issue6419_pending_user_reconnect_order.py` pinning:
- the helper is defined exactly once at module top level,
- it inserts before live assistant and falls back to append,
- `refreshSession()` uses the helper and does not push unconditionally,
- `loadSession()` still merges before renderMessages in the INFLIGHT
reattach branch.
Renames the inner end-marker in
`tests/test_gateway_sse_reconnect_dedupe.py` to a stable inside-loadSession
boundary (`// Phase 2a:`) since the helper is no longer nested.
The responsive font-size overrides for .msg-time were applied globally,
affecting both the role header timestamp (which is only a hover title
tooltip there) AND the message footer timestamp (.msg-foot .msg-time).
Scope to .msg-role .msg-time so the footer row retains its balanced
10.5px base while the role header timestamp scales with font-size.
Remove min-height:200px from the global .mermaid-viewer-viewport rule
(it was outside the @media(max-width:640px) block despite the PR title).
Add a properly-scoped .mermaid-viewer--inline .mermaid-viewer-viewport
min-height inside an actual @media(max-width:640px) block, capped at
min(200px, 70vh) so it cannot override the lightbox fit-to-screen envelope.
fix(ui): scale model name, icon, and TPS badge with font-size preference
The .msg-role (model name/icon header), .role-icon, .msg-role-name,
.msg-tps-inline, and .msg-time elements did not respond to the
data-font-size attribute on :root, causing them to appear
disproportionately small when users selected larger text sizes.
Add responsive CSS rules for small/large/xlarge font-size modes so
the chat role header scales proportionally alongside .msg-body text.
Also replaces the hardcoded inline style="font-size:12px" on the
assistant name span with a class-based rule (.msg-role-name) so the
responsive overrides can take effect.
Closes#5372
Co-Authored-By: Claude <noreply@anthropic.com>
@
The mermaid-viewer-viewport has position:relative with an
absolutely-positioned canvas child, so it collapses to 0 height
on narrow mobile screens where the SVG hasn't loaded yet.
Add min-height:200px so diagrams are visible while rendering.
Fixes#5525
Co-Authored-By: Claude <noreply@anthropic.com>
Extract _turn_transcript_lacks_final_assistant_answer() so settlement
logic can inspect an already-merged transcript. The merge wrapper now
delegates to the pure evaluator without changing behavior.
Fixes#5141