Description
When using OpenClaw TUI (openclaw tui), the streaming status indicator (e.g., streaming • 1m 50s) continues to display for a significant duration after the assistant has finished producing visible content. This makes it impossible for the user to tell whether the response is complete.
Expected Behavior
The TUI should transition from "streaming" to "idle" promptly after the last content token is delivered.
Actual Behavior
The status bar shows streaming • Xm Xs for 30-120+ seconds after the response text has stopped updating. The user cannot determine if the assistant is still working or has finished.
Root Cause Analysis
After tracing through the source, the delay appears to be between the model finishing its response and the gateway emitting the chat event with state: "final":
- Model produces last token →
runEmbeddedPiAgent returns
emitAgentEvent({ stream: "lifecycle", data: { phase: "end" } }) fires
finalizeLifecycleEvent() in server.impl processes the lifecycle end
emitChatFinal() broadcasts { state: "final" } to WebSocket clients
- TUI receives
state: "final" → calls finalizeRun() → sets activityStatus = "idle"
The gap between steps 1-2 and step 4 reaching the TUI client is where the perceived delay occurs. Post-run work (session persistence, delivery, buffer flushing, cleanup) all happen before or during the final broadcast, extending the visible "streaming" state.
Environment
- OpenClaw: v2026.4.9
- OS: Ubuntu 24.04.4 LTS (x64)
- Model: Claude Opus 4.6 (via API)
- Client:
openclaw tui (WebSocket)
Possible Improvements
- Emit a lightweight "content-complete" signal as soon as the model stops producing tokens, separate from the full lifecycle end
- Or: TUI could show a distinct status like "finishing…" when no new delta arrives for N seconds, while still waiting for the formal
final event
Impact
This is a UX issue — no data loss or functional impact, but it significantly hurts the interactive experience as users cannot tell when a response is done.
Description
When using OpenClaw TUI (
openclaw tui), the streaming status indicator (e.g.,streaming • 1m 50s) continues to display for a significant duration after the assistant has finished producing visible content. This makes it impossible for the user to tell whether the response is complete.Expected Behavior
The TUI should transition from "streaming" to "idle" promptly after the last content token is delivered.
Actual Behavior
The status bar shows
streaming • Xm Xsfor 30-120+ seconds after the response text has stopped updating. The user cannot determine if the assistant is still working or has finished.Root Cause Analysis
After tracing through the source, the delay appears to be between the model finishing its response and the gateway emitting the
chatevent withstate: "final":runEmbeddedPiAgentreturnsemitAgentEvent({ stream: "lifecycle", data: { phase: "end" } })firesfinalizeLifecycleEvent()inserver.implprocesses the lifecycle endemitChatFinal()broadcasts{ state: "final" }to WebSocket clientsstate: "final"→ callsfinalizeRun()→ setsactivityStatus = "idle"The gap between steps 1-2 and step 4 reaching the TUI client is where the perceived delay occurs. Post-run work (session persistence, delivery, buffer flushing, cleanup) all happen before or during the final broadcast, extending the visible "streaming" state.
Environment
openclaw tui(WebSocket)Possible Improvements
finaleventImpact
This is a UX issue — no data loss or functional impact, but it significantly hurts the interactive experience as users cannot tell when a response is done.