const { logger } = require('@librechat/data-schemas'); const { EndpointURLs, EModelEndpoint, isAgentsEndpoint, parseCompactConvo, } = require('librechat-data-provider'); 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) { logger.warn( `Error parsing conversation for endpoint ${endpoint}${error?.message ? `: ${error.message}` : ''}`, ); 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 { currentModelSpec.preset.spec = spec; if (currentModelSpec.iconURL != null && currentModelSpec.iconURL !== '') { currentModelSpec.preset.iconURL = currentModelSpec.iconURL; } parsedBody = parseCompactConvo({ endpoint, endpointType, conversation: currentModelSpec.preset, }); } catch (error) { logger.error(`Error parsing model spec for endpoint ${endpoint}`, error); return handleError(res, { text: 'Error parsing model spec' }); } } try { const isAgents = isAgentsEndpoint(endpoint) || req.baseUrl.startsWith(EndpointURLs[EModelEndpoint.agents]); const builder = isAgents ? (...args) => buildFunction[EModelEndpoint.agents](req, ...args) : buildFunction[endpointType ?? endpoint]; // TODO: use object params req.body.endpointOption = await builder(endpoint, parsedBody, endpointType); if (req.body.files && !isAgents) { req.body.endpointOption.attachments = processFiles(req.body.files); } next(); } catch (error) { logger.error( `Error building endpoint option for endpoint ${endpoint} with type ${endpointType}`, error, ); return handleError(res, { text: 'Error building endpoint option' }); } } module.exports = buildEndpointOption;