feat: render stream events in TUI message bubbles - #653
Conversation
- Add events prop to MessageBubble component - Build eventsEl following existing rendering pattern (Box wrapper, Text elements) - Render events alongside reasoning, tool call, and tool display elements - Add OpenSpec proposal, tasks, and spec for the change Closes #604
PR Audit: component-message-bubbles Spec CompliancePR: #653 — feat: render stream events in TUI message bubbles Requirement 1: MessageBubble renders stream events
Verdict: 4/5 pass. 1 gap. Requirement 2: Event data structure
Verdict: 2/3 pass. 1 gap. Requirement 3: Events rendering follows existing pattern
Verdict: 3/4 pass. 1 gap. Summary
Gaps to Address
Overall AssessmentThe implementation is functionally complete and well-structured. The three gaps are minor deviations — one is a missing interactive feature (collapsible), one is an unrendered optional field ( |
- Add collapsible toggle for events section (+/- indicator) - Render optional data field when present (truncated to 100 chars) - Change flexDirection from 'column' to 'row' to match spec pattern
Text doesn't support onClick in Ink — wrap the toggle label in a Box with cursorHidden and onClick on the Box instead.
Ink's onClick is unreliable and collapsible sections are a desktop UI pattern, not a terminal one. Events are now always visible.
Instead of listing every event, show one line per type with count: - message [16] - tool_call [3] - error [1]
Raw event types like 'on_tool_start' are now mapped to human-readable labels: tool, model, agent, chain, retriever, custom. Unknown types are cleaned up (strips 'on_' prefix, replaces underscores).
Previously the provider used streamMode 'messages' which only emitted message events. Now it uses 'events' to capture the full stream: on_tool_start, on_tool_end, on_chat_model_stream, on_agent_action, etc. Events are transformed from LangChain format (event.event) to the streamingCallback format (event.type) so the TUI handler works without changes.
|
I'm pretty sure this isn't technically possible without patching the deepagentsjs lib to emit more than a 'message' event. |
Summary
Render the captured LangChain
streamEventsin the TUI message bubbles so users can see what's actually happening during agent execution — tool calls, agent actions, chain events, reasoning, errors.Changes
eventsprop destructuring, builteventsElwith conditional rendering (Box wrapper + Text elements for each event), rendered alongsidereasoningEl,toolCallEl,toolDisplayElImplementation Details
The events rendering follows the existing pattern in MessageBubble:
hasEvents = events && events.length > 0flexDirection: "column"andmarginTop: 1Related
Closes #604