feat: enhance BadgeRowContext with MCPSelect and tool toggle functionality, refactor related components to utilize updated context and hooks

This commit is contained in:
Danny Avila 2025-06-21 23:53:32 -04:00
parent 5ba51d99fe
commit 01625b1b4a
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
6 changed files with 113 additions and 94 deletions

View file

@ -1,6 +1,8 @@
import { useRef, useEffect, useCallback, useMemo } from 'react';
import { useRecoilState } from 'recoil';
import { Constants, LocalStorageKeys } from 'librechat-data-provider';
import { Constants, LocalStorageKeys, EModelEndpoint } from 'librechat-data-provider';
import type { TPlugin, TPluginAuthConfig } from 'librechat-data-provider';
import { useAvailableToolsQuery } from '~/data-provider';
import useLocalStorage from '~/hooks/useLocalStorageAlt';
import { ephemeralAgentByConvoId } from '~/store';
@ -20,14 +22,40 @@ const storageCondition = (value: unknown, rawCurrentValue?: string | null) => {
interface UseMCPSelectOptions {
conversationId?: string | null;
mcpToolDetails?: Array<{ name: string }> | null;
isFetched: boolean;
}
export function useMCPSelect({ conversationId, mcpToolDetails, isFetched }: UseMCPSelectOptions) {
export interface McpServerInfo {
name: string;
pluginKey: string;
authConfig?: TPluginAuthConfig[];
authenticated?: boolean;
}
export function useMCPSelect({ conversationId }: UseMCPSelectOptions) {
const key = conversationId ?? Constants.NEW_CONVO;
const hasSetFetched = useRef<string | null>(null);
const [ephemeralAgent, setEphemeralAgent] = useRecoilState(ephemeralAgentByConvoId(key));
const { data: mcpToolDetails, isFetched } = useAvailableToolsQuery(EModelEndpoint.agents, {
select: (data: TPlugin[]) => {
const mcpToolsMap = new Map<string, McpServerInfo>();
data.forEach((tool) => {
const isMCP = tool.pluginKey.includes(Constants.mcp_delimiter);
if (isMCP && tool.chatMenu !== false) {
const parts = tool.pluginKey.split(Constants.mcp_delimiter);
const serverName = parts[parts.length - 1];
if (!mcpToolsMap.has(serverName)) {
mcpToolsMap.set(serverName, {
name: serverName,
pluginKey: tool.pluginKey,
authConfig: tool.authConfig,
authenticated: tool.authenticated,
});
}
}
});
return Array.from(mcpToolsMap.values());
},
});
const mcpState = useMemo(() => {
return ephemeralAgent?.mcp ?? [];
@ -80,6 +108,7 @@ export function useMCPSelect({ conversationId, mcpToolDetails, isFetched }: UseM
setMCPValues,
mcpServerNames,
ephemeralAgent,
mcpToolDetails,
setEphemeralAgent,
};
}

View file

@ -2,6 +2,9 @@ import { useRef, useEffect, useCallback, useMemo } from 'react';
import { useRecoilState } from 'recoil';
import debounce from 'lodash/debounce';
import { Constants, LocalStorageKeys } from 'librechat-data-provider';
import type { VerifyToolAuthResponse } from 'librechat-data-provider';
import type { UseQueryOptions } from '@tanstack/react-query';
import { useVerifyAgentToolAuth } from '~/data-provider';
import useLocalStorage from '~/hooks/useLocalStorageAlt';
import { ephemeralAgentByConvoId } from '~/store';
@ -25,18 +28,35 @@ interface UseToolToggleOptions {
localStorageKey: LocalStorageKeys;
isAuthenticated?: boolean;
setIsDialogOpen?: (open: boolean) => void;
/** Options for auth verification */
authConfig?: {
toolId: string;
queryOptions?: UseQueryOptions<VerifyToolAuthResponse>;
};
}
export function useToolToggle({
conversationId,
toolKey,
localStorageKey,
isAuthenticated,
isAuthenticated: externalIsAuthenticated,
setIsDialogOpen,
authConfig,
}: UseToolToggleOptions) {
const key = conversationId ?? Constants.NEW_CONVO;
const [ephemeralAgent, setEphemeralAgent] = useRecoilState(ephemeralAgentByConvoId(key));
const authQuery = useVerifyAgentToolAuth(
{ toolId: authConfig?.toolId || '' },
{
enabled: !!authConfig?.toolId,
...authConfig?.queryOptions,
},
);
const isAuthenticated =
externalIsAuthenticated ?? (authConfig ? (authQuery?.data?.authenticated ?? false) : false);
const isToolEnabled = useMemo(() => {
return ephemeralAgent?.[toolKey] ?? false;
}, [ephemeralAgent, toolKey]);
@ -93,5 +113,6 @@ export function useToolToggle({
ephemeralAgent,
debouncedChange,
setEphemeralAgent,
authData: authQuery?.data,
};
}