use-config.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import { useCallback } from 'react'
  2. import produce from 'immer'
  3. import { useBoolean } from 'ahooks'
  4. import {
  5. useIsChatMode,
  6. useIsNodeInIteration,
  7. useNodesReadOnly,
  8. useWorkflow,
  9. } from '../../hooks'
  10. import { VarType } from '../../types'
  11. import type { ErrorHandleMode, ValueSelector, Var } from '../../types'
  12. import useNodeCrud from '../_base/hooks/use-node-crud'
  13. import { getNodeInfoById, getNodeUsedVarPassToServerKey, getNodeUsedVars, isSystemVar, toNodeOutputVars } from '../_base/components/variable/utils'
  14. import useOneStepRun from '../_base/hooks/use-one-step-run'
  15. import type { IterationNodeType } from './types'
  16. import type { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
  17. import type { Item } from '@/app/components/base/select'
  18. const DELIMITER = '@@@@@'
  19. const useConfig = (id: string, payload: IterationNodeType) => {
  20. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  21. const { isNodeInIteration } = useIsNodeInIteration(id)
  22. const isChatMode = useIsChatMode()
  23. const { inputs, setInputs } = useNodeCrud<IterationNodeType>(id, payload)
  24. const filterInputVar = useCallback((varPayload: Var) => {
  25. return [VarType.array, VarType.arrayString, VarType.arrayNumber, VarType.arrayObject, VarType.arrayFile].includes(varPayload.type)
  26. }, [])
  27. const handleInputChange = useCallback((input: ValueSelector | string) => {
  28. const newInputs = produce(inputs, (draft) => {
  29. draft.iterator_selector = input as ValueSelector || []
  30. })
  31. setInputs(newInputs)
  32. }, [inputs, setInputs])
  33. // output
  34. const { getIterationNodeChildren, getBeforeNodesInSameBranch } = useWorkflow()
  35. const beforeNodes = getBeforeNodesInSameBranch(id)
  36. const iterationChildrenNodes = getIterationNodeChildren(id)
  37. const canChooseVarNodes = [...beforeNodes, ...iterationChildrenNodes]
  38. const childrenNodeVars = toNodeOutputVars(iterationChildrenNodes, isChatMode)
  39. const handleOutputVarChange = useCallback((output: ValueSelector | string, _varKindType: VarKindType, varInfo?: Var) => {
  40. const newInputs = produce(inputs, (draft) => {
  41. draft.output_selector = output as ValueSelector || []
  42. const outputItemType = varInfo?.type || VarType.string
  43. draft.output_type = ({
  44. [VarType.string]: VarType.arrayString,
  45. [VarType.number]: VarType.arrayNumber,
  46. [VarType.object]: VarType.arrayObject,
  47. [VarType.file]: VarType.arrayFile,
  48. } as Record<VarType, VarType>)[outputItemType] || VarType.arrayString
  49. })
  50. setInputs(newInputs)
  51. }, [inputs, setInputs])
  52. // single run
  53. const iteratorInputKey = `${id}.input_selector`
  54. const {
  55. isShowSingleRun,
  56. showSingleRun,
  57. hideSingleRun,
  58. toVarInputs,
  59. runningStatus,
  60. handleRun: doHandleRun,
  61. handleStop,
  62. runInputData,
  63. setRunInputData,
  64. runResult,
  65. iterationRunResult,
  66. } = useOneStepRun<IterationNodeType>({
  67. id,
  68. data: inputs,
  69. iteratorInputKey,
  70. defaultRunInputData: {
  71. [iteratorInputKey]: [''],
  72. },
  73. })
  74. const [isShowIterationDetail, {
  75. setTrue: doShowIterationDetail,
  76. setFalse: doHideIterationDetail,
  77. }] = useBoolean(false)
  78. const hideIterationDetail = useCallback(() => {
  79. hideSingleRun()
  80. doHideIterationDetail()
  81. }, [doHideIterationDetail, hideSingleRun])
  82. const showIterationDetail = useCallback(() => {
  83. doShowIterationDetail()
  84. }, [doShowIterationDetail])
  85. const backToSingleRun = useCallback(() => {
  86. hideIterationDetail()
  87. showSingleRun()
  88. }, [hideIterationDetail, showSingleRun])
  89. const { usedOutVars, allVarObject } = (() => {
  90. const vars: ValueSelector[] = []
  91. const varObjs: Record<string, boolean> = {}
  92. const allVarObject: Record<string, {
  93. inSingleRunPassedKey: string
  94. }> = {}
  95. iterationChildrenNodes.forEach((node) => {
  96. const nodeVars = getNodeUsedVars(node).filter(item => item && item.length > 0)
  97. nodeVars.forEach((varSelector) => {
  98. if (varSelector[0] === id) { // skip iteration node itself variable: item, index
  99. return
  100. }
  101. const isInIteration = isNodeInIteration(varSelector[0])
  102. if (isInIteration) // not pass iteration inner variable
  103. return
  104. const varSectorStr = varSelector.join('.')
  105. if (!varObjs[varSectorStr]) {
  106. varObjs[varSectorStr] = true
  107. vars.push(varSelector)
  108. }
  109. let passToServerKeys = getNodeUsedVarPassToServerKey(node, varSelector)
  110. if (typeof passToServerKeys === 'string')
  111. passToServerKeys = [passToServerKeys]
  112. passToServerKeys.forEach((key: string, index: number) => {
  113. allVarObject[[varSectorStr, node.id, index].join(DELIMITER)] = {
  114. inSingleRunPassedKey: key,
  115. }
  116. })
  117. })
  118. })
  119. const res = toVarInputs(vars.map((item) => {
  120. const varInfo = getNodeInfoById(canChooseVarNodes, item[0])
  121. return {
  122. label: {
  123. nodeType: varInfo?.data.type,
  124. nodeName: varInfo?.data.title || canChooseVarNodes[0]?.data.title, // default start node title
  125. variable: isSystemVar(item) ? item.join('.') : item[item.length - 1],
  126. },
  127. variable: `${item.join('.')}`,
  128. value_selector: item,
  129. }
  130. }))
  131. return {
  132. usedOutVars: res,
  133. allVarObject,
  134. }
  135. })()
  136. const handleRun = useCallback((data: Record<string, any>) => {
  137. const formattedData: Record<string, any> = {}
  138. Object.keys(allVarObject).forEach((key) => {
  139. const [varSectorStr, nodeId] = key.split(DELIMITER)
  140. formattedData[`${nodeId}.${allVarObject[key].inSingleRunPassedKey}`] = data[varSectorStr]
  141. })
  142. formattedData[iteratorInputKey] = data[iteratorInputKey]
  143. doHandleRun(formattedData)
  144. }, [allVarObject, doHandleRun, iteratorInputKey])
  145. const inputVarValues = (() => {
  146. const vars: Record<string, any> = {}
  147. Object.keys(runInputData)
  148. .filter(key => ![iteratorInputKey].includes(key))
  149. .forEach((key) => {
  150. vars[key] = runInputData[key]
  151. })
  152. return vars
  153. })()
  154. const setInputVarValues = useCallback((newPayload: Record<string, any>) => {
  155. const newVars = {
  156. ...newPayload,
  157. [iteratorInputKey]: runInputData[iteratorInputKey],
  158. }
  159. setRunInputData(newVars)
  160. }, [iteratorInputKey, runInputData, setRunInputData])
  161. const iterator = runInputData[iteratorInputKey]
  162. const setIterator = useCallback((newIterator: string[]) => {
  163. setRunInputData({
  164. ...runInputData,
  165. [iteratorInputKey]: newIterator,
  166. })
  167. }, [iteratorInputKey, runInputData, setRunInputData])
  168. const changeParallel = useCallback((value: boolean) => {
  169. const newInputs = produce(inputs, (draft) => {
  170. draft.is_parallel = value
  171. })
  172. setInputs(newInputs)
  173. }, [inputs, setInputs])
  174. const changeErrorResponseMode = useCallback((item: Item) => {
  175. const newInputs = produce(inputs, (draft) => {
  176. draft.error_handle_mode = item.value as ErrorHandleMode
  177. })
  178. setInputs(newInputs)
  179. }, [inputs, setInputs])
  180. const changeParallelNums = useCallback((num: number) => {
  181. const newInputs = produce(inputs, (draft) => {
  182. draft.parallel_nums = num
  183. })
  184. setInputs(newInputs)
  185. }, [inputs, setInputs])
  186. return {
  187. readOnly,
  188. inputs,
  189. filterInputVar,
  190. handleInputChange,
  191. childrenNodeVars,
  192. iterationChildrenNodes,
  193. handleOutputVarChange,
  194. isShowSingleRun,
  195. showSingleRun,
  196. hideSingleRun,
  197. isShowIterationDetail,
  198. showIterationDetail,
  199. hideIterationDetail,
  200. backToSingleRun,
  201. runningStatus,
  202. handleRun,
  203. handleStop,
  204. runResult,
  205. inputVarValues,
  206. setInputVarValues,
  207. usedOutVars,
  208. iterator,
  209. setIterator,
  210. iteratorInputKey,
  211. iterationRunResult,
  212. changeParallel,
  213. changeErrorResponseMode,
  214. changeParallelNums,
  215. }
  216. }
  217. export default useConfig