mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 02:26:37 +00:00
M7 #13 (pass-2): suppress empty assistant bubble during reasoning-only frames
Pass-2 turned up a ghost-message UX bug we missed in pass-1: every "Thinking…" reasoning disclosure had an empty gray bubble next to it. Happens because assistant messages exist momentarily in a reasoning-only state (chunks of thinking text arrive before any primary content), and the bubble path always rendered its padded background regardless of content. Gate the bubble render on non-empty content for assistant messages. User bubbles still always render (the user explicitly submitted content and saw it land — suppressing it on trim-empty would be surprising). `trimmingCharacters(in: .whitespacesAndNewlines)` so purely-whitespace assistant frames also don't render a bubble. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -672,7 +672,18 @@ private struct MessageBubble: View {
|
||||
if message.hasReasoning, let r = message.reasoning, !r.isEmpty {
|
||||
ReasoningDisclosure(reasoning: r)
|
||||
}
|
||||
bubbleContent
|
||||
// Only render the bubble when there's actual text
|
||||
// to show. Assistant messages can exist in a
|
||||
// "reasoning-only" or "tool-calls-only" state
|
||||
// while the agent is thinking / invoking tools —
|
||||
// rendering an empty gray bubble next to every
|
||||
// "Thinking…" disclosure looked like a ghost
|
||||
// message. User bubbles we always render (the
|
||||
// user explicitly submitted content, even if
|
||||
// it's just whitespace, they saw it land).
|
||||
if message.isUser || !message.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
||||
bubbleContent
|
||||
}
|
||||
if !message.toolCalls.isEmpty {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
ForEach(message.toolCalls) { call in
|
||||
|
||||
Reference in New Issue
Block a user