brief-rags-bench/static/api-client.js

247 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Brief Bench API Client
* Взаимодействие с FastAPI backend
*/
class BriefBenchAPI {
constructor() {
this.baseURL = '/api/v1'
}
// ============================================
// Internal Helpers
// ============================================
_getToken() {
return localStorage.getItem('access_token')
}
_setToken(token) {
localStorage.setItem('access_token', token)
}
_clearToken() {
localStorage.removeItem('access_token')
}
_getHeaders(includeAuth = true) {
const headers = {
'Content-Type': 'application/json'
}
if (includeAuth) {
const token = this._getToken()
if (token) {
headers['Authorization'] = `Bearer ${token}`
}
}
return headers
}
async _handleResponse(response) {
// Handle 401 Unauthorized
if (response.status === 401) {
this._clearToken()
throw new Error('Сессия истекла. Пожалуйста, войдите снова.')
}
// Handle 502 Bad Gateway (RAG backend error)
if (response.status === 502) {
throw new Error('RAG backend недоступен или вернул ошибку')
}
// Handle other errors
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`)
}
// Handle 204 No Content
if (response.status === 204) {
return null
}
return await response.json()
}
async _request(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`
try {
const response = await fetch(url, options)
return await this._handleResponse(response)
} catch (error) {
console.error(`API request failed: ${endpoint}`, error)
throw error
}
}
// ============================================
// Auth API
// ============================================
/**
* Авторизация с 8-значным логином
* @param {string} login - 8-значный логин
* @returns {Promise<{access_token: string, user: object}>}
*/
async login(login) {
const response = await this._request(`/auth/login?login=${login}`, {
method: 'POST',
headers: this._getHeaders(false)
})
// Сохранить токен
this._setToken(response.access_token)
return response
}
/**
* Выход (очистка токена)
*/
logout() {
this._clearToken()
window.location.reload()
}
/**
* Проверка авторизации
* @returns {boolean}
*/
isAuthenticated() {
return !!this._getToken()
}
// ============================================
// Settings API
// ============================================
/**
* Получить настройки пользователя для всех окружений
* @returns {Promise<{user_id: string, settings: object, updated_at: string}>}
*/
async getSettings() {
return await this._request('/settings', {
method: 'GET',
headers: this._getHeaders()
})
}
/**
* Обновить настройки пользователя
* @param {object} settings - Объект с настройками для окружений
* @returns {Promise<{user_id: string, settings: object, updated_at: string}>}
*/
async updateSettings(settings) {
return await this._request('/settings', {
method: 'PATCH',
headers: this._getHeaders(),
body: JSON.stringify({ settings })
})
}
// ============================================
// Query API
// ============================================
/**
* Отправить batch запрос (Bench mode)
* @param {string} environment - Окружение (ift/psi/prod)
* @param {Array<{body: string, with_docs: boolean}>} questions - Массив вопросов
* @returns {Promise<{request_id: string, timestamp: string, environment: string, response: object}>}
*/
async benchQuery(environment, questions) {
return await this._request('/query/bench', {
method: 'POST',
headers: this._getHeaders(),
body: JSON.stringify({
environment,
questions
})
})
}
/**
* Отправить последовательные запросы (Backend mode)
* @param {string} environment - Окружение (ift/psi/prod)
* @param {Array<{body: string, with_docs: boolean}>} questions - Массив вопросов
* @param {boolean} resetSession - Сбрасывать ли сессию после каждого вопроса
* @returns {Promise<{request_id: string, timestamp: string, environment: string, response: object}>}
*/
async backendQuery(environment, questions, resetSession = true) {
return await this._request('/query/backend', {
method: 'POST',
headers: this._getHeaders(),
body: JSON.stringify({
environment,
questions,
reset_session: resetSession
})
})
}
// ============================================
// Analysis Sessions API
// ============================================
/**
* Сохранить сессию анализа
* @param {object} sessionData - Данные сессии
* @returns {Promise<object>}
*/
async saveSession(sessionData) {
return await this._request('/analysis/sessions', {
method: 'POST',
headers: this._getHeaders(),
body: JSON.stringify(sessionData)
})
}
/**
* Получить список сессий
* @param {string|null} environment - Фильтр по окружению (опционально)
* @param {number} limit - Лимит результатов
* @param {number} offset - Смещение для пагинации
* @returns {Promise<{sessions: Array, total: number}>}
*/
async getSessions(environment = null, limit = 50, offset = 0) {
const params = new URLSearchParams({ limit, offset })
if (environment) {
params.append('environment', environment)
}
return await this._request(`/analysis/sessions?${params}`, {
method: 'GET',
headers: this._getHeaders()
})
}
/**
* Получить конкретную сессию
* @param {string} sessionId - ID сессии
* @returns {Promise<object>}
*/
async getSession(sessionId) {
return await this._request(`/analysis/sessions/${sessionId}`, {
method: 'GET',
headers: this._getHeaders()
})
}
/**
* Удалить сессию
* @param {string} sessionId - ID сессии
* @returns {Promise<null>}
*/
async deleteSession(sessionId) {
return await this._request(`/analysis/sessions/${sessionId}`, {
method: 'DELETE',
headers: this._getHeaders()
})
}
}
// Export API client instance
const api = new BriefBenchAPI()