Batch completion events to reduce notify() calls during streaming (#46802)
## Problem
Profiling showed that during agent streaming, `thread.rs:1393:23` was
appearing constantly as a hotspot. The issue was that every single token
from the model triggered:
1. `this.update(cx, ...)`
2. `handle_text_event()` (or thinking/redacted_thinking)
3. `cx.notify()`
4. UI re-render
This created significant foreground thread pressure, contributing to
~500ms delays visible in the profiler.
## Solution
Batch all immediately-available events using `now_or_never()` and
process them in a single `update()` call with one `notify()` at the end.
This approach is deterministic - it processes exactly what's available
right now, adapting naturally to network speed:
- When tokens arrive slowly, you get one at a time
- When they arrive in bursts, they batch automatically
## Changes
- Remove `cx.notify()` from `handle_text_event`,
`handle_thinking_event`, and `handle_redacted_thinking_event`
- Batch events in the streaming loop using `now_or_never()`
- Call `cx.notify()` once per batch instead of per-event
- Keep `cx.notify()` in `handle_tool_use_event` for immediate tool
feedback
Release Notes:
- Improve streaming tool call performance by batching UI updates.
5e9634c718Richard Feldman committed on 1/14/2026, 5:14:28 PM· committed by GitHubparent993bbf5