use-config.ts 8.2 KB

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