diff --git a/web/app/components/header/account-setting/model-provider-page/declarations.ts b/web/app/components/header/account-setting/model-provider-page/declarations.ts
index 8f0adb1259..4500ebc1f7 100644
--- a/web/app/components/header/account-setting/model-provider-page/declarations.ts
+++ b/web/app/components/header/account-setting/model-provider-page/declarations.ts
@@ -17,6 +17,7 @@ export enum FormTypeEnum {
file = 'file',
modelSelector = 'model-selector',
toolSelector = 'tool-selector',
+ multiToolSelector = 'array[tools]',
appSelector = 'app-selector',
}
diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx
index b7a9a69870..b357c2cb49 100644
--- a/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx
+++ b/web/app/components/header/account-setting/model-provider-page/model-modal/Form.tsx
@@ -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 && }
+
+ )
+ }
+
+ if (formSchema.type === FormTypeEnum.multiToolSelector) {
+ const {
+ variable,
+ label,
+ tooltip,
+ required,
+ scope,
+ } = formSchema as (CredentialFormSchemaTextInput | CredentialFormSchemaSecretInput)
+
+ return (
+
+ handleFormChange(variable, item as any)}
+ />
{fieldMoreInfo?.(formSchema)}
{validating && changeKey === variable && }
diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx
index d14c0d96be..150158e42c 100644
--- a/web/app/components/plugins/plugin-detail-panel/index.tsx
+++ b/web/app/components/plugins/plugin-detail-panel/index.tsx
@@ -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 = ({
console.log('tool change', val)
setValue(val)
}
- const testDelete = () => {
- setValue(undefined)
- }
if (!detail)
return null
@@ -62,15 +58,13 @@ const PluginDetailPanel: FC = ({
{!!detail.declaration.agent_strategy && }
{!!detail.declaration.endpoint && }
{!!detail.declaration.model && }
- {false && (
-
- testChange(item)}
- onDelete={testDelete}
- />
-
- )}
+ {/*
+
+
*/}
>
)}
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 bbf5a8a1ef..47c6833369 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
@@ -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 (
-
+ <>
+
+
+
{label}
+ {required &&
*
}
+ {tooltip && (
+
+
+
+ )}
+ {supportCollapse && (
+
+
+
+ )}
+
+ {value.length > 0 && (
+ <>
+
+ {`${value.length}/${value.length}`}
+ {t('appDebug.agent.tools.enabled')}
+
+
+ >
+ )}
+
{}}>
+
+
+
+ {!collapse && (
+ <>
+ {value.length === 0 && (
+ {t('plugin.detailPanel.toolSelector.empty')}
+ )}
+ >
+ )}
+ >
)
}
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 3e7993f761..7bf6165971 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
@@ -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
+ enabled?: boolean
+ extra?: Record
+}
+
type Props = {
- value?: {
- provider_name: string
- tool_name: string
- parameters?: Record
- extra?: Record
- }
+ value?: ToolValue
disabled?: boolean
placement?: Placement
offset?: OffsetOptions
diff --git a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
index 3f0b05b8e6..c156aac671 100644
--- a/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
+++ b/web/app/components/workflow/nodes/_base/components/agent-strategy.tsx
@@ -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 (
-
+
onChange(item)}
+ onDelete={() => onChange(null)}
/>
)
}
case 'array[tools]': {
- return
- multiple tool selector TODO
-
+ const value = props.value[schema.variable]
+ const onChange = (value: any) => {
+ props.onChange({ ...props.value, [schema.variable]: value })
+ }
+ return (
+
+ )
}
}
}
diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts
index 38ec6d9be7..a706f8f042 100644
--- a/web/i18n/en-US/plugin.ts
+++ b/web/i18n/en-US/plugin.ts
@@ -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',
diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts
index 8185f37b40..4b7c764d9f 100644
--- a/web/i18n/zh-Hans/plugin.ts
+++ b/web/i18n/zh-Hans/plugin.ts
@@ -73,6 +73,7 @@ const translation = {
placeholder: '选择工具',
auth: '授权',
settings: '工具设置',
+ empty: '点击 "+" 按钮添加工具。您可以添加多个工具。',
},
configureApp: '应用设置',
configureModel: '模型设置',