| import { useCallback, useEffect, useMemo, useState } from 'react' |
| import { useTranslation } from 'react-i18next' |
| import produce from 'immer' |
| import { useBoolean } from 'ahooks' |
| import { useStore } from '../../store' |
| import { type ToolNodeType, type ToolVarInputs, VarType } from './types' |
| import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' |
| import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' |
| import { CollectionType } from '@/app/components/tools/types' |
| import { updateBuiltInToolCredential } from '@/service/tools' |
| import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema' |
| import Toast from '@/app/components/base/toast' |
| import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form' |
| import { VarType as VarVarType } from '@/app/components/workflow/types' |
| import type { InputVar, ValueSelector, Var } from '@/app/components/workflow/types' |
| import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run' |
| import { |
| useFetchToolsData, |
| useNodesReadOnly, |
| } from '@/app/components/workflow/hooks' |
|
|
| const useConfig = (id: string, payload: ToolNodeType) => { |
| const { nodesReadOnly: readOnly } = useNodesReadOnly() |
| const { handleFetchAllTools } = useFetchToolsData() |
| const { t } = useTranslation() |
|
|
| const language = useLanguage() |
| const { inputs, setInputs: doSetInputs } = useNodeCrud<ToolNodeType>(id, payload) |
| |
| |
| |
| |
| const { provider_id, provider_type, tool_name, tool_configurations } = inputs |
| const isBuiltIn = provider_type === CollectionType.builtIn |
| const buildInTools = useStore(s => s.buildInTools) |
| const customTools = useStore(s => s.customTools) |
| const workflowTools = useStore(s => s.workflowTools) |
|
|
| const currentTools = (() => { |
| switch (provider_type) { |
| case CollectionType.builtIn: |
| return buildInTools |
| case CollectionType.custom: |
| return customTools |
| case CollectionType.workflow: |
| return workflowTools |
| default: |
| return [] |
| } |
| })() |
| const currCollection = currentTools.find(item => item.id === provider_id) |
|
|
| |
| const needAuth = !!currCollection?.allow_delete |
| const isAuthed = !!currCollection?.is_team_authorization |
| const isShowAuthBtn = isBuiltIn && needAuth && !isAuthed |
| const [showSetAuth, { |
| setTrue: showSetAuthModal, |
| setFalse: hideSetAuthModal, |
| }] = useBoolean(false) |
|
|
| const handleSaveAuth = useCallback(async (value: any) => { |
| await updateBuiltInToolCredential(currCollection?.name as string, value) |
|
|
| Toast.notify({ |
| type: 'success', |
| message: t('common.api.actionSuccess'), |
| }) |
| handleFetchAllTools(provider_type) |
| hideSetAuthModal() |
| }, [currCollection?.name, hideSetAuthModal, t, handleFetchAllTools, provider_type]) |
|
|
| const currTool = currCollection?.tools.find(tool => tool.name === tool_name) |
| const formSchemas = useMemo(() => { |
| return currTool ? toolParametersToFormSchemas(currTool.parameters) : [] |
| }, [currTool]) |
| const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm') |
| |
| const toolSettingSchema = formSchemas.filter((item: any) => item.form !== 'llm') |
| const hasShouldTransferTypeSettingInput = toolSettingSchema.some(item => item.type === 'boolean' || item.type === 'number-input') |
|
|
| const setInputs = useCallback((value: ToolNodeType) => { |
| if (!hasShouldTransferTypeSettingInput) { |
| doSetInputs(value) |
| return |
| } |
| const newInputs = produce(value, (draft) => { |
| const newConfig = { ...draft.tool_configurations } |
| Object.keys(draft.tool_configurations).forEach((key) => { |
| const schema = formSchemas.find(item => item.variable === key) |
| const value = newConfig[key] |
| if (schema?.type === 'boolean') { |
| if (typeof value === 'string') |
| newConfig[key] = parseInt(value, 10) |
|
|
| if (typeof value === 'boolean') |
| newConfig[key] = value ? 1 : 0 |
| } |
|
|
| if (schema?.type === 'number-input') { |
| if (typeof value === 'string' && value !== '') |
| newConfig[key] = parseFloat(value) |
| } |
| }) |
| draft.tool_configurations = newConfig |
| }) |
| doSetInputs(newInputs) |
| }, [doSetInputs, formSchemas, hasShouldTransferTypeSettingInput]) |
| const [notSetDefaultValue, setNotSetDefaultValue] = useState(false) |
| const toolSettingValue = (() => { |
| if (notSetDefaultValue) |
| return tool_configurations |
|
|
| return addDefaultValue(tool_configurations, toolSettingSchema) |
| })() |
| const setToolSettingValue = useCallback((value: Record<string, any>) => { |
| setNotSetDefaultValue(true) |
| setInputs({ |
| ...inputs, |
| tool_configurations: value, |
| }) |
| }, [inputs, setInputs]) |
|
|
| useEffect(() => { |
| if (!currTool) |
| return |
| const inputsWithDefaultValue = produce(inputs, (draft) => { |
| if (!draft.tool_configurations || Object.keys(draft.tool_configurations).length === 0) |
| draft.tool_configurations = addDefaultValue(tool_configurations, toolSettingSchema) |
|
|
| if (!draft.tool_parameters) |
| draft.tool_parameters = {} |
| }) |
| setInputs(inputsWithDefaultValue) |
| |
| }, [currTool]) |
|
|
| |
| const setInputVar = useCallback((value: ToolVarInputs) => { |
| setInputs({ |
| ...inputs, |
| tool_parameters: value, |
| }) |
| }, [inputs, setInputs]) |
|
|
| const [currVarIndex, setCurrVarIndex] = useState(-1) |
| const currVarType = toolInputVarSchema[currVarIndex]?._type |
| const handleOnVarOpen = useCallback((index: number) => { |
| setCurrVarIndex(index) |
| }, []) |
|
|
| const filterVar = useCallback((varPayload: Var) => { |
| if (currVarType) |
| return varPayload.type === currVarType |
|
|
| return varPayload.type !== VarVarType.arrayFile |
| }, [currVarType]) |
|
|
| const isLoading = currTool && (isBuiltIn ? !currCollection : false) |
|
|
| |
| const [inputVarValues, doSetInputVarValues] = useState<Record<string, any>>({}) |
| const setInputVarValues = (value: Record<string, any>) => { |
| doSetInputVarValues(value) |
| |
| setRunInputData(value) |
| } |
| |
| const inputVarValuesWithConstantValue = () => { |
| const res = produce(inputVarValues, (draft) => { |
| Object.keys(inputs.tool_parameters).forEach((key: string) => { |
| const { type, value } = inputs.tool_parameters[key] |
| if (type === VarType.constant && (value === undefined || value === null)) |
| draft.tool_parameters[key].value = value |
| }) |
| }) |
| return res |
| } |
|
|
| const { |
| isShowSingleRun, |
| hideSingleRun, |
| getInputVars, |
| runningStatus, |
| setRunInputData, |
| handleRun: doHandleRun, |
| handleStop, |
| runResult, |
| } = useOneStepRun<ToolNodeType>({ |
| id, |
| data: inputs, |
| defaultRunInputData: {}, |
| moreDataForCheckValid: { |
| toolInputsSchema: (() => { |
| const formInputs: InputVar[] = [] |
| toolInputVarSchema.forEach((item: any) => { |
| formInputs.push({ |
| label: item.label[language] || item.label.en_US, |
| variable: item.variable, |
| type: item.type, |
| required: item.required, |
| }) |
| }) |
| return formInputs |
| })(), |
| notAuthed: isShowAuthBtn, |
| toolSettingSchema, |
| language, |
| }, |
| }) |
|
|
| const hadVarParams = Object.keys(inputs.tool_parameters) |
| .filter(key => inputs.tool_parameters[key].type !== VarType.constant) |
| .map(k => inputs.tool_parameters[k]) |
|
|
| const varInputs = getInputVars(hadVarParams.map((p) => { |
| if (p.type === VarType.variable) |
| return `{{#${(p.value as ValueSelector).join('.')}#}}` |
|
|
| return p.value as string |
| })) |
|
|
| const singleRunForms = (() => { |
| const forms: FormProps[] = [{ |
| inputs: varInputs, |
| values: inputVarValuesWithConstantValue(), |
| onChange: setInputVarValues, |
| }] |
| return forms |
| })() |
|
|
| const handleRun = (submitData: Record<string, any>) => { |
| const varTypeInputKeys = Object.keys(inputs.tool_parameters) |
| .filter(key => inputs.tool_parameters[key].type === VarType.variable) |
| const shouldAdd = varTypeInputKeys.length > 0 |
| if (!shouldAdd) { |
| doHandleRun(submitData) |
| return |
| } |
| const addMissedVarData = { ...submitData } |
| Object.keys(submitData).forEach((key) => { |
| const value = submitData[key] |
| varTypeInputKeys.forEach((inputKey) => { |
| const inputValue = inputs.tool_parameters[inputKey].value as ValueSelector |
| if (`#${inputValue.join('.')}#` === key) |
| addMissedVarData[inputKey] = value |
| }) |
| }) |
| doHandleRun(addMissedVarData) |
| } |
|
|
| return { |
| readOnly, |
| inputs, |
| currTool, |
| toolSettingSchema, |
| toolSettingValue, |
| setToolSettingValue, |
| toolInputVarSchema, |
| setInputVar, |
| handleOnVarOpen, |
| filterVar, |
| currCollection, |
| isShowAuthBtn, |
| showSetAuth, |
| showSetAuthModal, |
| hideSetAuthModal, |
| handleSaveAuth, |
| isLoading, |
| isShowSingleRun, |
| hideSingleRun, |
| inputVarValues, |
| varInputs, |
| setInputVarValues, |
| singleRunForms, |
| runningStatus, |
| handleRun, |
| handleStop, |
| runResult, |
| } |
| } |
|
|
| export default useConfig |
|
|