mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Delete MCP server #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -106,8 +106,8 @@ export const useDeleteMcpServer = () => {
|
|||||||
mutateAsync,
|
mutateAsync,
|
||||||
} = useMutation({
|
} = useMutation({
|
||||||
mutationKey: [McpApiAction.DeleteMcpServer],
|
mutationKey: [McpApiAction.DeleteMcpServer],
|
||||||
mutationFn: async (params: Record<string, any>) => {
|
mutationFn: async (ids: string[]) => {
|
||||||
const { data = {} } = await mcpServerService.delete(params);
|
const { data = {} } = await mcpServerService.delete({ mcp_ids: ids });
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
message.success(i18n.t(`message.deleted`));
|
message.success(i18n.t(`message.deleted`));
|
||||||
|
|
||||||
|
|||||||
@ -685,6 +685,7 @@ export const initialWaitingDialogueValues = {};
|
|||||||
export const initialAgentValues = {
|
export const initialAgentValues = {
|
||||||
...initialLlmBaseValues,
|
...initialLlmBaseValues,
|
||||||
description: '',
|
description: '',
|
||||||
|
user_prompt: '',
|
||||||
sys_prompt: ``,
|
sys_prompt: ``,
|
||||||
prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }],
|
prompts: [{ role: PromptRole.User, content: `{${AgentGlobals.SysQuery}}` }],
|
||||||
message_history_window_size: 12,
|
message_history_window_size: 12,
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
} from '@/components/ui/form';
|
} from '@/components/ui/form';
|
||||||
import { Input, NumberInput } from '@/components/ui/input';
|
import { Input, NumberInput } from '@/components/ui/input';
|
||||||
import { RAGFlowSelect } from '@/components/ui/select';
|
import { RAGFlowSelect } from '@/components/ui/select';
|
||||||
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
@ -39,6 +40,7 @@ const exceptionMethodOptions = buildOptions(AgentExceptionMethod);
|
|||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
sys_prompt: z.string(),
|
sys_prompt: z.string(),
|
||||||
description: z.string().optional(),
|
description: z.string().optional(),
|
||||||
|
user_prompt: z.string().optional(),
|
||||||
prompts: z.string().optional(),
|
prompts: z.string().optional(),
|
||||||
// prompts: z
|
// prompts: z
|
||||||
// .array(
|
// .array(
|
||||||
@ -98,7 +100,23 @@ const AgentForm = ({ node }: INextOperatorForm) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
{isSubAgent && <DescriptionField></DescriptionField>}
|
{isSubAgent && (
|
||||||
|
<>
|
||||||
|
<DescriptionField></DescriptionField>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name={`user_prompt`}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex-1">
|
||||||
|
<FormLabel>Subagent Input</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea {...field}></Textarea>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<LargeModelFormField></LargeModelFormField>
|
<LargeModelFormField></LargeModelFormField>
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
|
|||||||
@ -56,6 +56,12 @@ import {
|
|||||||
getNodeDragHandle,
|
getNodeDragHandle,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
|
function isBottomSubAgent(type: string, position: Position) {
|
||||||
|
return (
|
||||||
|
(type === Operator.Agent && position === Position.Bottom) ||
|
||||||
|
type === Operator.Tool
|
||||||
|
);
|
||||||
|
}
|
||||||
export const useInitializeOperatorParams = () => {
|
export const useInitializeOperatorParams = () => {
|
||||||
const llmId = useFetchModelId();
|
const llmId = useFetchModelId();
|
||||||
|
|
||||||
@ -114,8 +120,17 @@ export const useInitializeOperatorParams = () => {
|
|||||||
}, [llmId]);
|
}, [llmId]);
|
||||||
|
|
||||||
const initializeOperatorParams = useCallback(
|
const initializeOperatorParams = useCallback(
|
||||||
(operatorName: Operator) => {
|
(operatorName: Operator, position: Position) => {
|
||||||
return initialFormValuesMap[operatorName];
|
const initialValues = initialFormValuesMap[operatorName];
|
||||||
|
if (isBottomSubAgent(operatorName, position)) {
|
||||||
|
return {
|
||||||
|
...initialValues,
|
||||||
|
description: 'This is an agent for a specific task.',
|
||||||
|
user_prompt: 'This is the order you need to send to the agent.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialValues;
|
||||||
},
|
},
|
||||||
[initialFormValuesMap],
|
[initialFormValuesMap],
|
||||||
);
|
);
|
||||||
@ -235,13 +250,6 @@ function useAddToolNode() {
|
|||||||
return { addToolNode };
|
return { addToolNode };
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBottomSubAgent(type: string, position: Position) {
|
|
||||||
return (
|
|
||||||
(type === Operator.Agent && position === Position.Bottom) ||
|
|
||||||
type === Operator.Tool
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function useResizeIterationNode() {
|
function useResizeIterationNode() {
|
||||||
const { getNode, nodes, updateNode } = useGraphStore((state) => state);
|
const { getNode, nodes, updateNode } = useGraphStore((state) => state);
|
||||||
|
|
||||||
@ -324,7 +332,7 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) {
|
|||||||
getNodeName(type),
|
getNodeName(type),
|
||||||
nodes,
|
nodes,
|
||||||
),
|
),
|
||||||
form: initializeOperatorParams(type as Operator),
|
form: initializeOperatorParams(type as Operator, params.position),
|
||||||
},
|
},
|
||||||
sourcePosition: Position.Right,
|
sourcePosition: Position.Right,
|
||||||
targetPosition: Position.Left,
|
targetPosition: Position.Left,
|
||||||
|
|||||||
@ -35,7 +35,7 @@ export function McpCard({
|
|||||||
<section className="flex justify-between pb-2">
|
<section className="flex justify-between pb-2">
|
||||||
<h3 className="text-lg font-semibold line-clamp-1">{data.name}</h3>
|
<h3 className="text-lg font-semibold line-clamp-1">{data.name}</h3>
|
||||||
<div className="space-x-4">
|
<div className="space-x-4">
|
||||||
<McpDropdown>
|
<McpDropdown mcpId={data.id}>
|
||||||
<MoreButton></MoreButton>
|
<MoreButton></MoreButton>
|
||||||
</McpDropdown>
|
</McpDropdown>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|||||||
@ -6,27 +6,33 @@ import {
|
|||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu';
|
} from '@/components/ui/dropdown-menu';
|
||||||
|
import { useDeleteMcpServer } from '@/hooks/use-mcp-request';
|
||||||
import { PenLine, Trash2 } from 'lucide-react';
|
import { PenLine, Trash2 } from 'lucide-react';
|
||||||
import { MouseEventHandler, PropsWithChildren, useCallback } from 'react';
|
import { MouseEventHandler, PropsWithChildren, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export function McpDropdown({ children }: PropsWithChildren) {
|
export function McpDropdown({
|
||||||
|
children,
|
||||||
|
mcpId,
|
||||||
|
}: PropsWithChildren & { mcpId: string }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { deleteMcpServer } = useDeleteMcpServer();
|
||||||
|
|
||||||
const handleShowAgentRenameModal: MouseEventHandler<HTMLDivElement> =
|
const handleShowAgentRenameModal: MouseEventHandler<HTMLDivElement> =
|
||||||
useCallback((e) => {
|
useCallback((e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDelete: MouseEventHandler<HTMLDivElement> =
|
const handleDelete: MouseEventHandler<HTMLDivElement> = useCallback(() => {
|
||||||
useCallback(() => {}, []);
|
deleteMcpServer([mcpId]);
|
||||||
|
}, [deleteMcpServer, mcpId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
|
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
<DropdownMenuItem onClick={handleShowAgentRenameModal}>
|
<DropdownMenuItem onClick={handleShowAgentRenameModal}>
|
||||||
{t('common.rename')} <PenLine />
|
{t('common.edit')} <PenLine />
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<ConfirmDeleteDialog onOk={handleDelete}>
|
<ConfirmDeleteDialog onOk={handleDelete}>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useDeleteMcpServer } from '@/hooks/use-mcp-request';
|
||||||
import { Trash2, Upload } from 'lucide-react';
|
import { Trash2, Upload } from 'lucide-react';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -5,10 +6,13 @@ import { useTranslation } from 'react-i18next';
|
|||||||
export function useBulkOperateMCP() {
|
export function useBulkOperateMCP() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [selectedList, setSelectedList] = useState<Array<string>>([]);
|
const [selectedList, setSelectedList] = useState<Array<string>>([]);
|
||||||
|
const { deleteMcpServer } = useDeleteMcpServer();
|
||||||
|
|
||||||
const handleEnableClick = useCallback(() => {}, []);
|
const handleEnableClick = useCallback(() => {}, []);
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {}, []);
|
const handleDelete = useCallback(() => {
|
||||||
|
deleteMcpServer(selectedList);
|
||||||
|
}, [deleteMcpServer, selectedList]);
|
||||||
|
|
||||||
const handleSelectChange = useCallback((id: string, checked: boolean) => {
|
const handleSelectChange = useCallback((id: string, checked: boolean) => {
|
||||||
setSelectedList((list) => {
|
setSelectedList((list) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user