feat: add AI chat builder frontend — types, API client, store, components, page, routing

- TypeScript types for chat session, messages, and responses
- API client module with all 6 endpoints
- Zustand store with session management, message sending, tree generation, import, resume
- 7 chat components: ChatMessage, ChatInput, ChatPanel, PhaseIndicator, ChatToolbar, EmptyPreview, StaticTreePreview
- AIChatBuilderPage with split-panel layout (60% chat / 40% preview)
- Route at /ai/chat with lazy loading
- "Build with AI" button on TreeLibraryPage
- Session resume via URL search params

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-27 07:20:04 -05:00
parent 0da67586da
commit 596153085a
15 changed files with 844 additions and 6 deletions

View File

@@ -0,0 +1,44 @@
import { apiClient } from './client'
import type {
AIChatStartResponse,
AIChatMessageResponse,
AIChatSessionResponse,
AIChatGenerateResponse,
AIChatImportResponse,
} from '@/types'
export const aiChatApi = {
startSession: async (flowType: 'troubleshooting' | 'procedural'): Promise<AIChatStartResponse> => {
const { data } = await apiClient.post('/ai/chat/sessions', { flow_type: flowType })
return data
},
sendMessage: async (sessionId: string, content: string): Promise<AIChatMessageResponse> => {
const { data } = await apiClient.post(`/ai/chat/sessions/${sessionId}/messages`, { content })
return data
},
getSession: async (sessionId: string): Promise<AIChatSessionResponse> => {
const { data } = await apiClient.get(`/ai/chat/sessions/${sessionId}`)
return data
},
generateTree: async (sessionId: string): Promise<AIChatGenerateResponse> => {
const { data } = await apiClient.post(`/ai/chat/sessions/${sessionId}/generate`)
return data
},
importTree: async (
sessionId: string,
params?: { name?: string; description?: string; category_id?: string; tags?: string[] }
): Promise<AIChatImportResponse> => {
const { data } = await apiClient.post(`/ai/chat/sessions/${sessionId}/import`, params || {})
return data
},
abandonSession: async (sessionId: string): Promise<void> => {
await apiClient.delete(`/ai/chat/sessions/${sessionId}`)
},
}
export default aiChatApi

View File

@@ -17,3 +17,4 @@ export { targetListsApi } from './targetLists'
export { maintenanceSchedulesApi, batchLaunchApi } from './maintenanceSchedules'
export { default as feedbackApi } from './feedback'
export { default as aiBuilderApi } from './aiBuilder'
export { default as aiChatApi } from './aiChat'