feat: unified sessions — merge assistant chat into ai_sessions table
Add session_type ('guided'|'chat') and title columns to ai_sessions,
enabling both FlowPilot guided sessions and assistant chat sessions to
live in a single table. This is the foundation for a unified session
history and consistent UX across both interaction modes.
Backend:
- Migration 066: session_type + title columns
- unified_chat_service: chat sessions on ai_sessions with same AI/RAG
- POST /ai-sessions supports session_type='chat' creation
- POST /ai-sessions/{id}/chat for chat messages
- DELETE /ai-sessions/{id} for session deletion
- session_type filter on GET /ai-sessions
Frontend:
- AssistantChatPage rewired to aiSessionsApi (no more assistantChatApi)
- /assistant/:sessionId route for deep-linking
- Session history: type filter pills (All/Guided/Chat), type icons
- Dashboard: both types shown with correct routing and icons
- Fixed glass-border → border-default in dashboard components
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
130
docs/plans/2026-03-23-unified-sessions.md
Normal file
130
docs/plans/2026-03-23-unified-sessions.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Unified Sessions — Migration Plan
|
||||
|
||||
> **Date:** 2026-03-23
|
||||
> **Status:** Implementation ready
|
||||
> **Goal:** Merge assistant chat into the ai_sessions system so both guided (FlowPilot) and free-form (chat) sessions share the same data model, history, and action system.
|
||||
|
||||
## Problem
|
||||
|
||||
Three separate conversation systems exist:
|
||||
1. `assistant_chats` — free-form chat, JSONB messages inline, no steps
|
||||
2. `ai_sessions` + `ai_session_steps` — guided FlowPilot, separate steps table
|
||||
3. `ai_chat_sessions` — flow builder (unrelated, leave alone)
|
||||
|
||||
This causes:
|
||||
- No unified session history
|
||||
- Assistant chats missing Resolve/Escalate/Update actions
|
||||
- Dashboard can't show assistant chats in active/recent
|
||||
- Two separate API surfaces to maintain
|
||||
|
||||
## Solution
|
||||
|
||||
Add `session_type` to `ai_sessions`. Chat sessions use `conversation_messages` JSONB for message history (already exists). Both types share the same status, PSA, escalation, and documentation features.
|
||||
|
||||
## Data Model Changes
|
||||
|
||||
### Migration: Add `session_type` to `ai_sessions`
|
||||
|
||||
```sql
|
||||
ALTER TABLE ai_sessions ADD COLUMN session_type VARCHAR(10) NOT NULL DEFAULT 'guided';
|
||||
-- Values: 'guided' (FlowPilot), 'chat' (assistant)
|
||||
```
|
||||
|
||||
### How chat sessions use ai_sessions
|
||||
|
||||
| ai_sessions column | Chat usage |
|
||||
|---|---|
|
||||
| `session_type` | `'chat'` |
|
||||
| `intake_type` | `'free_text'` |
|
||||
| `intake_content` | `{text: "first message"}` |
|
||||
| `conversation_messages` | Full chat history as JSONB array `[{role, content}]` |
|
||||
| `status` | Same: active/resolved/escalated/paused/abandoned |
|
||||
| `problem_summary` | AI-generated from first few messages |
|
||||
| `problem_domain` | AI-detected domain |
|
||||
| `step_count` | Message count (for display) |
|
||||
| `resolution_summary` | Set on resolve |
|
||||
| `escalation_reason` | Set on escalate |
|
||||
| All PSA fields | Same — can link tickets, push notes |
|
||||
| All timestamps | Same |
|
||||
|
||||
### What chat sessions DON'T use
|
||||
|
||||
- `ai_session_steps` table — no steps, messages are in `conversation_messages`
|
||||
- `matched_flow_id` / `match_score` — no flow matching
|
||||
- `confidence_tier` / `confidence_score` — no structured confidence
|
||||
- `system_prompt_snapshot` — could store chat system prompt
|
||||
|
||||
### New field on ai_sessions
|
||||
|
||||
- `title` (String 255, nullable) — chat sessions need a title for the sidebar. Guided sessions can use `problem_summary`.
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Backend — Model & Migration
|
||||
- [ ] Alembic migration: add `session_type` VARCHAR(10) default 'guided', add `title` VARCHAR(255) nullable
|
||||
- [ ] Update AISession model with new columns
|
||||
- [ ] Update schemas: add `session_type` and `title` to response schemas
|
||||
- [ ] Add session_type filter to GET /ai-sessions endpoint
|
||||
|
||||
### Phase 2: Backend — Chat API on ai_sessions
|
||||
- [ ] Create new endpoints or extend existing:
|
||||
- `POST /ai-sessions` with `session_type: 'chat'` — creates a chat session
|
||||
- `POST /ai-sessions/{id}/chat` — send message, get AI response (appends to conversation_messages)
|
||||
- Reuse existing: resolve, escalate, pause, abandon, status-update
|
||||
- [ ] Chat AI service: takes conversation_messages, calls Anthropic, appends response
|
||||
- [ ] Auto-generate title from first message (like current assistant chat does)
|
||||
- [ ] Auto-detect problem_domain from conversation
|
||||
|
||||
### Phase 3: Frontend — Unified Session History
|
||||
- [ ] Update SessionHistoryPage to show both types
|
||||
- [ ] Add type icon: compass/route for guided, message-circle for chat
|
||||
- [ ] Session detail page routes correctly based on type
|
||||
- [ ] Add session_type filter option
|
||||
|
||||
### Phase 4: Frontend — Assistant Chat on ai_sessions
|
||||
- [ ] Update AssistantChatPage to use ai_sessions API instead of assistant_chats
|
||||
- [ ] Chat sidebar queries ai_sessions with `session_type=chat`
|
||||
- [ ] Messages read from / write to `conversation_messages`
|
||||
- [ ] Add header actions: Resolve / Escalate / Share Update / Pause / Close
|
||||
- [ ] Status update modal works the same as FlowPilot
|
||||
|
||||
### Phase 5: Frontend — Dashboard Integration
|
||||
- [ ] ActiveFlowPilotSessions includes chat sessions (both types)
|
||||
- [ ] RecentFlowPilotSessions includes resolved chats
|
||||
- [ ] Type icon on each card so users see the difference at a glance
|
||||
|
||||
### Phase 6: Cleanup
|
||||
- [ ] Migrate existing assistant_chat data to ai_sessions (optional — could just start fresh for pilot)
|
||||
- [ ] Deprecate /assistant/* API endpoints
|
||||
- [ ] Remove assistant_chats model (post-pilot)
|
||||
|
||||
## Visual Differentiators
|
||||
|
||||
| Type | Icon | Badge color | Label |
|
||||
|------|------|------------|-------|
|
||||
| Guided (FlowPilot) | `<Route size={14} />` | cyan | "Guided" |
|
||||
| Chat (Assistant) | `<MessageCircle size={14} />` | purple/violet | "Chat" |
|
||||
|
||||
## API Surface (after migration)
|
||||
|
||||
All under `/ai-sessions`:
|
||||
|
||||
| Endpoint | Both types? | Notes |
|
||||
|----------|------------|-------|
|
||||
| `POST /ai-sessions` | Yes | `session_type` field determines behavior |
|
||||
| `GET /ai-sessions` | Yes | Filter by `session_type` optional |
|
||||
| `GET /ai-sessions/{id}` | Yes | Returns full session with messages or steps |
|
||||
| `POST /ai-sessions/{id}/chat` | Chat only | Send/receive messages |
|
||||
| `POST /ai-sessions/{id}/respond` | Guided only | Step response |
|
||||
| `POST /ai-sessions/{id}/resolve` | Both | Same resolve flow |
|
||||
| `POST /ai-sessions/{id}/escalate` | Both | Same escalation |
|
||||
| `POST /ai-sessions/{id}/pause` | Both | Same pause |
|
||||
| `POST /ai-sessions/{id}/abandon` | Both | Same abandon |
|
||||
| `POST /ai-sessions/{id}/status-update` | Both | Same status updates |
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
- **Low risk:** Adding columns to ai_sessions is additive, no existing data changes
|
||||
- **Medium risk:** Frontend routing — need to route to correct page based on session_type
|
||||
- **Data migration:** Can skip for pilot — start with fresh chat sessions on new system. Old assistant_chats remain accessible via old API until removed.
|
||||
- **Rollback:** session_type column is additive, old assistant_chat endpoints can stay as fallback
|
||||
Reference in New Issue
Block a user