docs: add FlowPilot / Cockpit side-by-side design spec

Sub-project 2 design spec covering dual-page routing, view toggle,
sidebar navigation, dashboard integration, and shared logic extraction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-02 16:44:07 +00:00
parent a001aa11e5
commit 79c8632dbb

View File

@@ -0,0 +1,147 @@
# FlowPilot / FlowPilot Cockpit Side-by-Side — Design Spec
**Date:** 2026-04-02
**Status:** Approved
**Prerequisite:** Sub-project 1 (Feature Flag Frontend Infrastructure) — completed
**Branch:** `feat/cockpit-harness` (PR #124)
---
## Context
ResolutionFlow's AI chat assistant lives at `/assistant`. On the `feat/cockpit-harness` branch (PR #124), this page was reframed as a triage cockpit with IncidentHeader, StepsPanel, FlowPilotAsks, and WhatWeKnow panels. The production version on `origin/main` retains the classic chat layout with ChatMessage and TaskLane.
Rather than replacing one with the other, both views will coexist on separate routes so beta users can try both and provide feedback. Long-term, the cockpit becomes a premium feature gated by the `flowpilot_cockpit` feature flag.
---
## Design
### 1. Pages & Routing
Two page components, two route groups, one shared session backend.
| Route | Page Component | Source | Description |
|-------|---------------|--------|-------------|
| `/assistant`, `/assistant/:sessionId` | `FlowPilotPage.tsx` | Production `AssistantChatPage` from `origin/main` + backported improvements | Classic chat layout: sidebar, chat messages, TaskLane side panel |
| `/cockpit`, `/cockpit/:sessionId` | `CockpitPage.tsx` | Current `AssistantChatPage` from `feat/cockpit-harness` | Cockpit layout: IncidentHeader, StepsPanel, FlowPilotAsks, WhatWeKnow, conversation log |
**Session portability:** Both pages use the same `ai_sessions` backend and `aiSessionsApi` calls. Navigating from `/assistant/abc123` to `/cockpit/abc123` loads the same session — the cockpit renders triage panels on top of the same data.
**File changes:**
- Rename current `AssistantChatPage.tsx``CockpitPage.tsx`
- Create new `FlowPilotPage.tsx` from `origin/main` version of `AssistantChatPage` with improvements cherry-picked (session-switch race condition guard, etc.)
- Update `router.tsx`: add `/cockpit` and `/cockpit/:sessionId` routes pointing to `CockpitPage`, update `/assistant` routes to point to `FlowPilotPage`
- Remove the now-unused `AssistantChatPage.tsx` import from router
### 2. View Toggle
A toggle in the page header lets users switch between FlowPilot and FlowPilot Cockpit mid-session.
- **Location:** Top bar area of both pages, next to existing action buttons (Resolve/Escalate)
- **Visibility:** Only appears when viewing an active session (not on empty/new session state) AND only if the user has the `flowpilot_cockpit` feature flag enabled
- **Visual:** Segmented control / pill toggle — `FlowPilot | Cockpit` — with the active view highlighted
- **Behavior:** Clicking the other segment navigates via `react-router` `navigate()`: e.g., `/assistant/abc123``/cockpit/abc123`
- **Performance:** Navigation is instant — no data refetch needed since both pages load the same session by ID from the API on mount
- **Component:** `ViewToggle.tsx` — shared component imported by both pages
**Edge case:** If the user is on `/cockpit/:sessionId` but loses the `flowpilot_cockpit` feature flag (admin disables it), the cockpit page redirects to `/assistant/:sessionId` via a `useEffect` check.
### 3. Sidebar Navigation
New top-level rail icon for FlowPilot, with flyout showing both views.
- **Rail icon:** `Sparkles` with label "FlowPilot"
- **Position:** Second item in the rail, right after Home — this is the primary workflow entry point
- **Flyout children:**
- "FlowPilot" → `/assistant`
- "FlowPilot Cockpit" → `/cockpit` — only shown if `useFeatureFlag('flowpilot_cockpit')` returns `true`
- **matchPaths:** `['/assistant', '/cockpit']` — both routes highlight this rail icon
- **Pinned sidebar sections:** Add under the existing "RESOLVE" section with the same gating logic
### 4. Dashboard Integration
`QuickStartPage` lets the user choose which view new sessions launch into.
- **Default behavior:** `StartSessionInput` continues to launch to `/assistant` (FlowPilot)
- **Cockpit launch option:** If the user has the `flowpilot_cockpit` flag enabled, show a small toggle or dropdown near the submit button — "Open in: FlowPilot | Cockpit" — that controls whether the new session navigates to `/assistant/:sessionId` or `/cockpit/:sessionId`
- **Preference persistence:** Store the user's last choice in `userPreferencesStore` (persisted to `localStorage`) so it remembers their preferred launch target across sessions
- **Dashboard session cards:** `ActiveFlowPilotSessions` and `RecentFlowPilotSessions` — clicking a session navigates to the user's stored view preference
### 5. Shared Logic Extraction
Both pages share significant session management code. Extract into a shared hook to avoid duplication.
**`useAssistantSession` hook** (new file: `frontend/src/hooks/useAssistantSession.ts`):
- Session CRUD (create, load, select, delete)
- Chat message sending + response handling
- File upload handling (`pendingUploads`, drag-drop)
- Active questions/actions state management
- Branching integration (`useBranching`)
- Session-switch race condition guard (`currentChatRef` pattern)
- Conclude/resolve/escalate flows
- Prefill auto-submit logic
**`FlowPilotPage.tsx`** — imports `useAssistantSession`, renders the classic chat layout (ChatMessage, TaskLane sidebar panel)
**`CockpitPage.tsx`** — imports `useAssistantSession`, renders the cockpit layout (IncidentHeader, StepsPanel, FlowPilotAsks, WhatWeKnow, conversation log) plus manages cockpit-specific state (triage metadata, evidence items, drag-resizable split)
This keeps each page focused on layout/rendering (~200-400 lines each) while the ~600+ lines of shared session logic live in one place.
### 6. Backend Changes
Minimal backend work — most infrastructure already exists.
The triage columns (`client_name`, `asset_name`, `issue_category`, `triage_hypothesis`, `evidence_items`) are already on the `ai_sessions` table. What's needed:
- **Verify existing endpoints:** Confirm `PATCH /ai-sessions/{id}/triage` and the `triage_update` field in `ChatMessageResponse` are working. If not, implement per the cockpit design spec (`docs/cockpit/2026-04-01-msp-assistant-harness-design.md`)
- **Handoff draft endpoint:** `POST /ai-sessions/{id}/handoff-draft` (streaming) — needed for the cockpit's Conclude modal. Streams a structured JSON object with `root_cause`, `resolution`, `steps_taken`, `recommendations`
- **No new migrations** — triage columns already exist on this branch, `flowpilot_cockpit` flag seeded in migration 072
- **No changes to the FlowPilot (chat) page's backend** — it uses the same endpoints it always has
### 7. UI Naming
- Rename "AI Assistant" → "FlowPilot" throughout the UI (sidebar, page titles, breadcrumbs, dashboard)
- The cockpit view is labelled "FlowPilot Cockpit"
- Internal code: `FlowPilotPage` and `CockpitPage`
---
## Scope Boundary
**In scope:**
- New `FlowPilotPage.tsx` (from production `AssistantChatPage` + backported improvements)
- Rename current `AssistantChatPage.tsx` to `CockpitPage.tsx`
- Extract shared session logic into `useAssistantSession` hook
- Routes: `/assistant`, `/assistant/:sessionId`, `/cockpit`, `/cockpit/:sessionId`
- `ViewToggle` component in both page headers (gated by feature flag)
- Sidebar rail entry with flyout (cockpit gated by feature flag)
- Dashboard `StartSessionInput` launch preference toggle
- Verify/complete triage backend endpoints (PATCH triage, handoff-draft streaming)
- Rename "AI Assistant" to "FlowPilot" in UI labels
**Not in scope:**
- Changes to the guided flow session page (`/pilot`) — stays as-is, hidden from sidebar
- New AI model routing or prompt changes
- PSA integration changes
- Real-time flag updates (reload is fine)
- Mobile-specific cockpit layout (responsive basics only)
---
## Files Changed
| File | Change |
|------|--------|
| `frontend/src/pages/AssistantChatPage.tsx` | Rename to `CockpitPage.tsx` |
| `frontend/src/pages/FlowPilotPage.tsx` | New — classic chat layout from `origin/main` + improvements |
| `frontend/src/pages/CockpitPage.tsx` | Renamed from AssistantChatPage, refactored to use `useAssistantSession` |
| `frontend/src/hooks/useAssistantSession.ts` | New — shared session logic extracted from both pages |
| `frontend/src/components/assistant/ViewToggle.tsx` | New — segmented control for switching views |
| `frontend/src/router.tsx` | Add `/cockpit` routes, update `/assistant` routes to FlowPilotPage |
| `frontend/src/components/layout/Sidebar.tsx` | Add FlowPilot rail entry with cockpit flyout child |
| `frontend/src/pages/QuickStartPage.tsx` | Add launch preference toggle for cockpit |
| `frontend/src/store/userPreferencesStore.ts` | Add `preferredFlowPilotView` preference |
| `backend/app/api/endpoints/ai_sessions.py` | Verify/add PATCH triage endpoint + handoff-draft streaming endpoint |
| `backend/app/schemas/ai_session.py` | Verify/add TriageUpdate, options on QuestionItem |
| `backend/app/services/unified_chat_service.py` | Verify/add triage extraction in chat responses |