#8353: fix(ui): display tool calls during webchat streaming
app: web-ui
stale
## Problem
In webchat, tool calls are invisible during streaming — they only appear after the run completes. Users see text responses streaming but tool cards don't render until the end.
Root causes:
1. **Race condition:** Tool events arriving before `assistant` events were dropped because `chatRunId` wasn't set yet
2. **Text interleaving:** Streaming text segments between tool calls replaced each other instead of accumulating
3. **Grouping:** Tool messages were incorrectly grouped with regular text messages
Related: #6446, #5681, #6614
## Solution
1. Initialize `chatRunId` from tool events if not yet set (fixes race condition)
2. Accumulate `chatStreamSegments` and sort by timestamp before rendering
3. Break message grouping when switching between tools and text
## Changes
- ~86 lines across 4 files in `ui/src/ui/`
## Testing
Verified tool cards now appear in real-time during streaming, matching the final rendered state after completion.
## Note
This is a complex fix touching multiple components. I've tested it extensively in my fork. Happy to iterate if maintainers have concerns about the approach.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the webchat streaming/render pipeline so tool calls become visible during streaming (not only after completion). It does this by (1) letting tool events initialize `chatRunId` when assistant events haven’t arrived yet, (2) tracking/accumulating committed streaming text segments and then interleaving them with tool messages by timestamp, and (3) preventing tool messages from being grouped with regular assistant text in the chat UI.
The changes primarily live in `ui/src/ui/app-tool-stream.ts` (event handling + segment commit), `ui/src/ui/views/chat.ts` (interleave/sort + grouping break), with wiring/state plumbed through `app.ts`/`app-render.ts` to pass the new `streamSegments` state into the chat view.
<h3>Confidence Score: 3/5</h3>
- This PR is reasonably safe to merge, but there are a couple run-identification and grouping edge cases that could still mis-associate events under reconnection/out-of-order delivery.
- The change addresses real streaming/UI correctness issues and the approach is coherent, but there are some correctness pitfalls around initializing `chatRunId` from tool events (which can claim the wrong run) and around detecting tool messages for grouping (which may miss content-only tool encodings). There’s also minor determinism risk in timestamp sorting without a tie-breaker.
- ui/src/ui/app-tool-stream.ts and ui/src/ui/views/chat.ts
<!-- greptile_other_comments_section -->
<sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#9248: Fix: Webchat UI goes grey/unresponsive after Slack message tool calls
by vishaltandale00 · 2026-02-05
84.7%
#15110: fix: enable auto-scroll during assistant response streaming
by jwchmodx · 2026-02-13
81.6%
#14946: fix(webchat): accumulate text across blocks in streaming buffer
by mcaxtr · 2026-02-12
80.1%
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
80.1%
#19235: fix(telegram): tool error warnings no longer overwrite streamed rep...
by gatewaybuddy · 2026-02-17
79.8%
#14309: fix(ui): resolve chat event session key mismatch
by justonlyforyou · 2026-02-11
79.6%
#5681: fix(gateway): flush text buffer before tool events in webchat
by MaudeBot · 2026-01-31
79.4%
#18187: fix: tool summaries silently dropped when reasoningLevel is stream
by ayanesakura · 2026-02-16
79.3%
#4495: Fix: emit final assistant event when reply tags hide stream
by ukeate · 2026-01-30
78.9%
#9220: Fix: TUI drops API responses silently when runID already finalized
by vishaltandale00 · 2026-02-05
78.8%