v2.16.1
Fix: TUI chat was stuck (no reply ever rendered)
In the Textual TUI, sending a chat message left the input read-only with no assistant reply: the turn looked permanently frozen.
Cause: the worker-to-UI Textual messages were named with a leading underscore (_ChatDone, _ChatAssistantText, _StreamToken, ...). Textual derives the handler name as on_ + camel_to_snake(class_name), and current Textual preserves the leading underscore, so _ChatDone dispatched to on__chat_done (double underscore) which never matched the defined on_chat_done. Every worker-to-UI message was silently dropped, so the reply never mounted and the turn never cleared. (Older Textual stripped the underscore, so this regressed on a Textual upgrade.)
Fix: renamed the five message classes to drop the leading underscore so the handler names match. Added regression tests for the previously-untested chat-worker path: a structural guard that asserts every TUI message class resolves to a real handler (so a future Textual bump cannot silently re-break it), and a headless pilot test that drives a full tool-enabled turn and asserts the reply renders and the turn clears.
Verified end-to-end: a real local (ollama) model through the headless TUI now renders the reply and clears the turn.
pip install -U conversation-tk