use-config.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. // list operator node can output array
  49. [VarType.array]: VarType.array,
  50. [VarType.arrayFile]: VarType.arrayFile,
  51. [VarType.arrayString]: VarType.arrayString,
  52. [VarType.arrayNumber]: VarType.arrayNumber,
  53. [VarType.arrayObject]: VarType.arrayObject,
  54. } as Record<VarType, VarType>)[outputItemType] || VarType.arrayString
  55. })
  56. setInputs(newInputs)
  57. }, [inputs, setInputs])
  58. // single run
  59. const iteratorInputKey = `${id}.input_selector`
  60. const {
  61. isShowSingleRun,
  62. showSingleRun,
  63. hideSingleRun,
  64. toVarInputs,
  65. runningStatus,
  66. handleRun: doHandleRun,
  67. handleStop,
  68. runInputData,
  69. setRunInputData,
  70. runResult,
  71. iterationRunResult,
  72. } = useOneStepRun<IterationNodeType>({
  73. id,
  74. data: inputs,
  75. iteratorInputKey,
  76. defaultRunInputData: {
  77. [iteratorInputKey]: [''],
  78. },
  79. })
  80. const [isShowIterationDetail, {
  81. setTrue: doShowIterationDetail,
  82. setFalse: doHideIterationDetail,
  83. }] = useBoolean(false)
  84. const hideIterationDetail = useCallback(() => {
  85. hideSingleRun()
  86. doHideIterationDetail()
  87. }, [doHideIterationDetail, hideSingleRun])
  88. const showIterationDetail = useCallback(() => {
  89. doShowIterationDetail()
  90. }, [doShowIterationDetail])
  91. const backToSingleRun = useCallback(() => {
  92. hideIterationDetail()
  93. showSingleRun()
  94. }, [hideIterationDetail, showSingleRun])
  95. const { usedOutVars, allVarObject } = (() => {
  96. const vars: ValueSelector[] = []
  97. const varObjs: Record<string, boolean> = {}
  98. const allVarObject: Record<string, {
  99. inSingleRunPassedKey: string
  100. }> = {}
  101. iterationChildrenNodes.forEach((node) => {
  102. const nodeVars = getNodeUsedVars(node).filter(item => item && item.length > 0)
  103. nodeVars.forEach((varSelector) => {
  104. if (varSelector[0] === id) { // skip iteration node itself variable: item, index
  105. return
  106. }
  107. const isInIteration = isNodeInIteration(varSelector[0])
  108. if (isInIteration) // not pass iteration inner variable
  109. return
  110. const varSectorStr = varSelector.join('.')
  111. if (!varObjs[varSectorStr]) {
  112. varObjs[varSectorStr] = true
  113. vars.push(varSelector)
  114. }
  115. let passToServerKeys = getNodeUsedVarPassToServerKey(node, varSelector)
  116. if (typeof passToServerKeys === 'string')
  117. passToServerKeys = [passToServerKeys]
  118. passToServerKeys.forEach((key: string, index: number) => {
  119. allVarObject[[varSectorStr, node.id, index].join(DELIMITER)] = {
  120. inSingleRunPassedKey: key,
  121. }
  122. })
  123. })
  124. })
  125. const res = toVarInputs(vars.map((item) => {
  126. const varInfo = getNodeInfoById(canChooseVarNodes, item[0])
  127. return {
  128. label: {
  129. nodeType: varInfo?.data.type,
  130. nodeName: varInfo?.data.title || canChooseVarNodes[0]?.data.title, // default start node title
  131. variable: isSystemVar(item) ? item.join('.') : item[item.length - 1],
  132. },
  133. variable: `${item.join('.')}`,
  134. value_selector: item,
  135. }
  136. }))
  137. return {
  138. usedOutVars: res,
  139. allVarObject,
  140. }
  141. })()
  142. const handleRun = useCallback((data: Record<string, any>) => {
  143. const formattedData: Record<string, any> = {}
  144. Object.keys(allVarObject).forEach((key) => {
  145. const [varSectorStr, nodeId] = key.split(DELIMITER)
  146. formattedData[`${nodeId}.${allVarObject[key].inSingleRunPassedKey}`] = data[varSectorStr]
  147. })
  148. formattedData[iteratorInputKey] = data[iteratorInputKey]
  149. doHandleRun(formattedData)
  150. }, [allVarObject, doHandleRun, iteratorInputKey])
  151. const inputVarValues = (() => {
  152. const vars: Record<string, any> = {}
  153. Object.keys(runInputData)
  154. .filter(key => ![iteratorInputKey].includes(key))
  155. .forEach((key) => {
  156. vars[key] = runInputData[key]
  157. })
  158. return vars
  159. })()
  160. const setInputVarValues = useCallback((newPayload: Record<string, any>) => {
  161. const newVars = {
  162. ...newPayload,
  163. [iteratorInputKey]: runInputData[iteratorInputKey],
  164. }
  165. setRunInputData(newVars)
  166. }, [iteratorInputKey, runInputData, setRunInputData])
  167. const iterator = runInputData[iteratorInputKey]
  168. const setIterator = useCallback((newIterator: string[]) => {
  169. setRunInputData({
  170. ...runInputData,
  171. [iteratorInputKey]: newIterator,
  172. })
  173. }, [iteratorInputKey, runInputData, setRunInputData])
  174. const changeParallel = useCallback((value: boolean) => {
  175. const newInputs = produce(inputs, (draft) => {
  176. draft.is_parallel = value
  177. })
  178. setInputs(newInputs)
  179. }, [inputs, setInputs])
  180. const changeErrorResponseMode = useCallback((item: Item) => {
  181. const newInputs = produce(inputs, (draft) => {
  182. draft.error_handle_mode = item.value as ErrorHandleMode
  183. })
  184. setInputs(newInputs)
  185. }, [inputs, setInputs])
  186. const changeParallelNums = useCallback((num: number) => {
  187. const newInputs = produce(inputs, (draft) => {
  188. draft.parallel_nums = num
  189. })
  190. setInputs(newInputs)
  191. }, [inputs, setInputs])
  192. return {
  193. readOnly,
  194. inputs,
  195. filterInputVar,
  196. handleInputChange,
  197. childrenNodeVars,
  198. iterationChildrenNodes,
  199. handleOutputVarChange,
  200. isShowSingleRun,
  201. showSingleRun,
  202. hideSingleRun,
  203. isShowIterationDetail,
  204. showIterationDetail,
  205. hideIterationDetail,
  206. backToSingleRun,
  207. runningStatus,
  208. handleRun,
  209. handleStop,
  210. runResult,
  211. inputVarValues,
  212. setInputVarValues,
  213. usedOutVars,
  214. iterator,
  215. setIterator,
  216. iteratorInputKey,
  217. iterationRunResult,
  218. changeParallel,
  219. changeErrorResponseMode,
  220. changeParallelNums,
  221. }
  222. }
  223. export default useConfig