| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 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'import { canFindTool } from '@/utils'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)  * output_schema: tool dynamic output  */  const { provider_id, provider_type, tool_name, tool_configurations, output_schema } = 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 => canFindTool(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] = Number.parseInt(value, 10)          if (typeof value === 'boolean')            newConfig[key] = value ? 1 : 0        }        if (schema?.type === 'number-input') {          if (typeof value === 'string' && value !== '')            newConfig[key] = Number.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 ts/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) {      // handle the old wrong value not crash the page      if (!(p.value as any).join)        return `{{#${p.value}#}}`      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)  }  const outputSchema = useMemo(() => {    const res: any[] = []    if (!output_schema)      return []    Object.keys(output_schema.properties).forEach((outputKey) => {      const output = output_schema.properties[outputKey]      res.push({        name: outputKey,        type: output.type === 'array'          ? `Array[${output.items?.type.slice(0, 1).toLocaleUpperCase()}${output.items?.type.slice(1)}]`          : `${output.type.slice(0, 1).toLocaleUpperCase()}${output.type.slice(1)}`,        description: output.description,      })    })    return res  }, [output_schema])  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,    outputSchema,  }}export default useConfig
 |