Extract Duo chat history into a routed view component
What does this MR do and why?
This MR implements the second tier of a chat initialization refactor, building on !251359 (merged). It removes the last initialization override by eliminating the websocket "connected" flag as a source of truth for the chat view.
Changes to duo_agentic_chat_state_manager.vue:
connectToStream()now always initializes the view from the route first, then optionally adopts a running reply as a separate step, then subscribes to live updates.- Adds
adoptRunningStream()to handle mid-stream replies: it anchors the dedup marker (lastProcessedMessageId) to the last loaded message and shows the waiting state if needed. - Makes
initializeView()awaitable so adoption occurs after the transcript has fully loaded.
Previously, the websocket "connected" flag could override the route (the source of truth). Since the chat state manager now remounts whenever the history view changes routes, initialization correctness depended on that flag being accurate at all times. This fix was flagged as a follow-up in !248969 (merged).
Behaviour change
The chat now loads the conversation transcript and then attaches to a live reply,
instead of skipping the reload when a reply is streaming. The dedup marker prevents
duplicate messages from appearing. On the new-chat route, onNewChat already
disconnects the socket before showing a blank view, so no stale reply gets adopted.
How to test
Frontend unit tests in duo_agentic_chat_state_manager_spec.js cover three scenarios:
(1) opening a thread while a reply streams loads the transcript and preserves the reply
with the dedup marker anchored to the last loaded message; (2) opening a thread with no
live reply shows no phantom waiting state; (3) landing on the new-chat route while a
previous reply streams starts blank without adopting it. All state manager, router,
ai_panel, and history specs pass locally.
Deferred
hydrateActiveWorkflow retains its own reconnect logic for the "reply running
server-side but socket not connected" case, since it has other callers. Consolidating
that into adoptRunningStream is left for a future cleanup.
Related
- Implements #619497 (closed)
- Parent work item: #593468 (closed)
- Tier 1: !251359 (merged)
- Review discussion: !248969 (merged)
Stacking note
This MR targets the branch of !251359 (merged). Retarget to master after that MR and its parent merge.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.