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:
@@ -11,7 +11,12 @@ from pydantic import BaseModel, Field
|
||||
# ── Intake ──
|
||||
|
||||
class AISessionCreateRequest(BaseModel):
|
||||
"""Start a new FlowPilot session."""
|
||||
"""Start a new FlowPilot or chat session."""
|
||||
session_type: str = Field(
|
||||
"guided",
|
||||
pattern="^(guided|chat)$",
|
||||
description="Session type: guided (FlowPilot) or chat (assistant)",
|
||||
)
|
||||
intake_type: str = Field(
|
||||
"free_text",
|
||||
pattern="^(free_text|psa_ticket|screenshot|log_paste|combined)$",
|
||||
@@ -192,6 +197,8 @@ class LinkTicketRequest(BaseModel):
|
||||
class AISessionSummary(BaseModel):
|
||||
"""Compact session for list views."""
|
||||
id: UUID
|
||||
session_type: str = "guided"
|
||||
title: str | None = None
|
||||
status: str
|
||||
intake_type: str
|
||||
problem_summary: str | None = None
|
||||
@@ -208,7 +215,7 @@ class AISessionSummary(BaseModel):
|
||||
|
||||
|
||||
class AISessionDetail(AISessionSummary):
|
||||
"""Full session detail with steps."""
|
||||
"""Full session detail with steps (guided) or messages (chat)."""
|
||||
intake_content: dict[str, Any]
|
||||
matched_flow_id: UUID | None = None
|
||||
match_score: float | None = None
|
||||
@@ -220,10 +227,32 @@ class AISessionDetail(AISessionSummary):
|
||||
psa_connection_id: UUID | None = None
|
||||
ticket_data: dict[str, Any] | None = None
|
||||
steps: list[AISessionStepResponse] = []
|
||||
conversation_messages: list[dict[str, Any]] = [] # Chat sessions store messages here
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
# ── Chat session ──
|
||||
|
||||
class ChatSessionCreateResponse(BaseModel):
|
||||
"""Response after creating a chat session on ai_sessions."""
|
||||
session_id: UUID
|
||||
session_type: str = "chat"
|
||||
title: str
|
||||
status: str = "active"
|
||||
|
||||
|
||||
class ChatMessageRequest(BaseModel):
|
||||
"""Send a message in a chat session."""
|
||||
message: str = Field(..., min_length=1, max_length=8000)
|
||||
|
||||
|
||||
class ChatMessageResponse(BaseModel):
|
||||
"""AI response to a chat message."""
|
||||
content: str
|
||||
suggested_flows: list[dict[str, Any]] = []
|
||||
|
||||
|
||||
class AISessionSearchResult(BaseModel):
|
||||
"""Lightweight session result for Command Palette / autocomplete."""
|
||||
id: UUID
|
||||
|
||||
Reference in New Issue
Block a user