mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🧰 refactor: Decouple MCP Tools from System Tools (#9748)
This commit is contained in:
parent
9d2aba5df5
commit
386900fb4f
29 changed files with 1032 additions and 1195 deletions
|
|
@ -7,8 +7,8 @@ import { useUpdateUserPluginsMutation } from 'librechat-data-provider/react-quer
|
|||
import type { TError, AgentToolType } from 'librechat-data-provider';
|
||||
import type { AgentForm, TPluginStoreDialogProps } from '~/common';
|
||||
import { useLocalize, usePluginDialogHelpers, useMCPServerManager } from '~/hooks';
|
||||
import { useGetStartupConfig, useAvailableToolsQuery } from '~/data-provider';
|
||||
import CustomUserVarsSection from '~/components/MCP/CustomUserVarsSection';
|
||||
import { useGetStartupConfig, useMCPToolsQuery } from '~/data-provider';
|
||||
import { PluginPagination } from '~/components/Plugins/Store';
|
||||
import { useAgentPanelContext } from '~/Providers';
|
||||
import MCPToolItem from './MCPToolItem';
|
||||
|
|
@ -27,8 +27,8 @@ function MCPToolSelectDialog({
|
|||
const { mcpServersMap } = useAgentPanelContext();
|
||||
const { initializeServer } = useMCPServerManager();
|
||||
const { data: startupConfig } = useGetStartupConfig();
|
||||
const { refetch: refetchMCPTools } = useMCPToolsQuery();
|
||||
const { getValues, setValue } = useFormContext<AgentForm>();
|
||||
const { refetch: refetchAvailableTools } = useAvailableToolsQuery(EModelEndpoint.agents);
|
||||
|
||||
const [isInitializing, setIsInitializing] = useState<string | null>(null);
|
||||
const [configuringServer, setConfiguringServer] = useState<string | null>(null);
|
||||
|
|
@ -90,15 +90,15 @@ function MCPToolSelectDialog({
|
|||
setIsInitializing(null);
|
||||
},
|
||||
onSuccess: async () => {
|
||||
const { data: updatedAvailableTools } = await refetchAvailableTools();
|
||||
const { data: updatedMCPTools } = await refetchMCPTools();
|
||||
|
||||
const currentTools = getValues('tools') || [];
|
||||
const toolsToAdd: string[] = [
|
||||
`${Constants.mcp_server}${Constants.mcp_delimiter}${serverName}`,
|
||||
];
|
||||
|
||||
if (updatedAvailableTools) {
|
||||
updatedAvailableTools.forEach((tool) => {
|
||||
if (updatedMCPTools) {
|
||||
updatedMCPTools.forEach((tool) => {
|
||||
if (tool.pluginKey.endsWith(`${Constants.mcp_delimiter}${serverName}`)) {
|
||||
toolsToAdd.push(tool.pluginKey);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import type {
|
|||
AssistantsEndpoint,
|
||||
EModelEndpoint,
|
||||
TPluginAction,
|
||||
AgentToolType,
|
||||
TPlugin,
|
||||
TError,
|
||||
} from 'librechat-data-provider';
|
||||
import type { AgentForm, TPluginStoreDialogProps } from '~/common';
|
||||
|
|
@ -27,7 +27,8 @@ function ToolSelectDialog({
|
|||
const localize = useLocalize();
|
||||
const isAgentTools = isAgentsEndpoint(endpoint);
|
||||
const { getValues, setValue } = useFormContext<AgentForm>();
|
||||
const { groupedTools, pluginTools } = useAgentPanelContext();
|
||||
// Only use regular tools, not MCP tools
|
||||
const { regularTools } = useAgentPanelContext();
|
||||
|
||||
const {
|
||||
maxPage,
|
||||
|
|
@ -68,19 +69,8 @@ function ToolSelectDialog({
|
|||
const handleInstall = (pluginAction: TPluginAction) => {
|
||||
const addFunction = () => {
|
||||
const installedToolIds: string[] = getValues('tools') || [];
|
||||
// Add the parent
|
||||
installedToolIds.push(pluginAction.pluginKey);
|
||||
|
||||
// If this tool is a group, add subtools too
|
||||
const groupObj = groupedTools?.[pluginAction.pluginKey];
|
||||
if (groupObj?.tools && groupObj.tools.length > 0) {
|
||||
for (const sub of groupObj.tools) {
|
||||
if (!installedToolIds.includes(sub.tool_id)) {
|
||||
installedToolIds.push(sub.tool_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
setValue('tools', Array.from(new Set(installedToolIds))); // no duplicates just in case
|
||||
setValue('tools', Array.from(new Set(installedToolIds)));
|
||||
};
|
||||
|
||||
if (!pluginAction.auth) {
|
||||
|
|
@ -98,19 +88,12 @@ function ToolSelectDialog({
|
|||
};
|
||||
|
||||
const onRemoveTool = (toolId: string) => {
|
||||
const groupObj = groupedTools?.[toolId];
|
||||
const toolIdsToRemove = [toolId];
|
||||
if (groupObj?.tools && groupObj.tools.length > 0) {
|
||||
toolIdsToRemove.push(...groupObj.tools.map((sub) => sub.tool_id));
|
||||
}
|
||||
// Remove these from the formTools
|
||||
updateUserPlugins.mutate(
|
||||
{ pluginKey: toolId, action: 'uninstall', auth: {}, isEntityTool: true },
|
||||
{
|
||||
onError: (error: unknown) => handleInstallError(error as TError),
|
||||
onSuccess: () => {
|
||||
const remainingToolIds =
|
||||
getValues('tools')?.filter((toolId) => !toolIdsToRemove.includes(toolId)) || [];
|
||||
const remainingToolIds = getValues('tools')?.filter((id) => id !== toolId) || [];
|
||||
setValue('tools', remainingToolIds);
|
||||
},
|
||||
},
|
||||
|
|
@ -119,7 +102,8 @@ function ToolSelectDialog({
|
|||
|
||||
const onAddTool = (pluginKey: string) => {
|
||||
setShowPluginAuthForm(false);
|
||||
const availablePluginFromKey = pluginTools?.find((p) => p.pluginKey === pluginKey);
|
||||
// Find the tool in regularTools
|
||||
const availablePluginFromKey = regularTools?.find((p) => p.pluginKey === pluginKey);
|
||||
setSelectedPlugin(availablePluginFromKey);
|
||||
|
||||
const { authConfig, authenticated = false } = availablePluginFromKey ?? {};
|
||||
|
|
@ -134,30 +118,19 @@ function ToolSelectDialog({
|
|||
}
|
||||
};
|
||||
|
||||
const filteredTools = Object.values(groupedTools || {}).filter(
|
||||
(currentTool: AgentToolType & { tools?: AgentToolType[] }) => {
|
||||
if (currentTool.metadata?.name?.toLowerCase().includes(searchValue.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
if (currentTool.tools) {
|
||||
return currentTool.tools.some((childTool) =>
|
||||
childTool.metadata?.name?.toLowerCase().includes(searchValue.toLowerCase()),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
);
|
||||
const filteredTools = (regularTools || []).filter((tool: TPlugin) => {
|
||||
return tool.name?.toLowerCase().includes(searchValue.toLowerCase());
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (filteredTools) {
|
||||
setMaxPage(Math.ceil(Object.keys(filteredTools || {}).length / itemsPerPage));
|
||||
setMaxPage(Math.ceil(filteredTools.length / itemsPerPage));
|
||||
if (searchChanged) {
|
||||
setCurrentPage(1);
|
||||
setSearchChanged(false);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
pluginTools,
|
||||
searchValue,
|
||||
itemsPerPage,
|
||||
filteredTools,
|
||||
|
|
@ -254,10 +227,13 @@ function ToolSelectDialog({
|
|||
.map((tool, index) => (
|
||||
<ToolItem
|
||||
key={index}
|
||||
tool={tool}
|
||||
isInstalled={getValues('tools')?.includes(tool.tool_id) || false}
|
||||
onAddTool={() => onAddTool(tool.tool_id)}
|
||||
onRemoveTool={() => onRemoveTool(tool.tool_id)}
|
||||
tool={{
|
||||
tool_id: tool.pluginKey,
|
||||
metadata: tool,
|
||||
}}
|
||||
isInstalled={getValues('tools')?.includes(tool.pluginKey) || false}
|
||||
onAddTool={() => onAddTool(tool.pluginKey)}
|
||||
onRemoveTool={() => onRemoveTool(tool.pluginKey)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue