brief-rags-bench/static/js/services/query.service.js

187 lines
5.7 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.

/**
* Query Service
*
* Сервис отправки запросов к RAG backend.
*/
import api from './api-client.js'
import appState from '../state/appState.js'
import { validateJSON } from '../utils/validation.utils.js'
import { generateUUID } from '../utils/format.utils.js'
import { loadFileAsJSON, loadFileAsText } from '../utils/file.utils.js'
/**
* Построить тело запроса из UI
* @param {string} mode - Режим ('questions' или 'raw-json')
* @param {string} questionsText - Текст вопросов (для режима questions)
* @param {string} jsonText - JSON текст (для режима raw-json)
* @returns {Array<{body: string, with_docs: boolean}>} Массив вопросов
*/
export function buildRequestBody(mode, questionsText, jsonText) {
if (mode === 'questions') {
const questions = questionsText
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0)
if (questions.length === 0) {
throw new Error('Введите хотя бы один вопрос')
}
const settings = appState.settings || {}
const defaultWithDocs = settings.defaultWithDocs !== undefined
? settings.defaultWithDocs
: true
return questions.map(q => ({
body: q,
with_docs: defaultWithDocs
}))
} else if (mode === 'raw-json') {
const validation = validateJSON(jsonText)
if (!validation.valid) {
throw new Error(validation.error)
}
return validation.data
} else {
throw new Error(`Неизвестный режим: ${mode}`)
}
}
/**
* Отправить запрос к RAG backend
* @param {string} environment - Окружение (ift/psi/prod)
* @param {string} apiMode - Режим API ('bench' или 'backend')
* @param {Array} questions - Массив вопросов
* @param {boolean} resetSession - Сбрасывать ли сессию (только для backend mode)
* @returns {Promise<object>} API response
*/
export async function sendQuery(environment, apiMode, questions, resetSession = true) {
let apiResponse
if (apiMode === 'bench') {
apiResponse = await api.benchQuery(environment, questions)
} else if (apiMode === 'backend') {
apiResponse = await api.backendQuery(environment, questions, resetSession)
} else {
throw new Error(`Неизвестный режим API: ${apiMode}`)
}
// Validate response format
if (!apiResponse.response ||
!apiResponse.response.answers ||
!Array.isArray(apiResponse.response.answers)) {
throw new Error('Некорректный формат ответа: отсутствует поле "answers"')
}
return apiResponse
}
/**
* Обработать результат запроса и обновить AppState
* @param {string} environment - Окружение
* @param {Array} requestBody - Тело запроса
* @param {object} apiResponse - Ответ от API
*/
export function processQueryResponse(environment, requestBody, apiResponse) {
const env = appState.getEnvironment(environment)
// Update environment state
env.currentRequest = requestBody
env.currentResponse = apiResponse.response
env.requestId = apiResponse.request_id
env.requestTimestamp = apiResponse.timestamp
env.currentAnswerIndex = 0
env.annotations = {}
// Save to localStorage
appState.saveEnvironmentToStorage(environment)
return env
}
/**
* Загрузить запрос из файла
* @param {File} file - JSON файл с запросом
* @returns {Promise<Array>} Массив вопросов
*/
export async function loadRequestFromFile(file) {
try {
const data = await loadFileAsJSON(file)
// Validate it's an array
if (!Array.isArray(data)) {
throw new Error('Файл должен содержать JSON массив')
}
return data
} catch (error) {
console.error('Error loading request from file:', error)
throw new Error(`Ошибка загрузки запроса: ${error.message}`)
}
}
/**
* Загрузить ответ из файла
* @param {File} file - JSON файл с ответом
* @param {string} environment - Текущее окружение
* @returns {Promise<object>} Загруженный ответ
*/
export async function loadResponseFromFile(file, environment) {
try {
const data = await loadFileAsJSON(file)
// Validate response format
if (!data.answers || !Array.isArray(data.answers)) {
throw new Error('Файл должен содержать объект с полем "answers" (массив)')
}
const env = appState.getEnvironment(environment)
// Set response
env.currentResponse = data
env.currentAnswerIndex = 0
env.requestTimestamp = new Date().toISOString()
env.requestId = 'loaded-' + generateUUID()
env.annotations = {}
// Try to reconstruct request from questions in response
env.currentRequest = data.answers.map(answer => ({
body: answer.question,
with_docs: true
}))
// Save to localStorage
appState.saveEnvironmentToStorage(environment)
return data
} catch (error) {
console.error('Error loading response from file:', error)
throw new Error(`Ошибка загрузки ответа: ${error.message}`)
}
}
/**
* Извлечь вопросы из textarea
* @param {string} text - Текст из textarea
* @returns {Array<string>} Массив вопросов
*/
export function extractQuestions(text) {
return text
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0)
}
// Export as default object
export default {
buildRequestBody,
sendQuery,
processQueryResponse,
loadRequestFromFile,
loadResponseFromFile,
extractQuestions
}