const { CacheKeys } = require('librechat-data-provider'); const { AppService, logger } = require('@librechat/data-schemas'); const { createAppConfigService, clearMcpConfigCache } = require('@librechat/api'); const { setCachedTools, invalidateCachedTools } = require('./getCachedTools'); const { loadAndFormatTools } = require('~/server/services/start/tools'); const loadCustomConfig = require('./loadCustomConfig'); const getLogStores = require('~/cache/getLogStores'); const paths = require('~/config/paths'); const db = require('~/models'); const loadBaseConfig = async () => { /** @type {TCustomConfig} */ const config = (await loadCustomConfig()) ?? {}; /** @type {Record} */ const systemTools = loadAndFormatTools({ adminFilter: config.filteredTools, adminIncluded: config.includedTools, directory: paths.structuredTools, }); return AppService({ config, paths, systemTools }); }; const { getAppConfig, clearAppConfigCache, clearOverrideCache } = createAppConfigService({ loadBaseConfig, setCachedTools, getCache: getLogStores, cacheKeys: CacheKeys, getApplicableConfigs: db.getApplicableConfigs, getUserPrincipals: db.getUserPrincipals, }); /** * Invalidate all config-related caches after an admin config mutation. * Clears the base config, per-principal override caches, tool caches, * and the MCP config-source server cache. * @param {string} [tenantId] - Optional tenant ID to scope override cache clearing. */ async function invalidateConfigCaches(tenantId) { const results = await Promise.allSettled([ clearAppConfigCache(), clearOverrideCache(tenantId), invalidateCachedTools({ invalidateGlobal: true }), clearMcpConfigCache(), ]); const labels = [ 'clearAppConfigCache', 'clearOverrideCache', 'invalidateCachedTools', 'clearMcpConfigCache', ]; for (let i = 0; i < results.length; i++) { if (results[i].status === 'rejected') { logger.error(`[invalidateConfigCaches] ${labels[i]} failed:`, results[i].reason); } } } module.exports = { getAppConfig, clearAppConfigCache, invalidateConfigCaches, };