mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-22 19:30:15 +01:00
WIP: app.locals refactoring
WIP: appConfig fix: update memory configuration retrieval to use getAppConfig based on user role fix: update comment for AppConfig interface to clarify purpose
This commit is contained in:
parent
5a14ee9c6a
commit
b992fed16c
66 changed files with 706 additions and 366 deletions
110
api/server/services/Config/getAppConfig.js
Normal file
110
api/server/services/Config/getAppConfig.js
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
const { logger } = require('@librechat/data-schemas');
|
||||
const { CacheKeys } = require('librechat-data-provider');
|
||||
const getLogStores = require('~/cache/getLogStores');
|
||||
|
||||
/**
|
||||
* @typedef {Object} AppConfig
|
||||
* @property {import('librechat-data-provider').TCustomConfig} config - The main custom configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['ocr']} ocr - OCR configuration
|
||||
* @property {Object} paths - File paths configuration
|
||||
* @property {import('librechat-data-provider').TMemoryConfig | undefined} memory - Memory configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['webSearch']} webSearch - Web search configuration
|
||||
* @property {string} fileStrategy - File storage strategy ('local', 's3', 'firebase', 'azure_blob')
|
||||
* @property {Array} socialLogins - Social login configurations
|
||||
* @property {string[]} [filteredTools] - Admin-filtered tools
|
||||
* @property {string[]} [includedTools] - Admin-included tools
|
||||
* @property {string} imageOutputType - Image output type configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['interface']} interfaceConfig - Interface configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['registration']} turnstileConfig - Turnstile configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['balance']} balance - Balance configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['mcpServers'] | null} mcpConfig - MCP server configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['fileConfig']} [fileConfig] - File configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['secureImageLinks']} [secureImageLinks] - Secure image links configuration
|
||||
* @property {import('librechat-data-provider').TCustomConfig['modelSpecs'] | undefined} [modelSpecs] - Processed model specifications
|
||||
* @property {import('librechat-data-provider').TEndpoint} [openAI] - OpenAI endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [google] - Google endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [bedrock] - Bedrock endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [anthropic] - Anthropic endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [gptPlugins] - GPT plugins endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [azureOpenAI] - Azure OpenAI endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [assistants] - Assistants endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [azureAssistants] - Azure assistants endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [agents] - Agents endpoint configuration
|
||||
* @property {import('librechat-data-provider').TEndpoint} [all] - Global endpoint configuration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the app configuration based on user context
|
||||
* @param {Object} [options]
|
||||
* @param {string} [options.role] - User role for role-based config
|
||||
* @param {boolean} [options.refresh] - Force refresh the cache
|
||||
* @returns {Promise<AppConfig>}
|
||||
*/
|
||||
async function getAppConfig(options = {}) {
|
||||
const { role, refresh } = options;
|
||||
|
||||
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
||||
const cacheKey = role ? `${CacheKeys.APP_CONFIG}:${role}` : CacheKeys.APP_CONFIG;
|
||||
|
||||
if (!refresh) {
|
||||
const cached = await cache.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
const baseConfig = await cache.get(CacheKeys.APP_CONFIG);
|
||||
if (!baseConfig) {
|
||||
throw new Error('App configuration not initialized. Please ensure AppService has been called.');
|
||||
}
|
||||
|
||||
// For now, return the base config
|
||||
// In the future, this is where we'll apply role-based modifications
|
||||
if (role) {
|
||||
// TODO: Apply role-based config modifications
|
||||
// const roleConfig = await applyRoleBasedConfig(baseConfig, role);
|
||||
// await cache.set(cacheKey, roleConfig);
|
||||
// return roleConfig;
|
||||
}
|
||||
|
||||
return baseConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache the app configuration
|
||||
* @param {AppConfig} config - The configuration to cache
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function cacheAppConfig(config) {
|
||||
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
||||
await cache.set(CacheKeys.APP_CONFIG, config);
|
||||
logger.debug('[getAppConfig] App configuration cached');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the app configuration cache
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async function clearAppConfigCache() {
|
||||
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
||||
const cacheKey = CacheKeys.APP_CONFIG;
|
||||
return await cache.delete(cacheKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the app configuration during startup
|
||||
* @param {AppConfig} config - The initial configuration to store
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function initializeAppConfig(config) {
|
||||
const cache = getLogStores(CacheKeys.CONFIG_STORE);
|
||||
await cache.set(CacheKeys.APP_CONFIG, config);
|
||||
logger.debug('[getAppConfig] App configuration initialized');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getAppConfig,
|
||||
cacheAppConfig,
|
||||
clearAppConfigCache,
|
||||
initializeAppConfig,
|
||||
};
|
||||
|
|
@ -8,6 +8,7 @@ const {
|
|||
const loadDefaultEndpointsConfig = require('./loadDefaultEConfig');
|
||||
const loadConfigEndpoints = require('./loadConfigEndpoints');
|
||||
const getLogStores = require('~/cache/getLogStores');
|
||||
const { getAppConfig } = require('./getAppConfig');
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -23,12 +24,13 @@ async function getEndpointsConfig(req) {
|
|||
|
||||
const defaultEndpointsConfig = await loadDefaultEndpointsConfig(req);
|
||||
const customConfigEndpoints = await loadConfigEndpoints(req);
|
||||
const appConfig = await getAppConfig({ role: req.user?.role });
|
||||
|
||||
/** @type {TEndpointsConfig} */
|
||||
const mergedConfig = { ...defaultEndpointsConfig, ...customConfigEndpoints };
|
||||
if (mergedConfig[EModelEndpoint.assistants] && req.app.locals?.[EModelEndpoint.assistants]) {
|
||||
if (mergedConfig[EModelEndpoint.assistants] && appConfig?.[EModelEndpoint.assistants]) {
|
||||
const { disableBuilder, retrievalModels, capabilities, version, ..._rest } =
|
||||
req.app.locals[EModelEndpoint.assistants];
|
||||
appConfig[EModelEndpoint.assistants];
|
||||
|
||||
mergedConfig[EModelEndpoint.assistants] = {
|
||||
...mergedConfig[EModelEndpoint.assistants],
|
||||
|
|
@ -38,9 +40,9 @@ async function getEndpointsConfig(req) {
|
|||
capabilities,
|
||||
};
|
||||
}
|
||||
if (mergedConfig[EModelEndpoint.agents] && req.app.locals?.[EModelEndpoint.agents]) {
|
||||
if (mergedConfig[EModelEndpoint.agents] && appConfig?.[EModelEndpoint.agents]) {
|
||||
const { disableBuilder, capabilities, allowedProviders, ..._rest } =
|
||||
req.app.locals[EModelEndpoint.agents];
|
||||
appConfig[EModelEndpoint.agents];
|
||||
|
||||
mergedConfig[EModelEndpoint.agents] = {
|
||||
...mergedConfig[EModelEndpoint.agents],
|
||||
|
|
@ -50,12 +52,9 @@ async function getEndpointsConfig(req) {
|
|||
};
|
||||
}
|
||||
|
||||
if (
|
||||
mergedConfig[EModelEndpoint.azureAssistants] &&
|
||||
req.app.locals?.[EModelEndpoint.azureAssistants]
|
||||
) {
|
||||
if (mergedConfig[EModelEndpoint.azureAssistants] && appConfig?.[EModelEndpoint.azureAssistants]) {
|
||||
const { disableBuilder, retrievalModels, capabilities, version, ..._rest } =
|
||||
req.app.locals[EModelEndpoint.azureAssistants];
|
||||
appConfig[EModelEndpoint.azureAssistants];
|
||||
|
||||
mergedConfig[EModelEndpoint.azureAssistants] = {
|
||||
...mergedConfig[EModelEndpoint.azureAssistants],
|
||||
|
|
@ -66,8 +65,8 @@ async function getEndpointsConfig(req) {
|
|||
};
|
||||
}
|
||||
|
||||
if (mergedConfig[EModelEndpoint.bedrock] && req.app.locals?.[EModelEndpoint.bedrock]) {
|
||||
const { availableRegions } = req.app.locals[EModelEndpoint.bedrock];
|
||||
if (mergedConfig[EModelEndpoint.bedrock] && appConfig?.[EModelEndpoint.bedrock]) {
|
||||
const { availableRegions } = appConfig[EModelEndpoint.bedrock];
|
||||
mergedConfig[EModelEndpoint.bedrock] = {
|
||||
...mergedConfig[EModelEndpoint.bedrock],
|
||||
availableRegions,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const getAppConfig = require('./getAppConfig');
|
||||
const { config } = require('./EndpointService');
|
||||
const getCachedTools = require('./getCachedTools');
|
||||
const getCustomConfig = require('./getCustomConfig');
|
||||
|
|
@ -15,6 +16,7 @@ module.exports = {
|
|||
loadDefaultModels,
|
||||
loadOverrideConfig,
|
||||
loadAsyncEndpoints,
|
||||
...getAppConfig,
|
||||
...getCachedTools,
|
||||
...getCustomConfig,
|
||||
...getEndpointsConfig,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const path = require('path');
|
|||
const { logger } = require('@librechat/data-schemas');
|
||||
const { loadServiceKey, isUserProvided } = require('@librechat/api');
|
||||
const { EModelEndpoint } = require('librechat-data-provider');
|
||||
const { getAppConfig } = require('./getAppConfig');
|
||||
const { config } = require('./EndpointService');
|
||||
|
||||
const { openAIApiKey, azureOpenAIApiKey, useAzurePlugins, userProvidedOpenAI, googleKey } = config;
|
||||
|
|
@ -11,6 +12,7 @@ const { openAIApiKey, azureOpenAIApiKey, useAzurePlugins, userProvidedOpenAI, go
|
|||
* @param {Express.Request} req - The request object
|
||||
*/
|
||||
async function loadAsyncEndpoints(req) {
|
||||
const appConfig = await getAppConfig({ role: req.user?.role });
|
||||
let serviceKey, googleUserProvides;
|
||||
|
||||
/** Check if GOOGLE_KEY is provided at all(including 'user_provided') */
|
||||
|
|
@ -34,7 +36,7 @@ async function loadAsyncEndpoints(req) {
|
|||
|
||||
const google = serviceKey || isGoogleKeyProvided ? { userProvide: googleUserProvides } : false;
|
||||
|
||||
const useAzure = req.app.locals[EModelEndpoint.azureOpenAI]?.plugins;
|
||||
const useAzure = appConfig[EModelEndpoint.azureOpenAI]?.plugins;
|
||||
const gptPlugins =
|
||||
useAzure || openAIApiKey || azureOpenAIApiKey
|
||||
? {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const { EModelEndpoint, extractEnvVariable } = require('librechat-data-provider');
|
||||
const { isUserProvided, normalizeEndpointName } = require('~/server/utils');
|
||||
const { getCustomConfig } = require('./getCustomConfig');
|
||||
const { getAppConfig } = require('./getAppConfig');
|
||||
|
||||
/**
|
||||
* Load config endpoints from the cached configuration object
|
||||
|
|
@ -14,6 +15,8 @@ async function loadConfigEndpoints(req) {
|
|||
return {};
|
||||
}
|
||||
|
||||
const appConfig = await getAppConfig({ role: req.user?.role });
|
||||
|
||||
const { endpoints = {} } = customConfig ?? {};
|
||||
const endpointsConfig = {};
|
||||
|
||||
|
|
@ -53,14 +56,14 @@ async function loadConfigEndpoints(req) {
|
|||
}
|
||||
}
|
||||
|
||||
if (req.app.locals[EModelEndpoint.azureOpenAI]) {
|
||||
if (appConfig[EModelEndpoint.azureOpenAI]) {
|
||||
/** @type {Omit<TConfig, 'order'>} */
|
||||
endpointsConfig[EModelEndpoint.azureOpenAI] = {
|
||||
userProvide: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (req.app.locals[EModelEndpoint.azureOpenAI]?.assistants) {
|
||||
if (appConfig[EModelEndpoint.azureOpenAI]?.assistants) {
|
||||
/** @type {Omit<TConfig, 'order'>} */
|
||||
endpointsConfig[EModelEndpoint.azureAssistants] = {
|
||||
userProvide: false,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const { EModelEndpoint, extractEnvVariable } = require('librechat-data-provider'
|
|||
const { isUserProvided, normalizeEndpointName } = require('~/server/utils');
|
||||
const { fetchModels } = require('~/server/services/ModelService');
|
||||
const { getCustomConfig } = require('./getCustomConfig');
|
||||
const { getAppConfig } = require('./getAppConfig');
|
||||
|
||||
/**
|
||||
* Load config endpoints from the cached configuration object
|
||||
|
|
@ -15,10 +16,11 @@ async function loadConfigModels(req) {
|
|||
return {};
|
||||
}
|
||||
|
||||
const appConfig = await getAppConfig({ role: req.user?.role });
|
||||
const { endpoints = {} } = customConfig ?? {};
|
||||
const modelsConfig = {};
|
||||
const azureEndpoint = endpoints[EModelEndpoint.azureOpenAI];
|
||||
const azureConfig = req.app.locals[EModelEndpoint.azureOpenAI];
|
||||
const azureConfig = appConfig[EModelEndpoint.azureOpenAI];
|
||||
const { modelNames } = azureConfig ?? {};
|
||||
|
||||
if (modelNames && azureEndpoint) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue