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:
@@ -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 |
|
||||
Reference in New Issue
Block a user