import axios from 'axios'; // Base URL for the API (will use proxy from package.json) const API_BASE_URL = process.env.REACT_APP_API_URL || '/api'; // Create axios instance with default config const api = axios.create({ baseURL: API_BASE_URL, headers: { 'Content-Type': 'application/json', }, }); // Request interceptor api.interceptors.request.use( (config) => { // Add auth token if available const token = localStorage.getItem('auth_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => { return Promise.reject(error); } ); // Response interceptor api.interceptors.response.use( (response) => { return response.data; }, (error) => { // Handle common errors if (error.response?.status === 401) { // Handle unauthorized access localStorage.removeItem('auth_token'); // Redirect to login if needed } const errorMessage = error.response?.data?.message || error.message || 'An error occurred'; return Promise.reject(new Error(errorMessage)); } ); // API Functions /** * Send a message/question to the RAG system */ export const sendMessage = async (message) => { try { const response = await api.post('/ask', { question: message, }); return response; } catch (error) { console.error('Error sending message:', error); throw error; } }; /** * Send a message/question to the RAG system and get a streaming response */ export const sendMessageStream = async (message, onChunk) => { try { const response = await fetch(`${API_BASE_URL}/ask_stream`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ question: message }), }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } if (!response.body) { throw new Error("ReadableStream not yet supported in this browser."); } 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, { stream: true }); if (chunk) { onChunk(chunk); } } } finally { reader.releaseLock(); } } catch (error) { console.error('Error sending streaming message:', error); throw error; } }; /** * Upload a document to the system */ export const uploadDocument = async (formData) => { try { const response = await api.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', }, // Upload progress callback onUploadProgress: (progressEvent) => { const percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); console.log(`Upload progress: ${percentCompleted}%`); }, }); return response; } catch (error) { console.error('Error uploading document:', error); throw error; } }; /** * Get system status and information */ export const getSystemStatus = async () => { try { const response = await api.get('/status'); return response; } catch (error) { console.error('Error getting system status:', error); throw error; } }; /** * Get collection information */ export const getCollectionInfo = async () => { try { const response = await api.get('/collection/info'); return response; } catch (error) { console.error('Error getting collection info:', error); throw error; } }; /** * Delete a document from the collection */ export const deleteDocument = async (documentId) => { try { const response = await api.delete(`/documents/${documentId}`); return response; } catch (error) { console.error('Error deleting document:', error); throw error; } }; /** * Search documents */ export const searchDocuments = async (query, limit = 5) => { try { const response = await api.post('/search', { query, limit, }); return response; } catch (error) { console.error('Error searching documents:', error); throw error; } }; /** * Health check endpoint */ export const healthCheck = async () => { try { const response = await api.get('/health'); return response; } catch (error) { console.error('Error checking health:', error); throw error; } }; export default api;