Ashutosh1975270's picture
feat: improve graph visualization, stabilize multi-hop path reasoning, and update multi-hop page styling
f14eb69
Raw
History Blame Contribute Delete
1.8 kB
import axios, { AxiosError } from 'axios';
import { API_BASE_URL } from './constants';
import { useAuthStore } from '@/store/auth';
const api = axios.create({
baseURL: API_BASE_URL,
headers: { 'Content-Type': 'application/json' },
timeout: 90000, // 90s β€” LLM calls can be slow
});
// Attach Bearer token to every request
api.interceptors.request.use((config) => {
if (typeof window !== 'undefined') {
const token = useAuthStore.getState().accessToken;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
}
return config;
});
// Handle 401 (auto-refresh) and 429 (rate limit)
api.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
const original = error.config as any;
// 429 – surface a clear, user-friendly rate limit message
if (error.response?.status === 429) {
const err: any = new Error(
'LLM rate limit reached (429). Please wait 30 seconds and try again.'
);
err.response = { data: { error: err.message }, status: 429 };
return Promise.reject(err);
}
// 401 – try to refresh the token once
if (
error.response?.status === 401 &&
!original._retry &&
typeof window !== 'undefined'
) {
original._retry = true;
const refresh = useAuthStore.getState().refreshToken;
if (refresh) {
try {
const { data } = await axios.post(`${API_BASE_URL}/auth/token/refresh/`, { refresh });
useAuthStore.getState().setTokens(data.access, refresh);
original.headers.Authorization = `Bearer ${data.access}`;
return api(original);
} catch {
useAuthStore.getState().logout();
}
}
}
return Promise.reject(error);
}
);
export default api;