const { parseCompactConvo, EModelEndpoint, isAgentsEndpoint } = require('librechat-data-provider'); const { getModelsConfig } = require('~/server/controllers/ModelController'); const azureAssistants = require('~/server/services/Endpoints/azureAssistants'); const assistants = require('~/server/services/Endpoints/assistants'); const gptPlugins = require('~/server/services/Endpoints/gptPlugins'); const { processFiles } = require('~/server/services/Files/process'); const anthropic = require('~/server/services/Endpoints/anthropic'); const bedrock = require('~/server/services/Endpoints/bedrock'); const openAI = require('~/server/services/Endpoints/openAI'); const agents = require('~/server/services/Endpoints/agents'); const custom = require('~/server/services/Endpoints/custom'); const google = require('~/server/services/Endpoints/google'); const { handleError } = require('~/server/utils'); const buildFunction = { [EModelEndpoint.openAI]: openAI.buildOptions, [EModelEndpoint.google]: google.buildOptions, [EModelEndpoint.custom]: custom.buildOptions, [EModelEndpoint.agents]: agents.buildOptions, [EModelEndpoint.bedrock]: bedrock.buildOptions, [EModelEndpoint.azureOpenAI]: openAI.buildOptions, [EModelEndpoint.anthropic]: anthropic.buildOptions, [EModelEndpoint.gptPlugins]: gptPlugins.buildOptions, [EModelEndpoint.assistants]: assistants.buildOptions, [EModelEndpoint.azureAssistants]: azureAssistants.buildOptions, }; async function buildEndpointOption(req, res, next) { const { endpoint, endpointType } = req.body; let parsedBody; try { parsedBody = parseCompactConvo({ endpoint, endpointType, conversation: req.body }); } catch (error) { return handleError(res, { text: 'Error parsing conversation' }); } if (req.app.locals.modelSpecs?.list && req.app.locals.modelSpecs?.enforce) { /** @type {{ list: TModelSpec[] }}*/ const { list } = req.app.locals.modelSpecs; const { spec } = parsedBody; if (!spec) { return handleError(res, { text: 'No model spec selected' }); } const currentModelSpec = list.find((s) => s.name === spec); if (!currentModelSpec) { return handleError(res, { text: 'Invalid model spec' }); } if (endpoint !== currentModelSpec.preset.endpoint) { return handleError(res, { text: 'Model spec mismatch' }); } if ( currentModelSpec.preset.endpoint !== EModelEndpoint.gptPlugins && currentModelSpec.preset.tools ) { return handleError(res, { text: `Only the "${EModelEndpoint.gptPlugins}" endpoint can have tools defined in the preset`, }); } try { parsedBody = parseCompactConvo({ endpoint, endpointType, conversation: currentModelSpec.preset, }); } catch (error) { return handleError(res, { text: 'Error parsing model spec' }); } } const endpointFn = buildFunction[endpointType ?? endpoint]; const builder = isAgentsEndpoint(endpoint) ? (...args) => endpointFn(req, ...args) : endpointFn; // TODO: use object params req.body.endpointOption = builder(endpoint, parsedBody, endpointType); // TODO: use `getModelsConfig` only when necessary const modelsConfig = await getModelsConfig(req); req.body.endpointOption.modelsConfig = modelsConfig; if (req.body.files) { // hold the promise req.body.endpointOption.attachments = processFiles(req.body.files); } next(); } module.exports = buildEndpointOption;