From b07dfb760374b0735662339c995bfa490381db32 Mon Sep 17 00:00:00 2001 From: chihlasm Date: Fri, 3 Apr 2026 03:09:19 +0000 Subject: [PATCH] fix: preserve cockpit steps across view toggles and show full step info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backend: stop wiping pending_task_lane when AI response has no new [ACTIONS]/[QUESTIONS] markers — previous task lane state is still relevant until replaced by new markers. Frontend (selectChat): don't eagerly clear task lane before server response arrives; restore from sessionStorage as fallback when pending_task_lane is null (covers sessions before backend fix). StepsPanel: show description and command for all steps instead of hiding behind hover/active-only visibility. Commands render as inline code blocks. Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/app/services/unified_chat_service.py | 8 ++--- .../src/components/assistant/StepsPanel.tsx | 13 ++++++-- frontend/src/hooks/useAssistantSession.ts | 31 ++++++++++++++++--- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/backend/app/services/unified_chat_service.py b/backend/app/services/unified_chat_service.py index ef2a0ff5..dcb9f670 100644 --- a/backend/app/services/unified_chat_service.py +++ b/backend/app/services/unified_chat_service.py @@ -339,14 +339,12 @@ async def send_chat_message( except Exception: logger.exception("Failed to create fork within branch for session %s", session.id) - # Persist task lane state on session + # Persist task lane state on session — only overwrite when new markers present if branch_questions_data or branch_actions_data: session.pending_task_lane = { "questions": branch_questions_data or [], "actions": branch_actions_data or [], } - else: - session.pending_task_lane = None suggested_flows = extract_suggested_flows( await rag_search(query=message, account_id=account_id, db=db, limit=8) @@ -472,14 +470,12 @@ async def send_chat_message( logger.exception("Failed to create fork for session %s", session_id) # Fork failed but chat message still sent — don't break the response - # Persist task lane state on session + # Persist task lane state on session — only overwrite when new markers present if questions_data or actions_data: session.pending_task_lane = { "questions": questions_data or [], "actions": actions_data or [], } - else: - session.pending_task_lane = None suggested_flows = extract_suggested_flows(rag_results) diff --git a/frontend/src/components/assistant/StepsPanel.tsx b/frontend/src/components/assistant/StepsPanel.tsx index e3560e94..b61157d5 100644 --- a/frontend/src/components/assistant/StepsPanel.tsx +++ b/frontend/src/components/assistant/StepsPanel.tsx @@ -101,15 +101,22 @@ export function StepsPanel({ 'transition-colors duration-200', isCompleted && 'line-through opacity-70', )}>{action.label} - {/* Show description for active step and on hover for others */} {action.description && (

{action.description}

)} + {action.command && ( + + {action.command} + + )} {/* Active indicator */} diff --git a/frontend/src/hooks/useAssistantSession.ts b/frontend/src/hooks/useAssistantSession.ts index d4aa5bd1..d7cdeba0 100644 --- a/frontend/src/hooks/useAssistantSession.ts +++ b/frontend/src/hooks/useAssistantSession.ts @@ -168,9 +168,7 @@ export function useAssistantSession() { const selectChat = useCallback(async (chatId: string) => { currentChatRef.current = chatId setActiveChatId(chatId) - setShowTaskLane(false) - setActiveQuestions([]) - setActiveActions([]) + // Don't clear task lane yet — wait for server response to decide try { const detail = await aiSessionsApi.getSession(chatId) if (currentChatRef.current !== chatId) return @@ -188,7 +186,7 @@ export function useAssistantSession() { triage_hypothesis: detail.triage_hypothesis ?? null, evidence_items: detail.evidence_items ?? null, }) - // Restore task lane from persisted state + // Restore task lane from server state if (detail.pending_task_lane) { const q = detail.pending_task_lane.questions || [] const a = detail.pending_task_lane.actions || [] @@ -202,10 +200,35 @@ export function useAssistantSession() { setActiveQuestions(q) setActiveActions(a) setShowTaskLane(true) + return } } + // Fallback: restore from sessionStorage (covers view toggles before backend fix) + try { + const saved = sessionStorage.getItem('rf-tasklane-meta') + if (saved) { + const d = JSON.parse(saved) + if (d.chatId === chatId) { + const q = d.questions || [] + const a = d.actions || [] + if (q.length > 0 || a.length > 0) { + setActiveQuestions(q) + setActiveActions(a) + setShowTaskLane(d.show === true) + return + } + } + } + } catch { /* ignore */ } + // No task lane data from either source — clear + setShowTaskLane(false) + setActiveQuestions([]) + setActiveActions([]) } catch { setMessages([]) + setShowTaskLane(false) + setActiveQuestions([]) + setActiveActions([]) } }, [])