diff --git a/api/server/controllers/agents/client.js b/api/server/controllers/agents/client.js index 97699e9248..8708e2f8bc 100644 --- a/api/server/controllers/agents/client.js +++ b/api/server/controllers/agents/client.js @@ -1,5 +1,7 @@ require('events').EventEmitter.defaultMaxListeners = 100; const { logger } = require('@librechat/data-schemas'); +const { DynamicStructuredTool } = require('@langchain/core/tools'); +const { getBufferString, HumanMessage } = require('@langchain/core/messages'); const { sendEvent, createRun, @@ -31,13 +33,16 @@ const { bedrockInputSchema, removeNullishValues, } = require('librechat-data-provider'); -const { DynamicStructuredTool } = require('@langchain/core/tools'); -const { getBufferString, HumanMessage } = require('@langchain/core/messages'); -const { createGetMCPAuthMap, checkCapability } = require('~/server/services/Config'); +const { + findPluginAuthsByKeys, + getFormattedMemories, + deleteMemory, + setMemory, +} = require('~/models'); +const { getMCPAuthMap, checkCapability, hasCustomUserVars } = require('~/server/services/Config'); const { addCacheControl, createContextHandlers } = require('~/app/clients/prompts'); const { initializeAgent } = require('~/server/services/Endpoints/agents/agent'); const { spendTokens, spendStructuredTokens } = require('~/models/spendTokens'); -const { getFormattedMemories, deleteMemory, setMemory } = require('~/models'); const { encodeAndFormat } = require('~/server/services/Files/images/encode'); const { getProviderConfig } = require('~/server/services/Endpoints'); const BaseClient = require('~/app/clients/BaseClient'); @@ -701,8 +706,6 @@ class AgentClient extends BaseClient { version: 'v2', }; - const getUserMCPAuthMap = await createGetMCPAuthMap(); - const toolSet = new Set((this.options.agent.tools ?? []).map((tool) => tool && tool.name)); let { messages: initialMessages, indexTokenCountMap } = formatAgentMessages( payload, @@ -823,10 +826,11 @@ class AgentClient extends BaseClient { } try { - if (getUserMCPAuthMap) { - config.configurable.userMCPAuthMap = await getUserMCPAuthMap({ + if (await hasCustomUserVars()) { + config.configurable.userMCPAuthMap = await getMCPAuthMap({ tools: agent.tools, userId: this.options.req.user.id, + findPluginAuthsByKeys, }); } } catch (err) { diff --git a/api/server/services/Config/getCustomConfig.js b/api/server/services/Config/getCustomConfig.js index f3fb6f26b4..7495ce1e2a 100644 --- a/api/server/services/Config/getCustomConfig.js +++ b/api/server/services/Config/getCustomConfig.js @@ -1,10 +1,9 @@ const { logger } = require('@librechat/data-schemas'); -const { getUserMCPAuthMap } = require('@librechat/api'); +const { isEnabled, getUserMCPAuthMap } = require('@librechat/api'); const { CacheKeys, EModelEndpoint } = require('librechat-data-provider'); -const { normalizeEndpointName, isEnabled } = require('~/server/utils'); +const { normalizeEndpointName } = require('~/server/utils'); const loadCustomConfig = require('./loadCustomConfig'); const { getCachedTools } = require('./getCachedTools'); -const { findPluginAuthsByKeys } = require('~/models'); const getLogStores = require('~/cache/getLogStores'); /** @@ -55,46 +54,48 @@ const getCustomEndpointConfig = async (endpoint) => { ); }; -async function createGetMCPAuthMap() { +/** + * @param {Object} params + * @param {string} params.userId + * @param {GenericTool[]} [params.tools] + * @param {import('@librechat/data-schemas').PluginAuthMethods['findPluginAuthsByKeys']} params.findPluginAuthsByKeys + * @returns {Promise> | undefined>} + */ +async function getMCPAuthMap({ userId, tools, findPluginAuthsByKeys }) { + try { + if (!tools || tools.length === 0) { + return; + } + const appTools = await getCachedTools({ + userId, + }); + return await getUserMCPAuthMap({ + tools, + userId, + appTools, + findPluginAuthsByKeys, + }); + } catch (err) { + logger.error( + `[api/server/controllers/agents/client.js #chatCompletion] Error getting custom user vars for agent`, + err, + ); + } +} + +/** + * @returns {Promise} + */ +async function hasCustomUserVars() { const customConfig = await getCustomConfig(); const mcpServers = customConfig?.mcpServers; - const hasCustomUserVars = Object.values(mcpServers ?? {}).some((server) => server.customUserVars); - if (!hasCustomUserVars) { - return; - } - - /** - * @param {Object} params - * @param {GenericTool[]} [params.tools] - * @param {string} params.userId - * @returns {Promise> | undefined>} - */ - return async function ({ tools, userId }) { - try { - if (!tools || tools.length === 0) { - return; - } - const appTools = await getCachedTools({ - userId, - }); - return await getUserMCPAuthMap({ - tools, - userId, - appTools, - findPluginAuthsByKeys, - }); - } catch (err) { - logger.error( - `[api/server/controllers/agents/client.js #chatCompletion] Error getting custom user vars for agent`, - err, - ); - } - }; + return Object.values(mcpServers ?? {}).some((server) => server.customUserVars); } module.exports = { + getMCPAuthMap, getCustomConfig, getBalanceConfig, - createGetMCPAuthMap, + hasCustomUserVars, getCustomEndpointConfig, }; diff --git a/packages/api/src/agents/auth.ts b/packages/api/src/agents/auth.ts index 564ef84b5a..a5fc882660 100644 --- a/packages/api/src/agents/auth.ts +++ b/packages/api/src/agents/auth.ts @@ -76,6 +76,11 @@ export async function getPluginAuthMap({ await Promise.all(decryptionPromises); return authMap; } catch (error) { + const message = error instanceof Error ? error.message : 'Unknown error'; + const plugins = pluginKeys?.join(', ') ?? 'all requested'; + logger.warn( + `[getPluginAuthMap] Failed to fetch auth values for userId ${userId}, plugins: ${plugins}: ${message}`, + ); if (!throwError) { /** Empty objects for each plugin key on error */ return pluginKeys.reduce((acc, key) => { @@ -83,11 +88,6 @@ export async function getPluginAuthMap({ return acc; }, {} as PluginAuthMap); } - - const message = error instanceof Error ? error.message : 'Unknown error'; - logger.error( - `[getPluginAuthMap] Failed to fetch auth values for userId ${userId}, plugins: ${pluginKeys.join(', ')}: ${message}`, - ); throw error; } }