Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

use-config.ts 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. import { useCallback, useEffect, useRef, useState } from 'react'
  2. import produce from 'immer'
  3. import type { Memory, MoreInfo, ValueSelector, Var } from '../../types'
  4. import { ChangeType, VarType } from '../../types'
  5. import { useStore } from '../../store'
  6. import {
  7. useIsChatMode,
  8. useNodesReadOnly,
  9. useWorkflow,
  10. } from '../../hooks'
  11. import useConfigVision from '../../hooks/use-config-vision'
  12. import type { Param, ParameterExtractorNodeType, ReasoningModeType } from './types'
  13. import { useModelListAndDefaultModelAndCurrentProviderAndModel, useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
  14. import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
  15. import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
  16. import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
  17. import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
  18. import { supportFunctionCall } from '@/utils/tool-call'
  19. import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud'
  20. const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
  21. const {
  22. deleteNodeInspectorVars,
  23. renameInspectVarName,
  24. } = useInspectVarsCrud()
  25. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  26. const { handleOutVarRenameChange } = useWorkflow()
  27. const isChatMode = useIsChatMode()
  28. const defaultConfig = useStore(s => s.nodesDefaultConfigs)[payload.type]
  29. const [defaultRolePrefix, setDefaultRolePrefix] = useState<{ user: string; assistant: string }>({ user: '', assistant: '' })
  30. const { inputs, setInputs: doSetInputs } = useNodeCrud<ParameterExtractorNodeType>(id, payload)
  31. const inputRef = useRef(inputs)
  32. const setInputs = useCallback((newInputs: ParameterExtractorNodeType) => {
  33. if (newInputs.memory && !newInputs.memory.role_prefix) {
  34. const newPayload = produce(newInputs, (draft) => {
  35. draft.memory!.role_prefix = defaultRolePrefix
  36. })
  37. doSetInputs(newPayload)
  38. inputRef.current = newPayload
  39. return
  40. }
  41. doSetInputs(newInputs)
  42. inputRef.current = newInputs
  43. }, [doSetInputs, defaultRolePrefix])
  44. const filterVar = useCallback((varPayload: Var) => {
  45. return [VarType.string].includes(varPayload.type)
  46. }, [])
  47. const handleInputVarChange = useCallback((newInputVar: ValueSelector | string) => {
  48. const newInputs = produce(inputs, (draft) => {
  49. draft.query = newInputVar as ValueSelector || []
  50. })
  51. setInputs(newInputs)
  52. }, [inputs, setInputs])
  53. const handleExactParamsChange = useCallback((newParams: Param[], moreInfo?: MoreInfo) => {
  54. const newInputs = produce(inputs, (draft) => {
  55. draft.parameters = newParams
  56. })
  57. setInputs(newInputs)
  58. if (moreInfo && moreInfo?.type === ChangeType.changeVarName && moreInfo.payload) {
  59. handleOutVarRenameChange(id, [id, moreInfo.payload.beforeKey], [id, moreInfo.payload.afterKey!])
  60. renameInspectVarName(id, moreInfo.payload.beforeKey, moreInfo.payload.afterKey!)
  61. }
  62. else {
  63. deleteNodeInspectorVars(id)
  64. }
  65. }, [deleteNodeInspectorVars, handleOutVarRenameChange, id, inputs, renameInspectVarName, setInputs])
  66. const addExtractParameter = useCallback((payload: Param) => {
  67. const newInputs = produce(inputs, (draft) => {
  68. if (!draft.parameters)
  69. draft.parameters = []
  70. draft.parameters.push(payload)
  71. })
  72. setInputs(newInputs)
  73. deleteNodeInspectorVars(id)
  74. }, [deleteNodeInspectorVars, id, inputs, setInputs])
  75. // model
  76. const model = inputs.model || {
  77. provider: '',
  78. name: '',
  79. mode: 'chat',
  80. completion_params: {
  81. temperature: 0.7,
  82. },
  83. }
  84. const modelMode = inputs.model?.mode
  85. const isChatModel = modelMode === 'chat'
  86. const isCompletionModel = !isChatModel
  87. const {
  88. isVisionModel,
  89. handleVisionResolutionEnabledChange,
  90. handleVisionResolutionChange,
  91. handleModelChanged: handleVisionConfigAfterModelChanged,
  92. } = useConfigVision(model, {
  93. payload: inputs.vision,
  94. onChange: (newPayload) => {
  95. const newInputs = produce(inputs, (draft) => {
  96. draft.vision = newPayload
  97. })
  98. setInputs(newInputs)
  99. },
  100. })
  101. const appendDefaultPromptConfig = useCallback((draft: ParameterExtractorNodeType, defaultConfig: any, _passInIsChatMode?: boolean) => {
  102. const promptTemplates = defaultConfig.prompt_templates
  103. if (!isChatModel) {
  104. setDefaultRolePrefix({
  105. user: promptTemplates.completion_model.conversation_histories_role.user_prefix,
  106. assistant: promptTemplates.completion_model.conversation_histories_role.assistant_prefix,
  107. })
  108. }
  109. }, [isChatModel])
  110. const [modelChanged, setModelChanged] = useState(false)
  111. const {
  112. currentProvider,
  113. currentModel,
  114. } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration)
  115. const handleModelChanged = useCallback((model: { provider: string; modelId: string; mode?: string }) => {
  116. const newInputs = produce(inputRef.current, (draft) => {
  117. draft.model.provider = model.provider
  118. draft.model.name = model.modelId
  119. draft.model.mode = model.mode!
  120. const isModeChange = model.mode !== inputRef.current.model?.mode
  121. if (isModeChange && defaultConfig && Object.keys(defaultConfig).length > 0)
  122. appendDefaultPromptConfig(draft, defaultConfig, model.mode === 'chat')
  123. })
  124. setInputs(newInputs)
  125. setModelChanged(true)
  126. }, [setInputs, defaultConfig, appendDefaultPromptConfig])
  127. useEffect(() => {
  128. if (currentProvider?.provider && currentModel?.model && !model.provider) {
  129. handleModelChanged({
  130. provider: currentProvider?.provider,
  131. modelId: currentModel?.model,
  132. mode: currentModel?.model_properties?.mode as string,
  133. })
  134. }
  135. }, [model?.provider, currentProvider, currentModel, handleModelChanged])
  136. // change to vision model to set vision enabled, else disabled
  137. useEffect(() => {
  138. if (!modelChanged)
  139. return
  140. setModelChanged(false)
  141. handleVisionConfigAfterModelChanged()
  142. }, [isVisionModel, modelChanged])
  143. const {
  144. currentModel: currModel,
  145. } = useTextGenerationCurrentProviderAndModelAndModelList(
  146. {
  147. provider: model.provider,
  148. model: model.name,
  149. },
  150. )
  151. const isSupportFunctionCall = supportFunctionCall(currModel?.features)
  152. const filterInputVar = useCallback((varPayload: Var) => {
  153. return [VarType.number, VarType.string].includes(varPayload.type)
  154. }, [])
  155. const {
  156. availableVars,
  157. availableNodesWithParent,
  158. } = useAvailableVarList(id, {
  159. onlyLeafNodeVar: false,
  160. filterVar: filterInputVar,
  161. })
  162. const handleCompletionParamsChange = useCallback((newParams: Record<string, any>) => {
  163. const newInputs = produce(inputs, (draft) => {
  164. draft.model.completion_params = newParams
  165. })
  166. setInputs(newInputs)
  167. }, [inputs, setInputs])
  168. const handleInstructionChange = useCallback((newInstruction: string) => {
  169. const newInputs = produce(inputs, (draft) => {
  170. draft.instruction = newInstruction
  171. })
  172. setInputs(newInputs)
  173. }, [inputs, setInputs])
  174. const hasSetBlockStatus = {
  175. history: false,
  176. query: isChatMode ? checkHasQueryBlock(inputs.instruction) : false,
  177. context: false,
  178. }
  179. const handleMemoryChange = useCallback((newMemory?: Memory) => {
  180. const newInputs = produce(inputs, (draft) => {
  181. draft.memory = newMemory
  182. })
  183. setInputs(newInputs)
  184. }, [inputs, setInputs])
  185. const handleReasoningModeChange = useCallback((newReasoningMode: ReasoningModeType) => {
  186. const newInputs = produce(inputs, (draft) => {
  187. draft.reasoning_mode = newReasoningMode
  188. })
  189. setInputs(newInputs)
  190. }, [inputs, setInputs])
  191. const handleImportFromTool = useCallback((params: Param[]) => {
  192. const newInputs = produce(inputs, (draft) => {
  193. draft.parameters = params
  194. })
  195. setInputs(newInputs)
  196. }, [inputs, setInputs])
  197. return {
  198. readOnly,
  199. handleInputVarChange,
  200. filterVar,
  201. isChatMode,
  202. inputs,
  203. isChatModel,
  204. isCompletionModel,
  205. handleModelChanged,
  206. handleCompletionParamsChange,
  207. handleImportFromTool,
  208. handleExactParamsChange,
  209. addExtractParameter,
  210. handleInstructionChange,
  211. hasSetBlockStatus,
  212. availableVars,
  213. availableNodesWithParent,
  214. isSupportFunctionCall,
  215. handleReasoningModeChange,
  216. handleMemoryChange,
  217. isVisionModel,
  218. handleVisionResolutionEnabledChange,
  219. handleVisionResolutionChange,
  220. }
  221. }
  222. export default useConfig