fix: can choose selected tools and show tool name instead of label (#13025)

This commit is contained in:
Joel 2025-01-24 22:34:09 +08:00 committed by GitHub
parent f93bf131ab
commit 6887b501b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 78 additions and 25 deletions

View File

@ -132,6 +132,7 @@ const AgentTools: FC = () => {
disabled={false}
supportAddCustomTool
onSelect={handleSelectTool}
selectedTools={tools}
/>
</>
)}
@ -161,7 +162,7 @@ const AgentTools: FC = () => {
)}
>
<span className='text-text-secondary system-xs-medium pr-1.5'>{item.provider_type === CollectionType.builtIn ? item.provider_name.split('/').pop() : item.tool_label}</span>
<span className='text-text-tertiary'>{item.tool_name}</span>
<span className='text-text-tertiary'>{item.tool_label}</span>
{!item.isDeleted && (
<Tooltip
needsDelay

View File

@ -315,7 +315,6 @@ function Form<
required,
scope,
} = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
return (
<div key={variable} className={cn(itemClassName, 'py-3')}>
<div className={cn(fieldLabelClassName, 'flex items-center py-2 system-sm-semibold text-text-secondary')}>
@ -329,6 +328,7 @@ function Form<
scope={scope}
disabled={readonly}
value={value[variable]}
// selectedTools={value[variable] ? [value[variable]] : []}
onSelect={item => handleFormChange(variable, item as any)}
onDelete={() => handleFormChange(variable, null as any)}
/>

View File

@ -9,7 +9,7 @@ import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-sele
import ActionButton from '@/app/components/base/action-button'
import Tooltip from '@/app/components/base/tooltip'
import Divider from '@/app/components/base/divider'
import type { ToolValue } from '@/app/components/plugins/plugin-detail-panel/tool-selector'
import type { ToolValue } from '@/app/components/workflow/block-selector/types'
import cn from '@/utils/classnames'
type Props = {
@ -85,7 +85,7 @@ const MultipleToolSelector = ({
popupContent={tooltip}
needsDelay
>
<div><RiQuestionLine className='w-3.5 h-3.5 text-text-quaternary hover:text-text-tertiary'/></div>
<div><RiQuestionLine className='w-3.5 h-3.5 text-text-quaternary hover:text-text-tertiary' /></div>
</Tooltip>
)}
{supportCollapse && (
@ -119,6 +119,7 @@ const MultipleToolSelector = ({
<ToolSelector
scope={scope}
value={undefined}
selectedTools={value}
onSelect={handleAdd}
controlledState={open}
onControlledStateChange={setOpen}
@ -134,6 +135,7 @@ const MultipleToolSelector = ({
<ToolSelector
scope={scope}
value={item}
selectedTools={value}
onSelect={item => handleConfigure(item, index)}
onDelete={() => handleDelete(index)}
supportEnableSwitch

View File

@ -35,7 +35,7 @@ import {
import { useInvalidateInstalledPluginList } from '@/service/use-plugins'
import { usePluginInstalledCheck } from '@/app/components/plugins/plugin-detail-panel/tool-selector/hooks'
import { CollectionType } from '@/app/components/tools/types'
import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types'
import type { ToolDefaultValue, ToolValue } from '@/app/components/workflow/block-selector/types'
import type {
OffsetOptions,
Placement,
@ -43,20 +43,13 @@ import type {
import { MARKETPLACE_API_PREFIX } from '@/config'
import cn from '@/utils/classnames'
export type ToolValue = {
provider_name: string
tool_name: string
parameters?: Record<string, any>
enabled?: boolean
extra?: Record<string, any>
}
type Props = {
disabled?: boolean
placement?: Placement
offset?: OffsetOptions
scope?: string
value?: ToolValue
selectedTools?: ToolValue[]
onSelect: (tool: {
provider_name: string
tool_name: string
@ -72,6 +65,7 @@ type Props = {
}
const ToolSelector: FC<Props> = ({
value,
selectedTools,
disabled,
placement = 'left',
offset = 4,
@ -113,6 +107,7 @@ const ToolSelector: FC<Props> = ({
provider_name: tool.provider_id,
type: tool.provider_type,
tool_name: tool.tool_name,
tool_label: tool.tool_label,
parameters: paramValues,
enabled: tool.is_team_authorization,
extra: {
@ -215,7 +210,7 @@ const ToolSelector: FC<Props> = ({
open={isShow}
icon={currentProvider?.icon || manifestIcon}
providerName={value.provider_name}
toolName={value.tool_name}
toolLabel={value.tool_label || value.tool_name}
showSwitch={supportEnableSwitch}
switchValue={value.enabled}
onSwitchChange={handleEnabledChange}
@ -264,6 +259,7 @@ const ToolSelector: FC<Props> = ({
supportAddCustomTool
onSelect={handleSelectTool}
scope={scope}
selectedTools={selectedTools}
/>
</div>
<div className='flex flex-col gap-1'>

View File

@ -21,7 +21,7 @@ import cn from '@/utils/classnames'
type Props = {
icon?: any
providerName?: string
toolName?: string
toolLabel?: string
showSwitch?: boolean
switchValue?: boolean
onSwitchChange?: (value: boolean) => void
@ -41,7 +41,7 @@ const ToolItem = ({
open,
icon,
providerName,
toolName,
toolLabel,
showSwitch,
switchValue,
onSwitchChange,
@ -83,7 +83,7 @@ const ToolItem = ({
)}
<div className={cn('pl-0.5 grow truncate', isTransparent && 'opacity-50')}>
<div className='text-text-tertiary system-2xs-medium-uppercase'>{providerNameText}</div>
<div className='text-text-secondary system-xs-medium'>{toolName}</div>
<div className='text-text-secondary system-xs-medium'>{toolLabel}</div>
</div>
<div className='hidden group-hover:flex items-center gap-1'>
{!noAuth && !isError && !uninstalled && !versionMismatch && (

View File

@ -8,6 +8,7 @@ import type {
OnSelectBlock,
ToolWithProvider,
} from '../types'
import type { ToolValue } from './types'
import { ToolTypeEnum } from './types'
import Tools from './tools'
import { useToolTabs } from './hooks'
@ -32,6 +33,7 @@ type AllToolsProps = {
supportAddCustomTool?: boolean
onAddedCustomTool?: () => void
onShowAddCustomCollectionModal?: () => void
selectedTools?: ToolValue[]
}
const AllTools = ({
className,
@ -44,6 +46,7 @@ const AllTools = ({
customTools,
supportAddCustomTool,
onShowAddCustomCollectionModal,
selectedTools,
}: AllToolsProps) => {
const language = useGetLanguage()
const tabs = useToolTabs()
@ -138,6 +141,7 @@ const AllTools = ({
onSelect={onSelect}
viewType={activeView}
hasSearchText={!!searchText}
selectedTools={selectedTools}
/>
{/* Plugins from marketplace */}
<PluginList

View File

@ -12,7 +12,7 @@ import type {
Placement,
} from '@floating-ui/react'
import AllTools from '@/app/components/workflow/block-selector/all-tools'
import type { ToolDefaultValue } from './types'
import type { ToolDefaultValue, ToolValue } from './types'
import type { BlockEnum } from '@/app/components/workflow/types'
import SearchBox from '@/app/components/plugins/marketplace/search-box'
import { useTranslation } from 'react-i18next'
@ -35,6 +35,7 @@ type Props = {
onSelect: (tool: ToolDefaultValue) => void
supportAddCustomTool?: boolean
scope?: string
selectedTools?: ToolValue[]
}
const ToolPicker: FC<Props> = ({
@ -47,6 +48,7 @@ const ToolPicker: FC<Props> = ({
onSelect,
supportAddCustomTool,
scope = 'all',
selectedTools,
}) => {
const { t } = useTranslation()
const [searchText, setSearchText] = useState('')
@ -160,6 +162,7 @@ const ToolPicker: FC<Props> = ({
supportAddCustomTool={supportAddCustomTool}
onAddedCustomTool={handleAddedCustomTool}
onShowAddCustomCollectionModal={showEditCustomCollectionModal}
selectedTools={selectedTools}
/>
</div>
</PortalToFollowElemContent>

View File

@ -8,10 +8,15 @@ import Tooltip from '@/app/components/base/tooltip'
import type { Tool } from '@/app/components/tools/types'
import { useGetLanguage } from '@/context/i18n'
import BlockIcon from '../../block-icon'
import cn from '@/utils/classnames'
import { useTranslation } from 'react-i18next'
import { RiCheckLine } from '@remixicon/react'
import Badge from '@/app/components/base/badge'
type Props = {
provider: ToolWithProvider
payload: Tool
disabled?: boolean
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
}
@ -19,7 +24,10 @@ const ToolItem: FC<Props> = ({
provider,
payload,
onSelect,
disabled,
}) => {
const { t } = useTranslation()
const language = useGetLanguage()
return (
@ -42,8 +50,9 @@ const ToolItem: FC<Props> = ({
>
<div
key={payload.name}
className='rounded-lg pl-[21px] hover:bg-state-base-hover cursor-pointer'
className='flex justify-between items-center pr-1 rounded-lg pl-[21px] hover:bg-state-base-hover cursor-pointer'
onClick={() => {
if (disabled) return
const params: Record<string, string> = {}
if (payload.parameters) {
payload.parameters.forEach((item) => {
@ -64,7 +73,15 @@ const ToolItem: FC<Props> = ({
})
}}
>
<div className='h-8 leading-8 border-l-2 border-divider-subtle pl-4 truncate text-text-secondary system-sm-medium'>{payload.label[language]}</div>
<div className={cn('h-8 leading-8 border-l-2 border-divider-subtle pl-4 truncate text-text-secondary system-sm-medium', disabled && 'opacity-30')}>{payload.label[language]}</div>
{disabled && <Badge
className='flex items-center h-5 text-text-tertiary space-x-0.5'
uppercase
>
<RiCheckLine className='w-3 h-3 ' />
<div>{t('tools.addToolModal.added')}</div>
</Badge>
}
</div>
</Tooltip >
)

View File

@ -3,7 +3,7 @@ import type { FC } from 'react'
import React from 'react'
import type { ToolWithProvider } from '../../../types'
import type { BlockEnum } from '../../../types'
import type { ToolDefaultValue } from '../../types'
import type { ToolDefaultValue, ToolValue } from '../../types'
import Tool from '../tool'
import { ViewType } from '../../view-type-select'
import { useMemo } from 'react'
@ -15,6 +15,7 @@ type Props = {
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
letters: string[]
toolRefs: any
selectedTools?: ToolValue[]
}
const ToolViewFlatView: FC<Props> = ({
@ -24,6 +25,7 @@ const ToolViewFlatView: FC<Props> = ({
hasSearchText,
onSelect,
toolRefs,
selectedTools,
}) => {
const firstLetterToolIds = useMemo(() => {
const res: Record<string, string> = {}
@ -51,6 +53,7 @@ const ToolViewFlatView: FC<Props> = ({
isShowLetterIndex={isShowLetterIndex}
hasSearchText={hasSearchText}
onSelect={onSelect}
selectedTools={selectedTools}
/>
</div>
))}

View File

@ -5,13 +5,14 @@ import type { ToolWithProvider } from '../../../types'
import Tool from '../tool'
import type { BlockEnum } from '../../../types'
import { ViewType } from '../../view-type-select'
import type { ToolDefaultValue } from '../../types'
import type { ToolDefaultValue, ToolValue } from '../../types'
type Props = {
groupName: string
toolList: ToolWithProvider[]
hasSearchText: boolean
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
selectedTools?: ToolValue[]
}
const Item: FC<Props> = ({
@ -19,6 +20,7 @@ const Item: FC<Props> = ({
toolList,
hasSearchText,
onSelect,
selectedTools,
}) => {
return (
<div>
@ -34,6 +36,7 @@ const Item: FC<Props> = ({
isShowLetterIndex={false}
hasSearchText={hasSearchText}
onSelect={onSelect}
selectedTools={selectedTools}
/>
))}
</div>

View File

@ -3,7 +3,7 @@ import type { FC } from 'react'
import React, { useCallback } from 'react'
import type { ToolWithProvider } from '../../../types'
import type { BlockEnum } from '../../../types'
import type { ToolDefaultValue } from '../../types'
import type { ToolDefaultValue, ToolValue } from '../../types'
import Item from './item'
import { useTranslation } from 'react-i18next'
import { AGENT_GROUP_NAME, CUSTOM_GROUP_NAME, WORKFLOW_GROUP_NAME } from '../../index-bar'
@ -12,12 +12,14 @@ type Props = {
payload: Record<string, ToolWithProvider[]>
hasSearchText: boolean
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
selectedTools?: ToolValue[]
}
const ToolListTreeView: FC<Props> = ({
payload,
hasSearchText,
onSelect,
selectedTools,
}) => {
const { t } = useTranslation()
const getI18nGroupName = useCallback((name: string) => {
@ -44,6 +46,7 @@ const ToolListTreeView: FC<Props> = ({
toolList={payload[groupName]}
hasSearchText={hasSearchText}
onSelect={onSelect}
selectedTools={selectedTools}
/>
))}
</div>

View File

@ -4,10 +4,11 @@ import React, { useEffect, useMemo } from 'react'
import cn from '@/utils/classnames'
import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react'
import { useGetLanguage } from '@/context/i18n'
import type { Tool as ToolType } from '../../../tools/types'
import { CollectionType } from '../../../tools/types'
import type { ToolWithProvider } from '../../types'
import { BlockEnum } from '../../types'
import type { ToolDefaultValue } from '../types'
import type { ToolDefaultValue, ToolValue } from '../types'
import { ViewType } from '../view-type-select'
import ActonItem from './action-item'
import BlockIcon from '../../block-icon'
@ -20,6 +21,7 @@ type Props = {
isShowLetterIndex: boolean
hasSearchText: boolean
onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void
selectedTools?: ToolValue[]
}
const Tool: FC<Props> = ({
@ -29,6 +31,7 @@ const Tool: FC<Props> = ({
isShowLetterIndex,
hasSearchText,
onSelect,
selectedTools,
}) => {
const { t } = useTranslation()
const language = useGetLanguage()
@ -36,6 +39,10 @@ const Tool: FC<Props> = ({
const actions = payload.tools
const hasAction = true // Now always support actions
const [isFold, setFold] = React.useState<boolean>(true)
const getIsDisabled = (tool: ToolType) => {
if (!selectedTools || !selectedTools.length) return false
return selectedTools.some(selectedTool => selectedTool.provider_name === payload.name && selectedTool.tool_name === tool.name)
}
useEffect(() => {
if (hasSearchText && isFold) {
setFold(false)
@ -116,6 +123,7 @@ const Tool: FC<Props> = ({
provider={payload}
payload={action}
onSelect={onSelect}
disabled={getIsDisabled(action)}
/>
))
)}

View File

@ -6,7 +6,7 @@ import {
import { useTranslation } from 'react-i18next'
import type { BlockEnum, ToolWithProvider } from '../types'
import IndexBar, { groupItems } from './index-bar'
import type { ToolDefaultValue } from './types'
import type { ToolDefaultValue, ToolValue } from './types'
import { ViewType } from './view-type-select'
import Empty from '@/app/components/tools/add-tool-modal/empty'
import { useGetLanguage } from '@/context/i18n'
@ -22,6 +22,7 @@ type ToolsProps = {
hasSearchText: boolean
className?: string
indexBarClassName?: string
selectedTools?: ToolValue[]
}
const Blocks = ({
showWorkflowEmpty,
@ -31,6 +32,7 @@ const Blocks = ({
hasSearchText,
className,
indexBarClassName,
selectedTools,
}: ToolsProps) => {
const { t } = useTranslation()
const language = useGetLanguage()
@ -105,12 +107,14 @@ const Blocks = ({
isShowLetterIndex={isShowLetterIndex}
hasSearchText={hasSearchText}
onSelect={onSelect}
selectedTools={selectedTools}
/>
) : (
<ToolListTreeView
payload={treeViewToolsData}
hasSearchText={hasSearchText}
onSelect={onSelect}
selectedTools={selectedTools}
/>
)
)}

View File

@ -30,3 +30,12 @@ export type ToolDefaultValue = {
paramSchemas: Record<string, any>[]
output_schema: Record<string, any>
}
export type ToolValue = {
provider_name: string
tool_name: string
tool_label: string
parameters?: Record<string, any>
enabled?: boolean
extra?: Record<string, any>
}