feat: can not choose mcp tool in picker

This commit is contained in:
Joel
2025-06-05 15:51:34 +08:00
parent 933194b1f7
commit fa3a616bf6
12 changed files with 41 additions and 14 deletions

View File

@ -35,7 +35,7 @@ type AllToolsProps = {
canNotSelectMultiple?: boolean
onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void
selectedTools?: ToolValue[]
isHideMCPTools?: boolean
canChooseMCPTool?: boolean
}
const DEFAULT_TAGS: AllToolsProps['tags'] = []
@ -53,10 +53,10 @@ const AllTools = ({
customTools,
mcpTools = [],
selectedTools,
isHideMCPTools,
canChooseMCPTool,
}: AllToolsProps) => {
const language = useGetLanguage()
const tabs = useToolTabs(isHideMCPTools)
const tabs = useToolTabs()
const [activeTab, setActiveTab] = useState(ToolTypeEnum.All)
const [activeView, setActiveView] = useState<ViewType>(ViewType.flat)
const hasFilter = searchText || tags.length > 0
@ -148,6 +148,7 @@ const AllTools = ({
viewType={isSupportGroupView ? activeView : ViewType.flat}
hasSearchText={!!searchText}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
{/* Plugins from marketplace */}
{enable_marketplace && <PluginList

View File

@ -83,7 +83,7 @@ const Tabs: FC<TabsProps> = ({
customTools={customTools || []}
workflowTools={workflowTools || []}
mcpTools={mcpTools || []}
isHideMCPTools={false}
canChooseMCPTool
/>
)
}

View File

@ -178,7 +178,7 @@ const ToolPicker: FC<Props> = ({
workflowTools={workflowToolList || []}
mcpTools={mcpTools || []}
selectedTools={selectedTools}
isHideMCPTools={!canChooseMCPTool}
canChooseMCPTool={canChooseMCPTool}
/>
</div>
</PortalToFollowElemContent>

View File

@ -15,6 +15,7 @@ type Props = {
provider: ToolWithProvider
payload: Tool
disabled?: boolean
isAdded?: boolean
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
}
@ -23,6 +24,7 @@ const ToolItem: FC<Props> = ({
payload,
onSelect,
disabled,
isAdded,
}) => {
const { t } = useTranslation()
@ -76,7 +78,7 @@ const ToolItem: FC<Props> = ({
<div className={cn('system-sm-medium h-8 truncate border-l-2 border-divider-subtle pl-4 leading-8 text-text-secondary')}>
<span className={cn(disabled && 'opacity-30')}>{payload.label[language]}</span>
</div>
{disabled && (
{isAdded && (
<div className='system-xs-regular mr-4 text-text-tertiary'>{t('tools.addToolModal.added')}</div>
)}
</div>

View File

@ -18,6 +18,7 @@ type Props = {
letters: string[]
toolRefs: any
selectedTools?: ToolValue[]
canChooseMCPTool?: boolean
}
const ToolViewFlatView: FC<Props> = ({
@ -30,6 +31,7 @@ const ToolViewFlatView: FC<Props> = ({
onSelectMultiple,
toolRefs,
selectedTools,
canChooseMCPTool,
}) => {
const firstLetterToolIds = useMemo(() => {
const res: Record<string, string> = {}
@ -60,6 +62,7 @@ const ToolViewFlatView: FC<Props> = ({
canNotSelectMultiple={canNotSelectMultiple}
onSelectMultiple={onSelectMultiple}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
</div>
))}

View File

@ -15,6 +15,7 @@ type Props = {
canNotSelectMultiple?: boolean
onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void
selectedTools?: ToolValue[]
canChooseMCPTool?: boolean
}
const Item: FC<Props> = ({
@ -25,6 +26,7 @@ const Item: FC<Props> = ({
canNotSelectMultiple,
onSelectMultiple,
selectedTools,
canChooseMCPTool,
}) => {
return (
<div>
@ -43,6 +45,7 @@ const Item: FC<Props> = ({
canNotSelectMultiple={canNotSelectMultiple}
onSelectMultiple={onSelectMultiple}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
))}
</div>

View File

@ -15,6 +15,7 @@ type Props = {
canNotSelectMultiple?: boolean
onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void
selectedTools?: ToolValue[]
canChooseMCPTool?: boolean
}
const ToolListTreeView: FC<Props> = ({
@ -24,6 +25,7 @@ const ToolListTreeView: FC<Props> = ({
canNotSelectMultiple,
onSelectMultiple,
selectedTools,
canChooseMCPTool,
}) => {
const { t } = useTranslation()
const getI18nGroupName = useCallback((name: string) => {
@ -53,6 +55,7 @@ const ToolListTreeView: FC<Props> = ({
canNotSelectMultiple={canNotSelectMultiple}
onSelectMultiple={onSelectMultiple}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
))}
</div>

View File

@ -14,6 +14,7 @@ import ActonItem from './action-item'
import BlockIcon from '../../block-icon'
import { useTranslation } from 'react-i18next'
import { useHover } from 'ahooks'
import McpToolNotSupportTooltip from '../../nodes/_base/components/mcp-tool-not-support-tooltip'
type Props = {
className?: string
@ -25,6 +26,7 @@ type Props = {
canNotSelectMultiple?: boolean
onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void
selectedTools?: ToolValue[]
canChooseMCPTool?: boolean
}
const Tool: FC<Props> = ({
@ -37,6 +39,7 @@ const Tool: FC<Props> = ({
canNotSelectMultiple,
onSelectMultiple,
selectedTools,
canChooseMCPTool,
}) => {
const { t } = useTranslation()
const language = useGetLanguage()
@ -47,6 +50,7 @@ const Tool: FC<Props> = ({
const [isFold, setFold] = React.useState<boolean>(true)
const ref = useRef(null)
const isHovering = useHover(ref)
const isShowCanNotChooseMCPTip = !canChooseMCPTool && payload.type === CollectionType.mcp
const getIsDisabled = useCallback((tool: ToolType) => {
if (!selectedTools || !selectedTools.length) return false
return selectedTools.some(selectedTool => (selectedTool.provider_name === payload.name || selectedTool.provider_name === payload.id) && selectedTool.tool_name === tool.name)
@ -173,7 +177,7 @@ const Tool: FC<Props> = ({
})
}}
>
<div className='flex h-8 grow items-center'>
<div className={cn('flex h-8 grow items-center', isShowCanNotChooseMCPTip && 'opacity-30')}>
<BlockIcon
className='shrink-0'
type={BlockEnum.Tool}
@ -188,7 +192,8 @@ const Tool: FC<Props> = ({
</div>
<div className='ml-2 flex items-center'>
{!canNotSelectMultiple && (notShowProvider ? notShowProviderSelectInfo : selectedInfo)}
{!isShowCanNotChooseMCPTip && !canNotSelectMultiple && (notShowProvider ? notShowProviderSelectInfo : selectedInfo)}
{isShowCanNotChooseMCPTip && <McpToolNotSupportTooltip />}
{hasAction && (
<FoldIcon className={cn('h-4 w-4 shrink-0 text-text-quaternary', isFold && 'text-text-tertiary')} />
)}
@ -202,7 +207,8 @@ const Tool: FC<Props> = ({
provider={payload}
payload={action}
onSelect={onSelect}
disabled={getIsDisabled(action)}
disabled={getIsDisabled(action) || isShowCanNotChooseMCPTip}
isAdded={getIsDisabled(action)}
/>
))
)}

View File

@ -25,6 +25,7 @@ type ToolsProps = {
className?: string
indexBarClassName?: string
selectedTools?: ToolValue[]
canChooseMCPTool?: boolean
}
const Blocks = ({
showWorkflowEmpty,
@ -37,6 +38,7 @@ const Blocks = ({
className,
indexBarClassName,
selectedTools,
canChooseMCPTool,
}: ToolsProps) => {
const { t } = useTranslation()
const language = useGetLanguage()
@ -114,6 +116,7 @@ const Blocks = ({
canNotSelectMultiple={canNotSelectMultiple}
onSelectMultiple={onSelectMultiple}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
) : (
<ToolListTreeView
@ -123,6 +126,7 @@ const Blocks = ({
canNotSelectMultiple={canNotSelectMultiple}
onSelectMultiple={onSelectMultiple}
selectedTools={selectedTools}
canChooseMCPTool={canChooseMCPTool}
/>
)
)}

View File

@ -33,7 +33,7 @@ export type ToolDefaultValue = {
params: Record<string, any>
paramSchemas: Record<string, any>[]
output_schema: Record<string, any>
meta: PluginMeta
meta?: PluginMeta
}
export type ToolValue = {

View File

@ -89,10 +89,11 @@ function formatStrategy(input: StrategyPluginDetail[], getIcon: (i: string) => s
export type AgentStrategySelectorProps = {
value?: Strategy,
onChange: (value?: Strategy) => void,
canChooseMCPTool: boolean,
}
export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) => {
const { value, onChange } = props
const { value, onChange, canChooseMCPTool } = props
const [open, setOpen] = useState(false)
const [viewType, setViewType] = useState<ViewType>(ViewType.flat)
const [query, setQuery] = useState('')
@ -216,7 +217,11 @@ export const AgentStrategySelector = memo((props: AgentStrategySelectorProps) =>
setOpen(false)
}}
className='h-full max-h-full max-w-none overflow-y-auto'
indexBarClassName='top-0 xl:top-36' showWorkflowEmpty={false} hasSearchText={false} />
indexBarClassName='top-0 xl:top-36'
showWorkflowEmpty={false}
hasSearchText={false}
canChooseMCPTool={canChooseMCPTool}
/>
<PluginList
ref={pluginRef}
wrapElemRef={wrapElemRef}

View File

@ -43,7 +43,7 @@ export type AgentStrategyProps = {
nodeOutputVars?: NodeOutPutVar[],
availableNodes?: Node[],
nodeId?: string
canChooseMCPTool?: boolean
canChooseMCPTool: boolean
}
type CustomSchema<Type, Field = {}> = Omit<CredentialFormSchema, 'type'> & { type: Type } & Field
@ -201,7 +201,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
}
}
return <div className='space-y-2'>
<AgentStrategySelector value={strategy} onChange={onStrategyChange} />
<AgentStrategySelector value={strategy} onChange={onStrategyChange} canChooseMCPTool={canChooseMCPTool} />
{
strategy
? <div>