Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

use-config.ts 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import { useCallback, useEffect, useMemo, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import produce from 'immer'
  4. import { useBoolean } from 'ahooks'
  5. import { useStore } from '../../store'
  6. import type { ToolNodeType, ToolVarInputs } from './types'
  7. import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
  8. import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
  9. import { CollectionType } from '@/app/components/tools/types'
  10. import { updateBuiltInToolCredential } from '@/service/tools'
  11. import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
  12. import Toast from '@/app/components/base/toast'
  13. import { VarType as VarVarType } from '@/app/components/workflow/types'
  14. import type { InputVar, Var } from '@/app/components/workflow/types'
  15. import {
  16. useFetchToolsData,
  17. useNodesReadOnly,
  18. } from '@/app/components/workflow/hooks'
  19. import { canFindTool } from '@/utils'
  20. const useConfig = (id: string, payload: ToolNodeType) => {
  21. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  22. const { handleFetchAllTools } = useFetchToolsData()
  23. const { t } = useTranslation()
  24. const language = useLanguage()
  25. const { inputs, setInputs: doSetInputs } = useNodeCrud<ToolNodeType>(id, payload)
  26. /*
  27. * tool_configurations: tool setting, not dynamic setting
  28. * tool_parameters: tool dynamic setting(by user)
  29. * output_schema: tool dynamic output
  30. */
  31. const { provider_id, provider_type, tool_name, tool_configurations, output_schema } = inputs
  32. const isBuiltIn = provider_type === CollectionType.builtIn
  33. const buildInTools = useStore(s => s.buildInTools)
  34. const customTools = useStore(s => s.customTools)
  35. const workflowTools = useStore(s => s.workflowTools)
  36. const currentTools = (() => {
  37. switch (provider_type) {
  38. case CollectionType.builtIn:
  39. return buildInTools
  40. case CollectionType.custom:
  41. return customTools
  42. case CollectionType.workflow:
  43. return workflowTools
  44. default:
  45. return []
  46. }
  47. })()
  48. const currCollection = currentTools.find(item => canFindTool(item.id, provider_id))
  49. // Auth
  50. const needAuth = !!currCollection?.allow_delete
  51. const isAuthed = !!currCollection?.is_team_authorization
  52. const isShowAuthBtn = isBuiltIn && needAuth && !isAuthed
  53. const [showSetAuth, {
  54. setTrue: showSetAuthModal,
  55. setFalse: hideSetAuthModal,
  56. }] = useBoolean(false)
  57. const handleSaveAuth = useCallback(async (value: any) => {
  58. await updateBuiltInToolCredential(currCollection?.name as string, value)
  59. Toast.notify({
  60. type: 'success',
  61. message: t('common.api.actionSuccess'),
  62. })
  63. handleFetchAllTools(provider_type)
  64. hideSetAuthModal()
  65. }, [currCollection?.name, hideSetAuthModal, t, handleFetchAllTools, provider_type])
  66. const currTool = currCollection?.tools.find(tool => tool.name === tool_name)
  67. const formSchemas = useMemo(() => {
  68. return currTool ? toolParametersToFormSchemas(currTool.parameters) : []
  69. }, [currTool])
  70. const toolInputVarSchema = formSchemas.filter((item: any) => item.form === 'llm')
  71. // use setting
  72. const toolSettingSchema = formSchemas.filter((item: any) => item.form !== 'llm')
  73. const hasShouldTransferTypeSettingInput = toolSettingSchema.some(item => item.type === 'boolean' || item.type === 'number-input')
  74. const setInputs = useCallback((value: ToolNodeType) => {
  75. if (!hasShouldTransferTypeSettingInput) {
  76. doSetInputs(value)
  77. return
  78. }
  79. const newInputs = produce(value, (draft) => {
  80. const newConfig = { ...draft.tool_configurations }
  81. Object.keys(draft.tool_configurations).forEach((key) => {
  82. const schema = formSchemas.find(item => item.variable === key)
  83. const value = newConfig[key]
  84. if (schema?.type === 'boolean') {
  85. if (typeof value === 'string')
  86. newConfig[key] = Number.parseInt(value, 10)
  87. if (typeof value === 'boolean')
  88. newConfig[key] = value ? 1 : 0
  89. }
  90. if (schema?.type === 'number-input') {
  91. if (typeof value === 'string' && value !== '')
  92. newConfig[key] = Number.parseFloat(value)
  93. }
  94. })
  95. draft.tool_configurations = newConfig
  96. })
  97. doSetInputs(newInputs)
  98. }, [doSetInputs, formSchemas, hasShouldTransferTypeSettingInput])
  99. const [notSetDefaultValue, setNotSetDefaultValue] = useState(false)
  100. const toolSettingValue = (() => {
  101. if (notSetDefaultValue)
  102. return tool_configurations
  103. return addDefaultValue(tool_configurations, toolSettingSchema)
  104. })()
  105. const setToolSettingValue = useCallback((value: Record<string, any>) => {
  106. setNotSetDefaultValue(true)
  107. setInputs({
  108. ...inputs,
  109. tool_configurations: value,
  110. })
  111. }, [inputs, setInputs])
  112. useEffect(() => {
  113. if (!currTool)
  114. return
  115. const inputsWithDefaultValue = produce(inputs, (draft) => {
  116. if (!draft.tool_configurations || Object.keys(draft.tool_configurations).length === 0)
  117. draft.tool_configurations = addDefaultValue(tool_configurations, toolSettingSchema)
  118. if (!draft.tool_parameters)
  119. draft.tool_parameters = {}
  120. })
  121. setInputs(inputsWithDefaultValue)
  122. // eslint-disable-next-line react-hooks/exhaustive-deps
  123. }, [currTool])
  124. // setting when call
  125. const setInputVar = useCallback((value: ToolVarInputs) => {
  126. setInputs({
  127. ...inputs,
  128. tool_parameters: value,
  129. })
  130. }, [inputs, setInputs])
  131. const [currVarIndex, setCurrVarIndex] = useState(-1)
  132. const currVarType = toolInputVarSchema[currVarIndex]?._type
  133. const handleOnVarOpen = useCallback((index: number) => {
  134. setCurrVarIndex(index)
  135. }, [])
  136. const filterVar = useCallback((varPayload: Var) => {
  137. if (currVarType)
  138. return varPayload.type === currVarType
  139. return varPayload.type !== VarVarType.arrayFile
  140. }, [currVarType])
  141. const isLoading = currTool && (isBuiltIn ? !currCollection : false)
  142. const getMoreDataForCheckValid = () => {
  143. return {
  144. toolInputsSchema: (() => {
  145. const formInputs: InputVar[] = []
  146. toolInputVarSchema.forEach((item: any) => {
  147. formInputs.push({
  148. label: item.label[language] || item.label.en_US,
  149. variable: item.variable,
  150. type: item.type,
  151. required: item.required,
  152. })
  153. })
  154. return formInputs
  155. })(),
  156. notAuthed: isShowAuthBtn,
  157. toolSettingSchema,
  158. language,
  159. }
  160. }
  161. const outputSchema = useMemo(() => {
  162. const res: any[] = []
  163. if (!output_schema)
  164. return []
  165. Object.keys(output_schema.properties).forEach((outputKey) => {
  166. const output = output_schema.properties[outputKey]
  167. const type = output.type
  168. if (type === 'object') {
  169. res.push({
  170. name: outputKey,
  171. value: output,
  172. })
  173. }
  174. else {
  175. res.push({
  176. name: outputKey,
  177. type: output.type === 'array'
  178. ? `Array[${output.items?.type.slice(0, 1).toLocaleUpperCase()}${output.items?.type.slice(1)}]`
  179. : `${output.type.slice(0, 1).toLocaleUpperCase()}${output.type.slice(1)}`,
  180. description: output.description,
  181. })
  182. }
  183. })
  184. return res
  185. }, [output_schema])
  186. const hasObjectOutput = useMemo(() => {
  187. if (!output_schema)
  188. return false
  189. const properties = output_schema.properties
  190. return Object.keys(properties).some(key => properties[key].type === 'object')
  191. }, [output_schema])
  192. return {
  193. readOnly,
  194. inputs,
  195. currTool,
  196. toolSettingSchema,
  197. toolSettingValue,
  198. setToolSettingValue,
  199. toolInputVarSchema,
  200. setInputVar,
  201. handleOnVarOpen,
  202. filterVar,
  203. currCollection,
  204. isShowAuthBtn,
  205. showSetAuth,
  206. showSetAuthModal,
  207. hideSetAuthModal,
  208. handleSaveAuth,
  209. isLoading,
  210. outputSchema,
  211. hasObjectOutput,
  212. getMoreDataForCheckValid,
  213. }
  214. }
  215. export default useConfig