tui: per-message chat widgets — render only the streaming bubble
ChatPanel used to hold a single Static rebuilt via update(Group(...)) on every
event, so a per-token stream_delta re-rendered all visible items (up to 200).
Now each message is its own _ChatItemView(Static); _sync() mounts new widgets at
the end, removes dropped ones, and signature-gated maybe_update re-renders only
the changed widget. On a stream only the streaming bubble repaints — the rest
stay mounted untouched. Public API stays synchronous (mount/remove are sync in
this Textual version), so tui_app is unchanged. Truncation hint is now a
dedicated top widget toggled via styles.display.

Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ff7c7bb commit 7a0f93b3e23f78343bfc5e9f4da278aaf293882e
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 20 hours ago
Showing 2 changed files
View
clients/terminal/tui/widgets/chat_panel.py
View
tests/clients/test_chat_panel.py