From f51f4a58437f5f0fed9c7d91395bcf411be21221 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 8 Mar 2024 15:43:01 +0800 Subject: [PATCH] feat: tool inputs --- .../workflow/nodes/_base/components/field.tsx | 2 +- .../nodes/tool/components/input-var-list.tsx | 86 +++++++++++++++++++ .../components/workflow/nodes/tool/panel.tsx | 25 ++++-- .../workflow/nodes/tool/use-config.ts | 19 ++-- 4 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 web/app/components/workflow/nodes/tool/components/input-var-list.tsx diff --git a/web/app/components/workflow/nodes/_base/components/field.tsx b/web/app/components/workflow/nodes/_base/components/field.tsx index e022fa10ea..2c3f9ac166 100644 --- a/web/app/components/workflow/nodes/_base/components/field.tsx +++ b/web/app/components/workflow/nodes/_base/components/field.tsx @@ -31,7 +31,7 @@ const Filed: FC = ({
-
{title}
+
{title}
{tooltip && ( diff --git a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx new file mode 100644 index 0000000000..24297d7532 --- /dev/null +++ b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx @@ -0,0 +1,86 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import produce from 'immer' +import type { ToolVarInput } from '../types' +import { VarType } from '../types' +import type { CredentialFormSchema } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { FormTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' +import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' + +type Props = { + readOnly: boolean + schema: CredentialFormSchema[] + value: ToolVarInput[] + onChange: (value: ToolVarInput[]) => void +} + +const InputVarList: FC = ({ + readOnly, + schema, + value, + onChange, +}) => { + const language = useLanguage() + + const keyValues = (() => { + const res: Record = {} + value.forEach((item) => { + res[item.variable] = item + }) + return res + })() + + const handleChange = useCallback((variable: string) => { + return (varValue: any) => { + const newValue = produce(value, (draft: ToolVarInput[]) => { + const target = draft.find(item => item.variable === variable) + if (target) { + target.value_selector = varValue // TODO: support constant value + } + else { + draft.push({ + variable, + variable_type: VarType.selector, // TODO: support constant value + value_selector: varValue, + }) + } + }) + onChange(newValue) + } + }, [value, onChange]) + + return ( +
+ { + schema.map(({ + variable, + label, + type, + required, + tooltip, + }) => { + const varInput = keyValues[variable] + return ( +
+
+ {label[language] || label.en_US} + {type === FormTypeEnum.textNumber ? 'Number' : 'String'} + {required && Required} +
+ + {tooltip &&
{tooltip[language] || tooltip.en_US}
} +
+ ) + }) + } +
+ ) +} +export default React.memo(InputVarList) diff --git a/web/app/components/workflow/nodes/tool/panel.tsx b/web/app/components/workflow/nodes/tool/panel.tsx index c828a1d71c..e03f545eb1 100644 --- a/web/app/components/workflow/nodes/tool/panel.tsx +++ b/web/app/components/workflow/nodes/tool/panel.tsx @@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next' import Split from '../_base/components/split' import type { ToolNodeType } from './types' import useConfig from './use-config' +import InputVarList from './components/input-var-list' import Button from '@/app/components/base/button' import Field from '@/app/components/workflow/nodes/_base/components/field' import type { NodePanelProps } from '@/app/components/workflow/types' @@ -20,6 +21,8 @@ const Panel: FC> = ({ const { inputs, + toolInputVarSchema, + setInputVar, toolSettingSchema, toolSettingValue, setToolSettingValue, @@ -41,12 +44,22 @@ const Panel: FC> = ({ )}
- - inputVars - - + {toolInputVarSchema.length > 0 && ( + <> + + + + + + )} +
{ const { inputs, setInputs } = useNodeCrud(id, payload) - const { provider_id, provider_type, tool_name, tool_parameters } = inputs + const { provider_id, provider_name, provider_type, tool_name, tool_parameters } = inputs const isBuiltIn = provider_type === CollectionType.builtIn const [currTool, setCurrTool] = useState(null) const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : [] @@ -26,21 +26,30 @@ const useConfig = (id: string, payload: ToolNodeType) => { }, [inputs, setInputs]) // setting when call - const toolInputSchema = formSchemas.filter((item: any) => item.form === 'llm') + const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm') + const setInputVar = useCallback((value: ToolVarInput[]) => { + setInputs({ + ...inputs, + tool_inputs: value, + }) + }, [inputs, setInputs]) + useEffect(() => { (async () => { - const list = isBuiltIn ? await fetchBuiltInToolList(provider_id) : await fetchCustomToolList(provider_id) + const list = isBuiltIn ? await fetchBuiltInToolList(provider_name || provider_id) : await fetchCustomToolList(provider_name) const currTool = list.find(tool => tool.name === tool_name) if (currTool) setCurrTool(currTool) })() - }, [provider_id]) + }, [provider_name]) return { inputs, currTool, toolSettingSchema, toolSettingValue, setToolSettingValue, + toolInputVarSchema, + setInputVar, } }