From 4ee5156afb2c9f6d8b73f53365052ed6ae21c875 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 9 May 2025 18:21:59 +0800 Subject: [PATCH] feat: can choose all in agent node --- .../multiple-tool-selector/index.tsx | 15 ++++++++++ .../tool-selector/index.tsx | 23 +++++++------- .../workflow/block-selector/all-tools.tsx | 6 +++- .../workflow/block-selector/tool-picker.tsx | 7 +++++ .../tool/tool-list-flat-view/list.tsx | 3 ++ .../tool/tool-list-tree-view/item.tsx | 3 ++ .../tool/tool-list-tree-view/list.tsx | 3 ++ .../workflow/block-selector/tool/tool.tsx | 30 +++++++++++++++++-- .../workflow/block-selector/tools.tsx | 4 +++ 9 files changed, 81 insertions(+), 13 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx index f243d30aff..e2b6b06fd6 100644 --- a/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx @@ -66,6 +66,19 @@ const MultipleToolSelector = ({ setOpen(false) } + const handleAddMultiple = (val: ToolValue[]) => { + const newValue = [...value, ...val] + // deduplication + const deduplication = newValue.reduce((acc, cur) => { + if (!acc.find(item => item.provider_name === cur.provider_name && item.tool_name === cur.tool_name)) + acc.push(cur) + return acc + }, [] as ToolValue[]) + // update value + onChange(deduplication) + setOpen(false) + } + // delete tool const handleDelete = (index: number) => { const newValue = [...value] @@ -134,6 +147,7 @@ const MultipleToolSelector = ({ value={undefined} selectedTools={value} onSelect={handleAdd} + onSelectMultiple={handleAddMultiple} controlledState={open} onControlledStateChange={setOpen} trigger={ @@ -156,6 +170,7 @@ const MultipleToolSelector = ({ value={item} selectedTools={value} onSelect={item => handleConfigure(item, index)} + onSelectMultiple={handleAddMultiple} onDelete={() => handleDelete(index)} supportEnableSwitch /> diff --git a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx index 4bbcb58bfb..954263b966 100644 --- a/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/tool-selector/index.tsx @@ -55,14 +55,8 @@ type Props = { scope?: string value?: ToolValue selectedTools?: ToolValue[] - onSelect: (tool: { - provider_name: string - tool_name: string - tool_label: string - settings?: Record - parameters?: Record - extra?: Record - }) => void + onSelect: (tool: ToolValue) => void + onSelectMultiple: (tool: ToolValue[]) => void onDelete?: () => void supportEnableSwitch?: boolean supportAddCustomTool?: boolean @@ -82,6 +76,7 @@ const ToolSelector: FC = ({ placement = 'left', offset = 4, onSelect, + onSelectMultiple, onDelete, scope, supportEnableSwitch, @@ -119,10 +114,10 @@ const ToolSelector: FC = ({ }, [value, buildInTools, customTools, workflowTools, mcpTools]) const [isShowChooseTool, setIsShowChooseTool] = useState(false) - const handleSelectTool = (tool: ToolDefaultValue) => { + const getToolValue = (tool: ToolDefaultValue) => { const settingValues = generateFormValue(tool.params, toolParametersToFormSchemas(tool.paramSchemas.filter(param => param.form !== 'llm') as any)) const paramValues = generateFormValue(tool.params, toolParametersToFormSchemas(tool.paramSchemas.filter(param => param.form === 'llm') as any), true) - const toolValue = { + return { provider_name: tool.provider_id, type: tool.provider_type, tool_name: tool.tool_name, @@ -136,9 +131,16 @@ const ToolSelector: FC = ({ }, schemas: tool.paramSchemas, } + } + const handleSelectTool = (tool: ToolDefaultValue) => { + const toolValue = getToolValue(tool) onSelect(toolValue) // setIsShowChooseTool(false) } + const handleSelectMultipleTool = (tool: ToolDefaultValue[]) => { + const toolValues = tool.map(item => getToolValue(item)) + onSelectMultiple(toolValues) + } const handleDescriptionChange = (e: React.ChangeEvent) => { onSelect({ @@ -300,6 +302,7 @@ const ToolSelector: FC = ({ disabled={false} supportAddCustomTool onSelect={handleSelectTool} + onSelectMultiple={handleSelectMultipleTool} scope={scope} selectedTools={selectedTools} /> diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index b37824f5b2..fd17c1f187 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -5,10 +5,11 @@ import { useState, } from 'react' import type { + BlockEnum, OnSelectBlock, ToolWithProvider, } from '../types' -import type { ToolValue } from './types' +import type { ToolDefaultValue, ToolValue } from './types' import { ToolTypeEnum } from './types' import Tools from './tools' import { useToolTabs } from './hooks' @@ -31,6 +32,7 @@ type AllToolsProps = { workflowTools: ToolWithProvider[] mcpTools: ToolWithProvider[] onSelect: OnSelectBlock + onSelectMultiple: (type: BlockEnum, tools: ToolDefaultValue[]) => void selectedTools?: ToolValue[] } @@ -42,6 +44,7 @@ const AllTools = ({ searchText, tags = DEFAULT_TAGS, onSelect, + onSelectMultiple, buildInTools, workflowTools, customTools, @@ -136,6 +139,7 @@ const AllTools = ({ showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} tools={tools} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} viewType={isSupportGroupView ? activeView : ViewType.flat} hasSearchText={!!searchText} selectedTools={selectedTools} diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index 8a79117086..bd24e204ce 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -35,6 +35,7 @@ type Props = { isShow: boolean onShowChange: (isShow: boolean) => void onSelect: (tool: ToolDefaultValue) => void + onSelectMultiple: (tools: ToolDefaultValue[]) => void supportAddCustomTool?: boolean scope?: string selectedTools?: ToolValue[] @@ -48,6 +49,7 @@ const ToolPicker: FC = ({ isShow, onShowChange, onSelect, + onSelectMultiple, supportAddCustomTool, scope = 'all', selectedTools, @@ -103,6 +105,10 @@ const ToolPicker: FC = ({ onSelect(tool!) } + const handleSelectMultiple = (_type: BlockEnum, tools: ToolDefaultValue[]) => { + onSelectMultiple(tools) + } + const [isShowEditCollectionToolModal, { setFalse: hideEditCustomCollectionModal, setTrue: showEditCustomCollectionModal, @@ -164,6 +170,7 @@ const ToolPicker: FC = ({ tags={tags} searchText={searchText} onSelect={handleSelect} + onSelectMultiple={handleSelectMultiple} buildInTools={builtinToolList || []} customTools={customToolList || []} workflowTools={workflowToolList || []} diff --git a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx index ef671ca1f8..91f2ea4677 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx @@ -13,6 +13,7 @@ type Props = { isShowLetterIndex: boolean hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + onSelectMultiple: (type: BlockEnum, tools: ToolDefaultValue[]) => void letters: string[] toolRefs: any selectedTools?: ToolValue[] @@ -24,6 +25,7 @@ const ToolViewFlatView: FC = ({ isShowLetterIndex, hasSearchText, onSelect, + onSelectMultiple, toolRefs, selectedTools, }) => { @@ -53,6 +55,7 @@ const ToolViewFlatView: FC = ({ isShowLetterIndex={isShowLetterIndex} hasSearchText={hasSearchText} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} selectedTools={selectedTools} /> diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx index d6c567f8e2..b09a0604ff 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx @@ -12,6 +12,7 @@ type Props = { toolList: ToolWithProvider[] hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + onSelectMultiple: (type: BlockEnum, tools: ToolValue[]) => void selectedTools?: ToolValue[] } @@ -20,6 +21,7 @@ const Item: FC = ({ toolList, hasSearchText, onSelect, + onSelectMultiple, selectedTools, }) => { return ( @@ -36,6 +38,7 @@ const Item: FC = ({ isShowLetterIndex={false} hasSearchText={hasSearchText} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} selectedTools={selectedTools} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx index f3f98279c8..c471709823 100644 --- a/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx +++ b/web/app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx @@ -12,6 +12,7 @@ type Props = { payload: Record hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + onSelectMultiple: (type: BlockEnum, tools: ToolValue[]) => void selectedTools?: ToolValue[] } @@ -19,6 +20,7 @@ const ToolListTreeView: FC = ({ payload, hasSearchText, onSelect, + onSelectMultiple, selectedTools, }) => { const { t } = useTranslation() @@ -46,6 +48,7 @@ const ToolListTreeView: FC = ({ toolList={payload[groupName]} hasSearchText={hasSearchText} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} selectedTools={selectedTools} /> ))} diff --git a/web/app/components/workflow/block-selector/tool/tool.tsx b/web/app/components/workflow/block-selector/tool/tool.tsx index 8c13fd38e0..40e9dda431 100644 --- a/web/app/components/workflow/block-selector/tool/tool.tsx +++ b/web/app/components/workflow/block-selector/tool/tool.tsx @@ -22,6 +22,7 @@ type Props = { isShowLetterIndex: boolean hasSearchText: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + onSelectMultiple: (type: BlockEnum, tools: ToolDefaultValue[]) => void selectedTools?: ToolValue[] } @@ -32,6 +33,7 @@ const Tool: FC = ({ isShowLetterIndex, hasSearchText, onSelect, + onSelectMultiple, selectedTools, }) => { const { t } = useTranslation() @@ -44,7 +46,7 @@ const Tool: FC = ({ const isHovering = useHover(ref) const getIsDisabled = (tool: ToolType) => { if (!selectedTools || !selectedTools.length) return false - return selectedTools.some(selectedTool => selectedTool.provider_name === payload.name && selectedTool.tool_name === tool.name) + return selectedTools.some(selectedTool => (selectedTool.provider_name === payload.name || selectedTool.provider_name === payload.id) && selectedTool.tool_name === tool.name) } const totalToolsNum = actions.length @@ -54,7 +56,31 @@ const Tool: FC = ({ const selectedInfo = useMemo(() => { if (isHovering && !isAllSelected) { return ( - + { + onSelectMultiple(BlockEnum.Tool, actions.filter(action => !getIsDisabled(action)).map((tool) => { + const params: Record = {} + if (tool.parameters) { + tool.parameters.forEach((item) => { + params[item.name] = '' + }) + } + return { + provider_id: payload.id, + provider_type: payload.type, + provider_name: payload.name, + tool_name: tool.name, + tool_label: tool.label[language], + tool_description: tool.description[language], + title: tool.label[language], + is_team_authorization: payload.is_team_authorization, + output_schema: tool.output_schema, + paramSchemas: tool.parameters, + params, + } + })) + }} + > {t('workflow.tabs.addAll')} ) diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index 2562501524..53e74117d2 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -17,6 +17,7 @@ import classNames from '@/utils/classnames' type ToolsProps = { showWorkflowEmpty: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void + onSelectMultiple: (type: BlockEnum, tools: ToolDefaultValue[]) => void tools: ToolWithProvider[] viewType: ViewType hasSearchText: boolean @@ -27,6 +28,7 @@ type ToolsProps = { const Blocks = ({ showWorkflowEmpty, onSelect, + onSelectMultiple, tools, viewType, hasSearchText, @@ -107,6 +109,7 @@ const Blocks = ({ isShowLetterIndex={isShowLetterIndex} hasSearchText={hasSearchText} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} selectedTools={selectedTools} /> ) : ( @@ -114,6 +117,7 @@ const Blocks = ({ payload={treeViewToolsData} hasSearchText={hasSearchText} onSelect={onSelect} + onSelectMultiple={onSelectMultiple} selectedTools={selectedTools} /> )