123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- 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)
- /*
- * tool_configurations: tool setting, not dynamic setting
- * tool_parameters: tool dynamic setting(by user)
- */
- 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)
- // Auth
- 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')
- // use setting
- 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)
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [currTool])
- // setting when call
- 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)
- // single run
- const [inputVarValues, doSetInputVarValues] = useState<Record<string, any>>({})
- const setInputVarValues = (value: Record<string, any>) => {
- doSetInputVarValues(value)
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- setRunInputData(value)
- }
- // fill single run form variable with constant value first time
- 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
|