| | const { |
| | SystemRoles, |
| | EModelEndpoint, |
| | defaultOrderQuery, |
| | defaultAssistantsVersion, |
| | } = require('librechat-data-provider'); |
| | const { |
| | initializeClient: initAzureClient, |
| | } = require('~/server/services/Endpoints/azureAssistants'); |
| | const { initializeClient } = require('~/server/services/Endpoints/assistants'); |
| | const { getEndpointsConfig } = require('~/server/services/Config'); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | const getCurrentVersion = async (req, endpoint) => { |
| | const index = req.baseUrl.lastIndexOf('/v'); |
| | let version = index !== -1 ? req.baseUrl.substring(index + 1, index + 3) : null; |
| | if (!version && req.body.version) { |
| | version = `v${req.body.version}`; |
| | } |
| | if (!version && endpoint) { |
| | const endpointsConfig = await getEndpointsConfig(req); |
| | version = `v${endpointsConfig?.[endpoint]?.version ?? defaultAssistantsVersion[endpoint]}`; |
| | } |
| | if (!version?.startsWith('v') && version.length !== 2) { |
| | throw new Error(`[${req.baseUrl}] Invalid version: ${version}`); |
| | } |
| | return version; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const _listAssistants = async ({ req, res, version, query }) => { |
| | const { openai } = await getOpenAIClient({ req, res, version }); |
| | return openai.beta.assistants.list(query); |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const listAllAssistants = async ({ req, res, version, query }) => { |
| | |
| | const { openai } = await getOpenAIClient({ req, res, version }); |
| | const allAssistants = []; |
| |
|
| | let first_id; |
| | let last_id; |
| | let afterToken = query.after; |
| | let hasMore = true; |
| |
|
| | while (hasMore) { |
| | const response = await openai.beta.assistants.list({ |
| | ...query, |
| | after: afterToken, |
| | }); |
| |
|
| | const { body } = response; |
| |
|
| | allAssistants.push(...body.data); |
| | hasMore = body.has_more; |
| |
|
| | if (!first_id) { |
| | first_id = body.first_id; |
| | } |
| |
|
| | if (hasMore) { |
| | afterToken = body.last_id; |
| | } else { |
| | last_id = body.last_id; |
| | } |
| | } |
| |
|
| | return { |
| | data: allAssistants, |
| | body: { |
| | data: allAssistants, |
| | has_more: false, |
| | first_id, |
| | last_id, |
| | }, |
| | }; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const listAssistantsForAzure = async ({ req, res, version, azureConfig = {}, query }) => { |
| | |
| | const groupModelTuples = []; |
| | const promises = []; |
| | |
| | const groups = []; |
| |
|
| | const { groupMap, assistantGroups } = azureConfig; |
| |
|
| | for (const groupName of assistantGroups) { |
| | const group = groupMap[groupName]; |
| | groups.push(group); |
| |
|
| | const currentModelTuples = Object.entries(group?.models); |
| | groupModelTuples.push(currentModelTuples); |
| |
|
| | |
| | |
| | req.body.model = currentModelTuples[0][0]; |
| | promises.push(listAllAssistants({ req, res, version, query })); |
| | } |
| |
|
| | const resolvedQueries = await Promise.all(promises); |
| | const data = resolvedQueries.flatMap((res, i) => |
| | res.data.map((assistant) => { |
| | const deploymentName = assistant.model; |
| | const currentGroup = groups[i]; |
| | const currentModelTuples = groupModelTuples[i]; |
| | const firstModel = currentModelTuples[0][0]; |
| |
|
| | if (currentGroup.deploymentName === deploymentName) { |
| | return { ...assistant, model: firstModel }; |
| | } |
| |
|
| | for (const [model, modelConfig] of currentModelTuples) { |
| | if (modelConfig.deploymentName === deploymentName) { |
| | return { ...assistant, model }; |
| | } |
| | } |
| |
|
| | return { ...assistant, model: firstModel }; |
| | }), |
| | ); |
| |
|
| | return { |
| | first_id: data[0]?.id, |
| | last_id: data[data.length - 1]?.id, |
| | object: 'list', |
| | has_more: false, |
| | data, |
| | }; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | async function getOpenAIClient({ req, res, endpointOption, initAppClient, overrideEndpoint }) { |
| | let endpoint = overrideEndpoint ?? req.body.endpoint ?? req.query.endpoint; |
| | const version = await getCurrentVersion(req, endpoint); |
| | if (!endpoint) { |
| | throw new Error(`[${req.baseUrl}] Endpoint is required`); |
| | } |
| |
|
| | let result; |
| | if (endpoint === EModelEndpoint.assistants) { |
| | result = await initializeClient({ req, res, version, endpointOption, initAppClient }); |
| | } else if (endpoint === EModelEndpoint.azureAssistants) { |
| | result = await initAzureClient({ req, res, version, endpointOption, initAppClient }); |
| | } |
| |
|
| | return result; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const fetchAssistants = async ({ req, res, overrideEndpoint }) => { |
| | const appConfig = req.config; |
| | const { |
| | limit = 100, |
| | order = 'desc', |
| | after, |
| | before, |
| | endpoint, |
| | } = req.query ?? { |
| | endpoint: overrideEndpoint, |
| | ...defaultOrderQuery, |
| | }; |
| |
|
| | const version = await getCurrentVersion(req, endpoint); |
| | const query = { limit, order, after, before }; |
| |
|
| | |
| | let body; |
| |
|
| | if (endpoint === EModelEndpoint.assistants) { |
| | ({ body } = await listAllAssistants({ req, res, version, query })); |
| | } else if (endpoint === EModelEndpoint.azureAssistants) { |
| | const azureConfig = appConfig.endpoints?.[EModelEndpoint.azureOpenAI]; |
| | body = await listAssistantsForAzure({ req, res, version, azureConfig, query }); |
| | } |
| |
|
| | if (req.user.role === SystemRoles.ADMIN) { |
| | return body; |
| | } else if (!appConfig.endpoints?.[endpoint]) { |
| | return body; |
| | } |
| |
|
| | body.data = filterAssistants({ |
| | userId: req.user.id, |
| | assistants: body.data, |
| | assistantsConfig: appConfig.endpoints?.[endpoint], |
| | }); |
| | return body; |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | function filterAssistants({ assistants, userId, assistantsConfig }) { |
| | const { supportedIds, excludedIds, privateAssistants } = assistantsConfig; |
| | if (privateAssistants) { |
| | return assistants.filter((assistant) => userId === assistant.metadata?.author); |
| | } else if (supportedIds?.length) { |
| | return assistants.filter((assistant) => supportedIds.includes(assistant.id)); |
| | } else if (excludedIds?.length) { |
| | return assistants.filter((assistant) => !excludedIds.includes(assistant.id)); |
| | } |
| | return assistants; |
| | } |
| |
|
| | module.exports = { |
| | getOpenAIClient, |
| | fetchAssistants, |
| | getCurrentVersion, |
| | }; |
| |
|