| @@ -1,3 +1,7 @@ | |||
| import type { | |||
| Dispatch, | |||
| SetStateAction, | |||
| } from 'react' | |||
| import { | |||
| useEffect, | |||
| useMemo, | |||
| @@ -21,6 +25,7 @@ import PluginList, { type ListProps } from '@/app/components/workflow/block-sele | |||
| import { PluginType } from '../../plugins/types' | |||
| import { useMarketplacePlugins } from '../../plugins/marketplace/hooks' | |||
| import { useGlobalPublicStore } from '@/context/global-public-context' | |||
| import RAGToolSuggestions from './rag-tool-suggestions' | |||
| type AllToolsProps = { | |||
| className?: string | |||
| @@ -36,6 +41,8 @@ type AllToolsProps = { | |||
| onSelectMultiple?: (type: BlockEnum, tools: ToolDefaultValue[]) => void | |||
| selectedTools?: ToolValue[] | |||
| canChooseMCPTool?: boolean | |||
| onTagsChange: Dispatch<SetStateAction<string[]>> | |||
| isInRAGPipeline?: boolean | |||
| } | |||
| const DEFAULT_TAGS: AllToolsProps['tags'] = [] | |||
| @@ -54,6 +61,8 @@ const AllTools = ({ | |||
| mcpTools = [], | |||
| selectedTools, | |||
| canChooseMCPTool, | |||
| onTagsChange, | |||
| isInRAGPipeline = false, | |||
| }: AllToolsProps) => { | |||
| const language = useGetLanguage() | |||
| const tabs = useToolTabs() | |||
| @@ -101,13 +110,14 @@ const AllTools = ({ | |||
| category: PluginType.tool, | |||
| }) | |||
| } | |||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||
| }, [searchText, tags, enable_marketplace]) | |||
| const pluginRef = useRef<ListRef>(null) | |||
| const wrapElemRef = useRef<HTMLDivElement>(null) | |||
| const isSupportGroupView = [ToolTypeEnum.All, ToolTypeEnum.BuiltIn].includes(activeTab) | |||
| const isShowRAGRecommendations = isInRAGPipeline && activeTab === ToolTypeEnum.All && !searchText | |||
| return ( | |||
| <div className={cn('min-w-[400px] max-w-[500px]', className)}> | |||
| <div className='flex items-center justify-between border-b border-divider-subtle px-3'> | |||
| @@ -137,6 +147,14 @@ const AllTools = ({ | |||
| className='max-h-[464px] overflow-y-auto' | |||
| onScroll={pluginRef.current?.handleScroll} | |||
| > | |||
| {isShowRAGRecommendations && ( | |||
| <RAGToolSuggestions | |||
| tools={[]} | |||
| viewType={isSupportGroupView ? activeView : ViewType.flat} | |||
| onSelect={onSelect} | |||
| onTagsChange={onTagsChange} | |||
| /> | |||
| )} | |||
| <Tools | |||
| className={toolContentClassName} | |||
| tools={tools} | |||
| @@ -148,16 +166,19 @@ const AllTools = ({ | |||
| hasSearchText={!!searchText} | |||
| selectedTools={selectedTools} | |||
| canChooseMCPTool={canChooseMCPTool} | |||
| isShowRAGRecommendations={isShowRAGRecommendations} | |||
| /> | |||
| {/* Plugins from marketplace */} | |||
| {enable_marketplace && <PluginList | |||
| ref={pluginRef} | |||
| wrapElemRef={wrapElemRef} | |||
| list={notInstalledPlugins} | |||
| searchText={searchText} | |||
| toolContentClassName={toolContentClassName} | |||
| tags={tags} | |||
| />} | |||
| {enable_marketplace && ( | |||
| <PluginList | |||
| ref={pluginRef} | |||
| wrapElemRef={wrapElemRef} | |||
| list={notInstalledPlugins} | |||
| searchText={searchText} | |||
| toolContentClassName={toolContentClassName} | |||
| tags={tags} | |||
| /> | |||
| )} | |||
| </div> | |||
| </div> | |||
| ) | |||
| @@ -197,6 +197,7 @@ const NodeSelector: FC<NodeSelectorProps> = ({ | |||
| noBlocks={noBlocks} | |||
| dataSources={dataSources} | |||
| noTools={noTools} | |||
| onTagsChange={setTags} | |||
| /> | |||
| </div> | |||
| </PortalToFollowElemContent> | |||
| @@ -0,0 +1,58 @@ | |||
| import type { Dispatch, SetStateAction } from 'react' | |||
| import React, { useCallback } from 'react' | |||
| import { useTranslation } from 'react-i18next' | |||
| import type { OnSelectBlock, ToolWithProvider } from '../types' | |||
| // import Tools from './tools' | |||
| // import { ToolTypeEnum } from './types' | |||
| import type { ViewType } from './view-type-select' | |||
| import { RiMoreLine } from '@remixicon/react' | |||
| type RAGToolSuggestionsProps = { | |||
| tools: ToolWithProvider[] | |||
| viewType: ViewType | |||
| onSelect: OnSelectBlock | |||
| onTagsChange: Dispatch<SetStateAction<string[]>> | |||
| } | |||
| const RAGToolSuggestions: React.FC<RAGToolSuggestionsProps> = ({ | |||
| // tools, | |||
| // viewType, | |||
| // onSelect, | |||
| onTagsChange, | |||
| }) => { | |||
| const { t } = useTranslation() | |||
| const loadMore = useCallback(() => { | |||
| onTagsChange(prev => [...prev, 'rag']) | |||
| }, [onTagsChange]) | |||
| return ( | |||
| <div className='flex flex-col p-1'> | |||
| <div className='system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary'> | |||
| {t('pipeline.ragToolSuggestions.title')} | |||
| </div> | |||
| {/* <Tools | |||
| className='p-0' | |||
| tools={tools} | |||
| onSelect={onSelect} | |||
| canNotSelectMultiple | |||
| toolType={ToolTypeEnum.All} | |||
| viewType={viewType} | |||
| hasSearchText={false} | |||
| /> */} | |||
| <div | |||
| className='flex cursor-pointer items-center gap-x-2 py-1 pl-3 pr-2' | |||
| onClick={loadMore} | |||
| > | |||
| <div className='px-1'> | |||
| <RiMoreLine className='size-4 text-text-tertiary' /> | |||
| </div> | |||
| <div className='system-xs-regular text-text-tertiary'> | |||
| {t('common.operation.more')} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| ) | |||
| } | |||
| export default React.memo(RAGToolSuggestions) | |||
| @@ -1,4 +1,4 @@ | |||
| import type { FC } from 'react' | |||
| import type { Dispatch, FC, SetStateAction } from 'react' | |||
| import { memo } from 'react' | |||
| import { useAllBuiltInTools, useAllCustomTools, useAllMCPTools, useAllWorkflowTools } from '@/service/use-tools' | |||
| import type { | |||
| @@ -18,6 +18,7 @@ export type TabsProps = { | |||
| onActiveTabChange: (activeTab: TabsEnum) => void | |||
| searchText: string | |||
| tags: string[] | |||
| onTagsChange: Dispatch<SetStateAction<string[]>> | |||
| onSelect: OnSelectBlock | |||
| availableBlocksTypes?: BlockEnum[] | |||
| blocks: NodeDefault[] | |||
| @@ -34,6 +35,7 @@ const Tabs: FC<TabsProps> = ({ | |||
| activeTab, | |||
| onActiveTabChange, | |||
| tags, | |||
| onTagsChange, | |||
| searchText, | |||
| onSelect, | |||
| availableBlocksTypes, | |||
| @@ -109,6 +111,8 @@ const Tabs: FC<TabsProps> = ({ | |||
| workflowTools={workflowTools || []} | |||
| mcpTools={mcpTools || []} | |||
| canChooseMCPTool | |||
| onTagsChange={onTagsChange} | |||
| isInRAGPipeline={dataSources.length > 0} | |||
| /> | |||
| ) | |||
| } | |||
| @@ -28,6 +28,7 @@ type ToolsProps = { | |||
| indexBarClassName?: string | |||
| selectedTools?: ToolValue[] | |||
| canChooseMCPTool?: boolean | |||
| isShowRAGRecommendations?: boolean | |||
| } | |||
| const Blocks = ({ | |||
| onSelect, | |||
| @@ -42,6 +43,7 @@ const Blocks = ({ | |||
| indexBarClassName, | |||
| selectedTools, | |||
| canChooseMCPTool, | |||
| isShowRAGRecommendations = false, | |||
| }: ToolsProps) => { | |||
| // const tools: any = [] | |||
| const { t } = useTranslation() | |||
| @@ -105,7 +107,12 @@ const Blocks = ({ | |||
| } | |||
| {!tools.length && !hasSearchText && ( | |||
| <div className='py-10'> | |||
| <Empty type={toolType!} isAgent={isAgent}/> | |||
| <Empty type={toolType!} isAgent={isAgent} /> | |||
| </div> | |||
| )} | |||
| {!!tools.length && isShowRAGRecommendations && ( | |||
| <div className='system-xs-medium px-3 pb-0.5 pt-1 text-text-tertiary'> | |||
| {t('tools.allTools')} | |||
| </div> | |||
| )} | |||
| {!!tools.length && ( | |||
| @@ -31,6 +31,9 @@ const translation = { | |||
| footerTip: 'In test run mode, preview up to {{count}} chunks', | |||
| }, | |||
| }, | |||
| ragToolSuggestions: { | |||
| title: 'Suggestions for RAG', | |||
| }, | |||
| } | |||
| export default translation | |||
| @@ -234,6 +234,7 @@ const translation = { | |||
| publishTip: 'App not published. Please publish the app first.', | |||
| }, | |||
| }, | |||
| allTools: 'All tools', | |||
| } | |||
| export default translation | |||
| @@ -31,6 +31,9 @@ const translation = { | |||
| footerTip: '在测试运行模式下,最多预览 {{count}} 个分段', | |||
| }, | |||
| }, | |||
| ragToolSuggestions: { | |||
| title: 'RAG 工具推荐', | |||
| }, | |||
| } | |||
| export default translation | |||
| @@ -234,6 +234,7 @@ const translation = { | |||
| publishTip: '应用未发布。请先发布应用。', | |||
| }, | |||
| }, | |||
| allTools: '全部工具', | |||
| } | |||
| export default translation | |||