import api from '../../api'; import type { AiApiResponse, AiAttachment, AiConversation, AiMessagePage, AiReviewSchema, AiReviewSection, AiReviewSectionType, AiSkill, } from './types'; const basePath = '/ai/chat/conversations'; export const aiChatApi = { listSkills: async () => (await api.get>('/ai/chat/skills')).data, listConversations: async () => (await api.get>(basePath)).data, createConversation: async (input?: { title?: string; lockedSkillKey?: string | null }) => (await api.post>(basePath, input ?? {})).data, updateConversation: async ( id: number, input: { title?: string; lockedSkillKey?: string | null }, ) => (await api.patch>(`${basePath}/${id}`, input)).data, deleteConversation: (id: number) => api.delete(`${basePath}/${id}`), deleteAllConversations: async () => (await api.delete<{ success: boolean; data: { deleted: number } }>(basePath)).data, deleteMessage: async (conversationId: number, messageId: number) => ( await api.delete>( `${basePath}/${conversationId}/messages/${messageId}`, ) ).data, uploadAttachment: async ( file: File, onProgress?: (percent: number) => void, ): Promise => { const form = new FormData(); form.append('file', file); return ( await api.post>('/ai/chat/attachments', form, { timeout: 120_000, onUploadProgress: (event) => { if (!onProgress || !event.total) return; onProgress(Math.min(Math.round((event.loaded / event.total) * 100), 100)); }, }) ).data; }, deleteAttachment: (id: number) => api.delete(`/ai/chat/attachments/${id}`), confirmReviewStep: async ( reviewId: string, sectionKey: AiReviewSection['key'], ): Promise => ( await api.post>( `/ai/chat/reviews/${reviewId}/steps/${sectionKey}/confirm`, ) ).data, confirmReviewGroup: async ( reviewId: string, type: AiReviewSectionType, ): Promise => ( await api.post>( `/ai/chat/reviews/${reviewId}/types/${type}/confirm`, ) ).data, listMessages: async (id: number): Promise => { const first = ( await api.get>(`${basePath}/${id}/messages`, { params: { page: 1, limit: 100 }, }) ).data; const pageCount = Math.ceil(first.total / first.limit); if (pageCount <= 1) return first; const rest = await Promise.all( Array.from({ length: pageCount - 1 }, (_, index) => api .get>(`${basePath}/${id}/messages`, { params: { page: index + 2, limit: first.limit }, }) .then((response) => response.data), ), ); return { ...first, items: [first, ...rest].flatMap((page) => page.items) }; }, }; export function conversationStreamUrl(id: number): string { return `/api${basePath}/${id}/stream`; }