add multiple tool selector

This commit is contained in:
JzoNg 2024-12-27 16:30:19 +08:00
parent 3a5170716b
commit 573c8f909c
8 changed files with 149 additions and 27 deletions

View File

@ -17,6 +17,7 @@ export enum FormTypeEnum {
file = 'file',
modelSelector = 'model-selector',
toolSelector = 'tool-selector',
multiToolSelector = 'array[tools]',
appSelector = 'app-selector',
}

View File

@ -19,6 +19,7 @@ import Tooltip from '@/app/components/base/tooltip'
import Radio from '@/app/components/base/radio'
import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector'
import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-selector'
import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector'
import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-selector'
import RadioE from '@/app/components/base/radio/ui'
@ -328,7 +329,35 @@ function Form<
scope={scope}
disabled={readonly}
value={value[variable]}
onSelect={item => handleFormChange(variable, item as any)} />
onSelect={item => handleFormChange(variable, item as any)}
onDelete={() => handleFormChange(variable, null as any)}
/>
{fieldMoreInfo?.(formSchema)}
{validating && changeKey === variable && <ValidatingTip />}
</div>
)
}
if (formSchema.type === FormTypeEnum.multiToolSelector) {
const {
variable,
label,
tooltip,
required,
scope,
} = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
return (
<div key={variable} className={cn(itemClassName, 'py-3')}>
<MultipleToolSelector
disabled={readonly}
scope={scope}
label={label[language] || label.en_US}
required={required}
tooltip={tooltip?.[language] || tooltip?.en_US}
value={value[variable]}
onChange={item => handleFormChange(variable, item as any)}
/>
{fieldMoreInfo?.(formSchema)}
{validating && changeKey === variable && <ValidatingTip />}
</div>

View File

@ -7,7 +7,6 @@ import ActionList from './action-list'
import ModelList from './model-list'
import AgentStrategyList from './agent-strategy-list'
import Drawer from '@/app/components/base/drawer'
import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-selector'
import type { PluginDetail } from '@/app/components/plugins/types'
import cn from '@/utils/classnames'
@ -33,9 +32,6 @@ const PluginDetailPanel: FC<Props> = ({
console.log('tool change', val)
setValue(val)
}
const testDelete = () => {
setValue(undefined)
}
if (!detail)
return null
@ -62,15 +58,13 @@ const PluginDetailPanel: FC<Props> = ({
{!!detail.declaration.agent_strategy && <AgentStrategyList detail={detail} />}
{!!detail.declaration.endpoint && <EndpointList detail={detail} />}
{!!detail.declaration.model && <ModelList detail={detail} />}
{false && (
<div className='px-4 py-2'>
<ToolSelector
value={value}
onSelect={item => testChange(item)}
onDelete={testDelete}
/>
</div>
)}
{/* <div className='px-4 py-2'>
<MultipleToolSelector
value={value || []}
label='TOOLS'
onChange={testChange}
/>
</div> */}
</div>
</>
)}

View File

@ -1,12 +1,91 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiAddLine,
RiArrowDropDownLine,
RiQuestionLine,
} from '@remixicon/react'
import type { ToolValue } from '@/app/components/plugins/plugin-detail-panel/tool-selector'
import ActionButton from '@/app/components/base/action-button'
import Tooltip from '@/app/components/base/tooltip'
import Divider from '@/app/components/base/divider'
import cn from '@/utils/classnames'
type Props = {
value: any[]
disabled?: boolean
value: ToolValue[]
label: string
required?: boolean
tooltip?: any
supportCollapse?: boolean
onChange: (value: ToolValue[]) => void
scope?: string
}
const MultipleToolSelector = ({ value }: Props) => {
const MultipleToolSelector = ({
value,
label,
required,
tooltip,
supportCollapse,
}: Props) => {
const { t } = useTranslation()
const [collapse, setCollapse] = React.useState(false)
const handleCollapse = () => {
if (supportCollapse)
setCollapse(!collapse)
}
return (
<div></div>
<>
<div className='flex items-center mb-1'>
<div
className={cn('relative grow flex items-center gap-0.5', supportCollapse && 'cursor-pointer')}
onClick={handleCollapse}
>
<div className='h-6 flex items-center text-text-secondary system-sm-semibold-uppercase'>{label}</div>
{required && <div className='text-error-main'>*</div>}
{tooltip && (
<Tooltip
popupContent={tooltip}
needsDelay
>
<div><RiQuestionLine className='w-3.5 h-3.5 text-text-quaternary hover:text-text-tertiary'/></div>
</Tooltip>
)}
{supportCollapse && (
<div className='absolute -left-4 top-1'>
<RiArrowDropDownLine
className={cn(
'w-4 h-4 text-text-tertiary',
collapse && 'transform -rotate-90',
)}
/>
</div>
)}
</div>
{value.length > 0 && (
<>
<div className='flex items-center gap-1 text-text-tertiary system-xs-medium'>
<span>{`${value.length}/${value.length}`}</span>
<span>{t('appDebug.agent.tools.enabled')}</span>
</div>
<Divider type='vertical' className='ml-3 mr-1 h-3' />
</>
)}
<ActionButton className='mx-1' onClick={() => {}}>
<RiAddLine className='w-4 h-4' />
</ActionButton>
</div>
{!collapse && (
<>
{value.length === 0 && (
<div className='p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.toolSelector.empty')}</div>
)}
</>
)}
</>
)
}

View File

@ -40,13 +40,16 @@ import type {
} from '@floating-ui/react'
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 = {
value?: {
provider_name: string
tool_name: string
parameters?: Record<string, any>
extra?: Record<string, any>
}
value?: ToolValue
disabled?: boolean
placement?: Placement
offset?: OffsetOptions

View File

@ -10,6 +10,7 @@ import { Agent } from '@/app/components/base/icons/src/vender/workflow'
import { InputNumber } from '@/app/components/base/input-number'
import Slider from '@/app/components/base/slider'
import ToolSelector from '@/app/components/plugins/plugin-detail-panel/tool-selector'
import MultipleToolSelector from '@/app/components/plugins/plugin-detail-panel/multiple-tool-selector'
import Field from './field'
import type { ComponentProps } from 'react'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
@ -160,18 +161,31 @@ export const AgentStrategy = (props: AgentStrategyProps) => {
props.onChange({ ...props.value, [schema.variable]: value })
}
return (
<Field title={'tool selector'} tooltip={'tool selector'}>
<Field title={schema.label[language]} tooltip={schema.tooltip?.[language]}>
<ToolSelector
scope={schema.scope}
value={value}
onSelect={item => onChange(item)}
onDelete={() => onChange(null)}
/>
</Field>
)
}
case 'array[tools]': {
return <Field title={'tool selector'} tooltip={'tool selector'}>
multiple tool selector TODO
</Field>
const value = props.value[schema.variable]
const onChange = (value: any) => {
props.onChange({ ...props.value, [schema.variable]: value })
}
return (
<MultipleToolSelector
scope={schema.scope}
value={value}
label={schema.label[language]}
tooltip={schema.tooltip?.[language]}
onChange={onChange}
supportCollapse
/>
)
}
}
}

View File

@ -73,6 +73,7 @@ const translation = {
placeholder: 'Select a tool...',
auth: 'AUTHORIZATION',
settings: 'TOOL SETTINGS',
empty: 'Click the \'+\' button to add tools. You can add multiple tools.',
},
configureApp: 'Configure App',
configureModel: 'Configure model',

View File

@ -73,6 +73,7 @@ const translation = {
placeholder: '选择工具',
auth: '授权',
settings: '工具设置',
empty: '点击 "+" 按钮添加工具。您可以添加多个工具。',
},
configureApp: '应用设置',
configureModel: '模型设置',