Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/just-cameron/letta-libre. A fork of libre chat for Letta.
Something went wrong. Try again.
4.9 kB · 129 lines
JavaScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130const { logger } = require('@librechat/data-schemas');const { CacheKeys } = require('librechat-data-provider');const { getToolkitKey, checkPluginAuth, filterUniquePlugins } = require('@librechat/api');const { getCachedTools, setCachedTools } = require('~/server/services/Config');const { availableTools, toolkits } = require('~/app/clients/tools');const { getAppConfig } = require('~/server/services/Config');const { getLogStores } = require('~/cache');
const getAvailablePluginsController = async (req, res) => { try { const cache = getLogStores(CacheKeys.CONFIG_STORE); const cachedPlugins = await cache.get(CacheKeys.PLUGINS); if (cachedPlugins) { res.status(200).json(cachedPlugins); return; }
const appConfig = await getAppConfig({ role: req.user?.role }); /** @type {{ filteredTools: string[], includedTools: string[] }} */ const { filteredTools = [], includedTools = [] } = appConfig; /** @type {import('@librechat/api').LCManifestTool[]} */ const pluginManifest = availableTools;
const uniquePlugins = filterUniquePlugins(pluginManifest); let authenticatedPlugins = []; for (const plugin of uniquePlugins) { authenticatedPlugins.push( checkPluginAuth(plugin) ? { ...plugin, authenticated: true } : plugin, ); }
let plugins = authenticatedPlugins;
if (includedTools.length > 0) { plugins = plugins.filter((plugin) => includedTools.includes(plugin.pluginKey)); } else { plugins = plugins.filter((plugin) => !filteredTools.includes(plugin.pluginKey)); }
await cache.set(CacheKeys.PLUGINS, plugins); res.status(200).json(plugins); } catch (error) { res.status(500).json({ message: error.message }); }};
/** * Retrieves and returns a list of available tools, either from a cache or by reading a plugin manifest file. * * This function first attempts to retrieve the list of tools from a cache. If the tools are not found in the cache, * it reads a plugin manifest file, filters for unique plugins, and determines if each plugin is authenticated. * Only plugins that are marked as available in the application's local state are included in the final list. * The resulting list of tools is then cached and sent to the client. * * @param {object} req - The request object, containing information about the HTTP request. * @param {object} res - The response object, used to send back the desired HTTP response. * @returns {Promise<void>} A promise that resolves when the function has completed. */const getAvailableTools = async (req, res) => { try { const userId = req.user?.id; if (!userId) { logger.warn('[getAvailableTools] User ID not found in request'); return res.status(401).json({ message: 'Unauthorized' }); } const cache = getLogStores(CacheKeys.CONFIG_STORE); const cachedToolsArray = await cache.get(CacheKeys.TOOLS);
const appConfig = req.config ?? (await getAppConfig({ role: req.user?.role }));
// Return early if we have cached tools if (cachedToolsArray != null) { res.status(200).json(cachedToolsArray); return; }
/** @type {Record<string, FunctionTool> | null} Get tool definitions to filter which tools are actually available */ let toolDefinitions = await getCachedTools();
if (toolDefinitions == null && appConfig?.availableTools != null) { logger.warn('[getAvailableTools] Tool cache was empty, re-initializing from app config'); await setCachedTools(appConfig.availableTools); toolDefinitions = appConfig.availableTools; }
/** @type {import('@librechat/api').LCManifestTool[]} */ let pluginManifest = availableTools;
/** @type {TPlugin[]} Deduplicate and authenticate plugins */ const uniquePlugins = filterUniquePlugins(pluginManifest); const authenticatedPlugins = uniquePlugins.map((plugin) => { if (checkPluginAuth(plugin)) { return { ...plugin, authenticated: true }; } else { return plugin; } });
/** Filter plugins based on availability */ const toolsOutput = []; for (const plugin of authenticatedPlugins) { const isToolDefined = toolDefinitions?.[plugin.pluginKey] !== undefined; const isToolkit = plugin.toolkit === true && Object.keys(toolDefinitions ?? {}).some( (key) => getToolkitKey({ toolkits, toolName: key }) === plugin.pluginKey, );
if (!isToolDefined && !isToolkit) { continue; }
toolsOutput.push(plugin); }
const finalTools = filterUniquePlugins(toolsOutput); await cache.set(CacheKeys.TOOLS, finalTools);
res.status(200).json(finalTools); } catch (error) { logger.error('[getAvailableTools]', error); res.status(500).json({ message: error.message }); }};
module.exports = { getAvailableTools, getAvailablePluginsController,};