📛 refactor: Decouple MCP Dialog UI from BadgeRowContext (#8920)

* decouple MCP dialog from BadgeRowContext

* chore: import order and style according to guidelines

---------

Co-authored-by: Dustin Healy <dustinhealy1@gmail.com>
This commit is contained in:
Federico Ruggi 2025-08-18 17:20:45 +02:00 committed by GitHub
parent a6fd32a15a
commit 2a0a8f6beb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 18 additions and 29 deletions

View file

@ -2,27 +2,18 @@ import React, { createContext, useContext, useEffect, useRef } from 'react';
import { useSetRecoilState } from 'recoil';
import { Tools, Constants, LocalStorageKeys, AgentCapabilities } from 'librechat-data-provider';
import type { TAgentsEndpoint } from 'librechat-data-provider';
import {
useSearchApiKeyForm,
useGetAgentsConfig,
useCodeApiKeyForm,
useToolToggle,
useMCPSelect,
} from '~/hooks';
import { useGetStartupConfig } from '~/data-provider';
import { useSearchApiKeyForm, useGetAgentsConfig, useCodeApiKeyForm, useToolToggle } from '~/hooks';
import { ephemeralAgentByConvoId } from '~/store';
interface BadgeRowContextType {
conversationId?: string | null;
agentsConfig?: TAgentsEndpoint | null;
mcpSelect: ReturnType<typeof useMCPSelect>;
webSearch: ReturnType<typeof useToolToggle>;
artifacts: ReturnType<typeof useToolToggle>;
fileSearch: ReturnType<typeof useToolToggle>;
codeInterpreter: ReturnType<typeof useToolToggle>;
codeApiKeyForm: ReturnType<typeof useCodeApiKeyForm>;
searchApiKeyForm: ReturnType<typeof useSearchApiKeyForm>;
startupConfig: ReturnType<typeof useGetStartupConfig>['data'];
}
const BadgeRowContext = createContext<BadgeRowContextType | undefined>(undefined);
@ -119,12 +110,6 @@ export default function BadgeRowProvider({
}
}, [key, isSubmitting, setEphemeralAgent]);
/** Startup config */
const { data: startupConfig } = useGetStartupConfig();
/** MCPSelect hook */
const mcpSelect = useMCPSelect({ conversationId });
/** CodeInterpreter hooks */
const codeApiKeyForm = useCodeApiKeyForm({});
const { setIsDialogOpen: setCodeDialogOpen } = codeApiKeyForm;
@ -172,12 +157,10 @@ export default function BadgeRowProvider({
});
const value: BadgeRowContextType = {
mcpSelect,
webSearch,
artifacts,
fileSearch,
agentsConfig,
startupConfig,
conversationId,
codeApiKeyForm,
codeInterpreter,

View file

@ -10,11 +10,12 @@ import {
PermissionTypes,
defaultAgentCapabilities,
} from 'librechat-data-provider';
import { useLocalize, useHasAccess, useAgentCapabilities } from '~/hooks';
import { useLocalize, useHasAccess, useAgentCapabilities, useMCPSelect } from '~/hooks';
import ArtifactsSubMenu from '~/components/Chat/Input/ArtifactsSubMenu';
import MCPSubMenu from '~/components/Chat/Input/MCPSubMenu';
import { useBadgeRowContext } from '~/Providers';
import { cn } from '~/utils';
import { useGetStartupConfig } from '~/data-provider';
interface ToolsDropdownProps {
disabled?: boolean;
@ -26,15 +27,16 @@ const ToolsDropdown = ({ disabled }: ToolsDropdownProps) => {
const [isPopoverActive, setIsPopoverActive] = useState(false);
const {
webSearch,
mcpSelect,
artifacts,
fileSearch,
agentsConfig,
startupConfig,
codeApiKeyForm,
codeInterpreter,
searchApiKeyForm,
} = useBadgeRowContext();
const mcpSelect = useMCPSelect();
const { data: startupConfig } = useGetStartupConfig();
const { codeEnabled, webSearchEnabled, artifactsEnabled, fileSearchEnabled } =
useAgentCapabilities(agentsConfig?.capabilities ?? defaultAgentCapabilities);

View file

@ -10,8 +10,8 @@ import {
import type { TUpdateUserPlugins, TPlugin } from 'librechat-data-provider';
import type { ConfigFieldDetail } from '~/components/MCP/MCPConfigDialog';
import { useMCPConnectionStatusQuery } from '~/data-provider/Tools/queries';
import { useBadgeRowContext } from '~/Providers';
import { useLocalize } from '~/hooks';
import { useGetStartupConfig } from '~/data-provider';
import { useLocalize, useMCPSelect } from '~/hooks';
interface ServerState {
isInitializing: boolean;
@ -24,7 +24,8 @@ interface ServerState {
export function useMCPServerManager() {
const localize = useLocalize();
const { showToast } = useToastContext();
const { mcpSelect, startupConfig } = useBadgeRowContext();
const mcpSelect = useMCPSelect();
const { data: startupConfig } = useGetStartupConfig();
const { mcpValues, setMCPValues, mcpToolDetails, isPinned, setIsPinned } = mcpSelect;
const queryClient = useQueryClient();

View file

@ -5,6 +5,7 @@ import type { TPlugin } from 'librechat-data-provider';
import { useAvailableToolsQuery, useGetStartupConfig } from '~/data-provider';
import useLocalStorage from '~/hooks/useLocalStorageAlt';
import { ephemeralAgentByConvoId } from '~/store';
import { useChatContext } from '~/Providers';
const storageCondition = (value: unknown, rawCurrentValue?: string | null) => {
if (rawCurrentValue) {
@ -20,12 +21,14 @@ const storageCondition = (value: unknown, rawCurrentValue?: string | null) => {
return Array.isArray(value) && value.length > 0;
};
interface UseMCPSelectOptions {
conversationId?: string | null;
}
export function useMCPSelect() {
const { conversation } = useChatContext();
const key = useMemo(
() => conversation?.conversationId ?? Constants.NEW_CONVO,
[conversation?.conversationId],
);
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: startupConfig } = useGetStartupConfig();