mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-16 18:15:55 +08:00
feat: add mcp tab and merge tool with server ts define
This commit is contained in:
parent
b3faaa3754
commit
347cb2685e
@ -9,6 +9,10 @@ export const listData = [
|
|||||||
is_team_authorization: true,
|
is_team_authorization: true,
|
||||||
tools: ['aaa', 'bbb'],
|
tools: ['aaa', 'bbb'],
|
||||||
update_elapsed_time: 1744793369,
|
update_elapsed_time: 1744793369,
|
||||||
|
label: {
|
||||||
|
en_US: 'GOGOGO',
|
||||||
|
zh_Hans: 'GOGOGO',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'fdjklajfkljadslf222',
|
id: 'fdjklajfkljadslf222',
|
||||||
@ -20,6 +24,10 @@ export const listData = [
|
|||||||
is_team_authorization: false,
|
is_team_authorization: false,
|
||||||
tools: [],
|
tools: [],
|
||||||
update_elapsed_time: 1744793369,
|
update_elapsed_time: 1744793369,
|
||||||
|
label: {
|
||||||
|
en_US: 'GOGOGO2',
|
||||||
|
zh_Hans: 'GOGOGO2',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'fdjklajfkljadslf333',
|
id: 'fdjklajfkljadslf333',
|
||||||
@ -31,5 +39,9 @@ export const listData = [
|
|||||||
is_team_authorization: true,
|
is_team_authorization: true,
|
||||||
tools: ['aaa', 'bbb'],
|
tools: ['aaa', 'bbb'],
|
||||||
update_elapsed_time: 1744793369,
|
update_elapsed_time: 1744793369,
|
||||||
|
label: {
|
||||||
|
en_US: 'GOGOGO3',
|
||||||
|
zh_Hans: 'GOGOGO3',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -9,13 +9,13 @@ import { RiHammerFill } from '@remixicon/react'
|
|||||||
import Indicator from '@/app/components/header/indicator'
|
import Indicator from '@/app/components/header/indicator'
|
||||||
import Icon from '@/app/components/plugins/card/base/card-icon'
|
import Icon from '@/app/components/plugins/card/base/card-icon'
|
||||||
import { useFormatTimeFromNow } from './hooks'
|
import { useFormatTimeFromNow } from './hooks'
|
||||||
import type { MCPProvider } from '@/app/components/tools/types'
|
import type { ToolWithProvider } from '../../workflow/types'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
currentProvider?: MCPProvider
|
currentProvider?: ToolWithProvider
|
||||||
data: MCPProvider
|
data: ToolWithProvider
|
||||||
handleSelect: (provider: MCPProvider) => void
|
handleSelect: (provider: ToolWithProvider) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCPCard = ({
|
const MCPCard = ({
|
||||||
@ -27,7 +27,7 @@ const MCPCard = ({
|
|||||||
const { formatTimeFromNow } = useFormatTimeFromNow()
|
const { formatTimeFromNow } = useFormatTimeFromNow()
|
||||||
// const { locale } = useContext(I18n)
|
// const { locale } = useContext(I18n)
|
||||||
// const language = getLanguage(locale)
|
// const language = getLanguage(locale)
|
||||||
// const { isCurrentWorkspaceManager } = useAppContext()
|
// const { isCurrentWorkspaceManager } = useAppContext()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -52,7 +52,7 @@ const MCPCard = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className='system-xs-regular text-divider-deep'>/</div>
|
<div className='system-xs-regular text-divider-deep'>/</div>
|
||||||
<div className='system-xs-regular truncate text-text-tertiary'>{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.update_elapsed_time * 1000)}`}</div>
|
<div className='system-xs-regular truncate text-text-tertiary'>{`${t('tools.mcp.updateTime')} ${formatTimeFromNow(data.update_elapsed_time! * 1000)}`}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import Drawer from '@/app/components/base/drawer'
|
import Drawer from '@/app/components/base/drawer'
|
||||||
import type { MCPProvider } from '@/app/components/tools/types'
|
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import type { ToolWithProvider } from '../../workflow/types'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
detail?: MCPProvider
|
detail?: ToolWithProvider
|
||||||
onUpdate: () => void
|
onUpdate: () => void
|
||||||
onHide: () => void
|
onHide: () => void
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,9 @@ export type Collection = {
|
|||||||
labels: string[]
|
labels: string[]
|
||||||
plugin_id?: string
|
plugin_id?: string
|
||||||
letter?: string
|
letter?: string
|
||||||
|
// MCP Server
|
||||||
|
server_url?: string
|
||||||
|
update_elapsed_time?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ToolParameter = {
|
export type ToolParameter = {
|
||||||
@ -169,15 +172,3 @@ export type WorkflowToolProviderResponse = {
|
|||||||
}
|
}
|
||||||
privacy_policy: string
|
privacy_policy: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MCPProvider = {
|
|
||||||
id: string
|
|
||||||
author: string
|
|
||||||
name: string
|
|
||||||
icon: string | Emoji
|
|
||||||
server_url: string
|
|
||||||
type: CollectionType
|
|
||||||
is_team_authorization: boolean
|
|
||||||
tools: string[]
|
|
||||||
update_elapsed_time: number
|
|
||||||
}
|
|
||||||
|
@ -31,6 +31,7 @@ type AllToolsProps = {
|
|||||||
buildInTools: ToolWithProvider[]
|
buildInTools: ToolWithProvider[]
|
||||||
customTools: ToolWithProvider[]
|
customTools: ToolWithProvider[]
|
||||||
workflowTools: ToolWithProvider[]
|
workflowTools: ToolWithProvider[]
|
||||||
|
mcpTools: ToolWithProvider[]
|
||||||
onSelect: OnSelectBlock
|
onSelect: OnSelectBlock
|
||||||
supportAddCustomTool?: boolean
|
supportAddCustomTool?: boolean
|
||||||
onAddedCustomTool?: () => void
|
onAddedCustomTool?: () => void
|
||||||
@ -49,6 +50,7 @@ const AllTools = ({
|
|||||||
buildInTools,
|
buildInTools,
|
||||||
workflowTools,
|
workflowTools,
|
||||||
customTools,
|
customTools,
|
||||||
|
mcpTools = [],
|
||||||
supportAddCustomTool,
|
supportAddCustomTool,
|
||||||
onShowAddCustomCollectionModal,
|
onShowAddCustomCollectionModal,
|
||||||
selectedTools,
|
selectedTools,
|
||||||
@ -64,13 +66,15 @@ const AllTools = ({
|
|||||||
const tools = useMemo(() => {
|
const tools = useMemo(() => {
|
||||||
let mergedTools: ToolWithProvider[] = []
|
let mergedTools: ToolWithProvider[] = []
|
||||||
if (activeTab === ToolTypeEnum.All)
|
if (activeTab === ToolTypeEnum.All)
|
||||||
mergedTools = [...buildInTools, ...customTools, ...workflowTools]
|
mergedTools = [...buildInTools, ...customTools, ...workflowTools, ...mcpTools]
|
||||||
if (activeTab === ToolTypeEnum.BuiltIn)
|
if (activeTab === ToolTypeEnum.BuiltIn)
|
||||||
mergedTools = buildInTools
|
mergedTools = buildInTools
|
||||||
if (activeTab === ToolTypeEnum.Custom)
|
if (activeTab === ToolTypeEnum.Custom)
|
||||||
mergedTools = customTools
|
mergedTools = customTools
|
||||||
if (activeTab === ToolTypeEnum.Workflow)
|
if (activeTab === ToolTypeEnum.Workflow)
|
||||||
mergedTools = workflowTools
|
mergedTools = workflowTools
|
||||||
|
if (activeTab === ToolTypeEnum.MCP)
|
||||||
|
mergedTools = mcpTools
|
||||||
|
|
||||||
if (!hasFilter)
|
if (!hasFilter)
|
||||||
return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0)
|
return mergedTools.filter(toolWithProvider => toolWithProvider.tools.length > 0)
|
||||||
@ -80,7 +84,7 @@ const AllTools = ({
|
|||||||
return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase())
|
return tool.label[language].toLowerCase().includes(searchText.toLowerCase()) || tool.name.toLowerCase().includes(searchText.toLowerCase())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, [activeTab, buildInTools, customTools, workflowTools, searchText, language, hasFilter])
|
}, [activeTab, buildInTools, customTools, workflowTools, mcpTools, searchText, language, hasFilter])
|
||||||
|
|
||||||
const {
|
const {
|
||||||
queryPluginsWithDebounced: fetchPlugins,
|
queryPluginsWithDebounced: fetchPlugins,
|
||||||
|
@ -51,5 +51,9 @@ export const useToolTabs = () => {
|
|||||||
key: ToolTypeEnum.Workflow,
|
key: ToolTypeEnum.Workflow,
|
||||||
name: t('workflow.tabs.workflowTool'),
|
name: t('workflow.tabs.workflowTool'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: ToolTypeEnum.MCP,
|
||||||
|
name: 'MCP',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools } from '@/service/use-tools'
|
import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools } from '@/service/use-tools'
|
||||||
import type { BlockEnum } from '../types'
|
import type { BlockEnum } from '../types'
|
||||||
import { useTabs } from './hooks'
|
import { useTabs } from './hooks'
|
||||||
import type { ToolDefaultValue } from './types'
|
import type { ToolDefaultValue } from './types'
|
||||||
@ -31,6 +31,7 @@ const Tabs: FC<TabsProps> = ({
|
|||||||
const { data: buildInTools } = useAllBuiltInTools()
|
const { data: buildInTools } = useAllBuiltInTools()
|
||||||
const { data: customTools } = useAllCustomTools()
|
const { data: customTools } = useAllCustomTools()
|
||||||
const { data: workflowTools } = useAllWorkflowTools()
|
const { data: workflowTools } = useAllWorkflowTools()
|
||||||
|
const { data: mcpTools } = useAllMCPTools()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onClick={e => e.stopPropagation()}>
|
<div onClick={e => e.stopPropagation()}>
|
||||||
@ -75,6 +76,7 @@ const Tabs: FC<TabsProps> = ({
|
|||||||
buildInTools={buildInTools || []}
|
buildInTools={buildInTools || []}
|
||||||
customTools={customTools || []}
|
customTools={customTools || []}
|
||||||
workflowTools={workflowTools || []}
|
workflowTools={workflowTools || []}
|
||||||
|
mcpTools={mcpTools || []}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
} from '@/service/tools'
|
} from '@/service/tools'
|
||||||
import type { CustomCollectionBackend } from '@/app/components/tools/types'
|
import type { CustomCollectionBackend } from '@/app/components/tools/types'
|
||||||
import Toast from '@/app/components/base/toast'
|
import Toast from '@/app/components/base/toast'
|
||||||
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools, useInvalidateAllCustomTools } from '@/service/use-tools'
|
import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools, useInvalidateAllCustomTools } from '@/service/use-tools'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -61,6 +61,7 @@ const ToolPicker: FC<Props> = ({
|
|||||||
const { data: customTools } = useAllCustomTools()
|
const { data: customTools } = useAllCustomTools()
|
||||||
const invalidateCustomTools = useInvalidateAllCustomTools()
|
const invalidateCustomTools = useInvalidateAllCustomTools()
|
||||||
const { data: workflowTools } = useAllWorkflowTools()
|
const { data: workflowTools } = useAllWorkflowTools()
|
||||||
|
const { data: mcpTools } = useAllMCPTools()
|
||||||
|
|
||||||
const { builtinToolList, customToolList, workflowToolList } = useMemo(() => {
|
const { builtinToolList, customToolList, workflowToolList } = useMemo(() => {
|
||||||
if (scope === 'plugins') {
|
if (scope === 'plugins') {
|
||||||
@ -162,6 +163,7 @@ const ToolPicker: FC<Props> = ({
|
|||||||
buildInTools={builtinToolList || []}
|
buildInTools={builtinToolList || []}
|
||||||
customTools={customToolList || []}
|
customTools={customToolList || []}
|
||||||
workflowTools={workflowToolList || []}
|
workflowTools={workflowToolList || []}
|
||||||
|
mcpTools={mcpTools || []}
|
||||||
supportAddCustomTool={supportAddCustomTool}
|
supportAddCustomTool={supportAddCustomTool}
|
||||||
onAddedCustomTool={handleAddedCustomTool}
|
onAddedCustomTool={handleAddedCustomTool}
|
||||||
onShowAddCustomCollectionModal={showEditCustomCollectionModal}
|
onShowAddCustomCollectionModal={showEditCustomCollectionModal}
|
||||||
|
@ -8,6 +8,7 @@ export enum ToolTypeEnum {
|
|||||||
BuiltIn = 'built-in',
|
BuiltIn = 'built-in',
|
||||||
Custom = 'custom',
|
Custom = 'custom',
|
||||||
Workflow = 'workflow',
|
Workflow = 'workflow',
|
||||||
|
MCP = 'mcp',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BlockClassificationEnum {
|
export enum BlockClassificationEnum {
|
||||||
|
@ -4,7 +4,6 @@ import type {
|
|||||||
Tool,
|
Tool,
|
||||||
} from '@/app/components/tools/types'
|
} from '@/app/components/tools/types'
|
||||||
import type { ToolWithProvider } from '@/app/components/workflow/types'
|
import type { ToolWithProvider } from '@/app/components/workflow/types'
|
||||||
import type { MCPProvider } from '@/app/components/tools/types'
|
|
||||||
import { useInvalid } from './use-base'
|
import { useInvalid } from './use-base'
|
||||||
import {
|
import {
|
||||||
useMutation,
|
useMutation,
|
||||||
@ -66,11 +65,11 @@ export const useInvalidateAllWorkflowTools = () => {
|
|||||||
|
|
||||||
const useAllMCPToolsKey = [NAME_SPACE, 'MCPTools']
|
const useAllMCPToolsKey = [NAME_SPACE, 'MCPTools']
|
||||||
export const useAllMCPTools = () => {
|
export const useAllMCPTools = () => {
|
||||||
return useQuery<MCPProvider[]>({
|
return useQuery<ToolWithProvider[]>({
|
||||||
queryKey: useAllMCPToolsKey,
|
queryKey: useAllMCPToolsKey,
|
||||||
// queryFn: () => get<MCPProvider[]>('/workspaces/current/tools/mcp'),
|
// queryFn: () => get<ToolWithProvider[]>('/workspaces/current/tools/mcp'),
|
||||||
queryFn: () => {
|
queryFn: () => {
|
||||||
return listData as unknown as MCPProvider[]
|
return listData as unknown as ToolWithProvider[]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user