diff --git a/api/server/services/Config/loadConfigModels.js b/api/server/services/Config/loadConfigModels.js index bfdb80b4ac..b3997a2ada 100644 --- a/api/server/services/Config/loadConfigModels.js +++ b/api/server/services/Config/loadConfigModels.js @@ -46,12 +46,23 @@ async function loadConfigModels(req) { (endpoint.models.fetch || endpoint.models.default), ); - const fetchPromisesMap = {}; // Map for promises keyed by unique combination of baseURL and apiKey - const uniqueKeyToNameMap = {}; // Map to associate unique keys with endpoint names + /** + * @type {Record} + * Map for promises keyed by unique combination of baseURL and apiKey */ + const fetchPromisesMap = {}; + /** + * @type {Record} + * Map to associate unique keys with endpoint names; note: one key may can correspond to multiple endpoints */ + const uniqueKeyToEndpointsMap = {}; + /** + * @type {Record>} + * Map to associate endpoint names to their configurations */ + const endpointsMap = {}; for (let i = 0; i < customEndpoints.length; i++) { const endpoint = customEndpoints[i]; const { models, name, baseURL, apiKey } = endpoint; + endpointsMap[name] = endpoint; const API_KEY = extractEnvVariable(apiKey); const BASE_URL = extractEnvVariable(baseURL); @@ -69,11 +80,9 @@ async function loadConfigModels(req) { apiKey: API_KEY, name, userIdQuery: models.userIdQuery, - }).then((result) => { - return !result?.length ? models.default ?? [] : result; }); - uniqueKeyToNameMap[uniqueKey] = uniqueKeyToNameMap[uniqueKey] || []; - uniqueKeyToNameMap[uniqueKey].push(name); + uniqueKeyToEndpointsMap[uniqueKey] = uniqueKeyToEndpointsMap[uniqueKey] || []; + uniqueKeyToEndpointsMap[uniqueKey].push(name); continue; } @@ -88,10 +97,11 @@ async function loadConfigModels(req) { for (let i = 0; i < fetchedData.length; i++) { const currentKey = uniqueKeys[i]; const modelData = fetchedData[i]; - const associatedNames = uniqueKeyToNameMap[currentKey]; + const associatedNames = uniqueKeyToEndpointsMap[currentKey]; for (const name of associatedNames) { - modelsConfig[name] = modelData; + const endpoint = endpointsMap[name]; + modelsConfig[name] = !modelData?.length ? endpoint.models.default ?? [] : modelData; } } diff --git a/api/server/services/Config/loadConfigModels.spec.js b/api/server/services/Config/loadConfigModels.spec.js index 695a59b03f..1b7dec5fd7 100644 --- a/api/server/services/Config/loadConfigModels.spec.js +++ b/api/server/services/Config/loadConfigModels.spec.js @@ -267,6 +267,15 @@ describe('loadConfigModels', () => { getCustomConfig.mockResolvedValue({ endpoints: { custom: [ + { + name: 'EndpointWithSameFetchKey', + apiKey: 'API_KEY', + baseURL: 'http://example.com', + models: { + fetch: true, + default: ['defaultModel1'], + }, + }, { name: 'EmptyFetchModel', apiKey: 'API_KEY', @@ -283,14 +292,7 @@ describe('loadConfigModels', () => { fetchModels.mockResolvedValue([]); const result = await loadConfigModels(mockRequest); - - expect(fetchModels).toHaveBeenCalledWith( - expect.objectContaining({ - name: 'EmptyFetchModel', - apiKey: 'API_KEY', - }), - ); - + expect(fetchModels).toHaveBeenCalledTimes(1); expect(result.EmptyFetchModel).toEqual(['defaultModel1', 'defaultModel2']); }); diff --git a/api/typedefs.js b/api/typedefs.js index def59971dc..24870b63ba 100644 --- a/api/typedefs.js +++ b/api/typedefs.js @@ -277,6 +277,12 @@ * @memberof typedefs */ +/** + * @exports TEndpoint + * @typedef {import('librechat-data-provider').TEndpoint} TEndpoint + * @memberof typedefs + */ + /** * @exports TEndpointsConfig * @typedef {import('librechat-data-provider').TEndpointsConfig} TEndpointsConfig diff --git a/packages/data-provider/src/config.ts b/packages/data-provider/src/config.ts index e1b9271e9b..56faa115df 100644 --- a/packages/data-provider/src/config.ts +++ b/packages/data-provider/src/config.ts @@ -150,6 +150,8 @@ export const endpointSchema = z.object({ customOrder: z.number().optional(), }); +export type TEndpoint = z.infer; + export const azureEndpointSchema = z .object({ groups: azureGroupConfigsSchema,