import axios from 'axios' const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api' const api = axios.create({ baseURL: API_BASE_URL, timeout: 30000, }) // Add authentication interceptor api.interceptors.request.use( async (config) => { // Try to get token from either auth method const authToken = localStorage.getItem('authToken'); const azureToken = localStorage.getItem('azureAuthToken'); const token = authToken || azureToken; if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => Promise.reject(error) ) api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // Token expired or invalid, clear all tokens and redirect to login localStorage.removeItem('authToken'); localStorage.removeItem('azureAuthToken'); localStorage.removeItem('currentUser'); window.location.href = '/login'; } console.error('API Error:', error.response?.data || error.message) return Promise.reject(error) } ) export const agentsAPI = { async getAll(admin = false) { const params = admin ? { admin: 'true' } : {}; // Add userId for permission filtering (unless admin request) if (!admin) { const currentUser = localStorage.getItem('currentUser'); if (currentUser) { const user = JSON.parse(currentUser); params.userId = user.id; } } const response = await api.get('/assistants', { params }) return response.data }, async getByKey(key) { const response = await api.get(`/assistants/${key}`) return response.data }, async update(key, data) { const response = await api.put(`/assistants/${key}`, data) return response.data }, async toggleStatus(key) { const response = await api.patch(`/assistants/${key}/toggle-status`) return response.data }, async create(data) { const response = await api.post('/assistants', data) return response.data }, async delete(key) { const response = await api.delete(`/assistants/${key}`) return response.data } } // Keep old name for backward compatibility during migration export const assistantsAPI = agentsAPI export const chatAPI = { async sendMessage(data, files = []) { if (files && files.length > 0) { const formData = new FormData() // Add text data Object.keys(data).forEach(key => { if (key !== 'files') { formData.append(key, typeof data[key] === 'object' ? JSON.stringify(data[key]) : data[key]) } }) // Add files files.forEach(file => { formData.append('files', file) }) const response = await api.post('/chat/completions', formData, { headers: { 'Content-Type': 'multipart/form-data', } }) return response.data } else { const response = await api.post('/chat/completions', data) return response.data } }, async sendStreamingMessage(data, onChunk, files = []) { let requestBody let headers = {} if (files && files.length > 0) { const formData = new FormData() // Add text data Object.keys(data).forEach(key => { if (key !== 'files') { formData.append(key, typeof data[key] === 'object' ? JSON.stringify(data[key]) : data[key]) } }) formData.append('stream', 'true') // Add files files.forEach(file => { formData.append('files', file) }) requestBody = formData } else { headers['Content-Type'] = 'application/json' requestBody = JSON.stringify({ ...data, stream: true }) } const response = await fetch(`${API_BASE_URL}/chat/completions`, { method: 'POST', headers, body: requestBody }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } const reader = response.body.getReader() const decoder = new TextDecoder() try { while (true) { const { done, value } = await reader.read() if (done) break const chunk = decoder.decode(value) const lines = chunk.split('\n') for (const line of lines) { if (line.startsWith('data: ')) { try { const data = JSON.parse(line.slice(6)) if (onChunk) onChunk(data) } catch (e) { console.warn('Failed to parse SSE data:', line) } } } } } finally { reader.releaseLock() } }, async getConversationMessages(conversationId, limit = 50, offset = 0) { const response = await api.get(`/chat/conversations/${conversationId}/messages`, { params: { limit, offset } }) return response.data }, async getConversations(userId, limit = 20, offset = 0) { const response = await api.get('/chat/conversations', { params: { userId, limit, offset } }) return response.data } } export const analyticsAPI = { async getUsageData(filters = {}) { const params = {}; if (filters.startDate) params.startDate = filters.startDate; if (filters.endDate) params.endDate = filters.endDate; if (filters.userId) params.userId = filters.userId; if (filters.agentKey) params.agentKey = filters.agentKey; const response = await api.get('/analytics/usage', { params }); return response.data; }, async getUsageStats(filters = {}) { const params = {}; if (filters.startDate) params.startDate = filters.startDate; if (filters.endDate) params.endDate = filters.endDate; const response = await api.get('/analytics/stats', { params }); return response.data; }, async getTrends(days = 30) { const response = await api.get('/analytics/trends', { params: { days } }); return response.data; }, async getAgentTrends(days = 30) { const response = await api.get('/analytics/agent-trends', { params: { days } }); return response.data; } }; export const usersAPI = { async getAll() { const response = await api.get('/users'); return response.data; }, async getById(id) { const response = await api.get(`/users/${id}`); return response.data; }, async update(id, userData) { const response = await api.put(`/users/${id}`, userData); return response.data; }, async create(userData) { const response = await api.post('/users', userData); return response.data; }, async delete(id) { const response = await api.delete(`/users/${id}`); return response.data; }, async toggleStatus(id) { const response = await api.patch(`/users/${id}/toggle-status`); return response.data; } }; export default api