You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

use-config.ts 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import {
  2. useCallback,
  3. useRef,
  4. } from 'react'
  5. import produce from 'immer'
  6. import { v4 as uuid4 } from 'uuid'
  7. import {
  8. useIsChatMode,
  9. useNodesReadOnly,
  10. useWorkflow,
  11. } from '../../hooks'
  12. import { ValueType, VarType } from '../../types'
  13. import type { ErrorHandleMode, Var } from '../../types'
  14. import useNodeCrud from '../_base/hooks/use-node-crud'
  15. import { toNodeOutputVars } from '../_base/components/variable/utils'
  16. import { getOperators } from './utils'
  17. import { LogicalOperator } from './types'
  18. import type { HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleToggleConditionLogicalOperator, HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, HandleUpdateSubVariableCondition, LoopNodeType } from './types'
  19. import useIsVarFileAttribute from './use-is-var-file-attribute'
  20. import { useStore } from '@/app/components/workflow/store'
  21. const useConfig = (id: string, payload: LoopNodeType) => {
  22. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  23. const isChatMode = useIsChatMode()
  24. const conversationVariables = useStore(s => s.conversationVariables)
  25. const { inputs, setInputs } = useNodeCrud<LoopNodeType>(id, payload)
  26. const inputsRef = useRef(inputs)
  27. const handleInputsChange = useCallback((newInputs: LoopNodeType) => {
  28. inputsRef.current = newInputs
  29. setInputs(newInputs)
  30. }, [setInputs])
  31. const filterInputVar = useCallback((varPayload: Var) => {
  32. return [VarType.array, VarType.arrayString, VarType.arrayNumber, VarType.arrayObject, VarType.arrayFile].includes(varPayload.type)
  33. }, [])
  34. // output
  35. const { getLoopNodeChildren } = useWorkflow()
  36. const loopChildrenNodes = [{ id, data: payload } as any, ...getLoopNodeChildren(id)]
  37. const buildInTools = useStore(s => s.buildInTools)
  38. const customTools = useStore(s => s.customTools)
  39. const workflowTools = useStore(s => s.workflowTools)
  40. const mcpTools = useStore(s => s.mcpTools)
  41. const dataSourceList = useStore(s => s.dataSourceList)
  42. const allPluginInfoList = {
  43. buildInTools,
  44. customTools,
  45. workflowTools,
  46. mcpTools,
  47. dataSourceList: dataSourceList ?? [],
  48. }
  49. const childrenNodeVars = toNodeOutputVars(loopChildrenNodes, isChatMode, undefined, [], conversationVariables, [], allPluginInfoList)
  50. const {
  51. getIsVarFileAttribute,
  52. } = useIsVarFileAttribute({
  53. nodeId: id,
  54. })
  55. const changeErrorResponseMode = useCallback((item: { value: unknown }) => {
  56. const newInputs = produce(inputsRef.current, (draft) => {
  57. draft.error_handle_mode = item.value as ErrorHandleMode
  58. })
  59. handleInputsChange(newInputs)
  60. }, [inputs, handleInputsChange])
  61. const handleAddCondition = useCallback<HandleAddCondition>((valueSelector, varItem) => {
  62. const newInputs = produce(inputsRef.current, (draft) => {
  63. if (!draft.break_conditions)
  64. draft.break_conditions = []
  65. draft.break_conditions?.push({
  66. id: uuid4(),
  67. varType: varItem.type,
  68. variable_selector: valueSelector,
  69. comparison_operator: getOperators(varItem.type, getIsVarFileAttribute(valueSelector) ? { key: valueSelector.slice(-1)[0] } : undefined)[0],
  70. value: varItem.type === VarType.boolean ? 'false' : '',
  71. })
  72. })
  73. handleInputsChange(newInputs)
  74. }, [getIsVarFileAttribute, handleInputsChange])
  75. const handleRemoveCondition = useCallback<HandleRemoveCondition>((conditionId) => {
  76. const newInputs = produce(inputsRef.current, (draft) => {
  77. draft.break_conditions = draft.break_conditions?.filter(item => item.id !== conditionId)
  78. })
  79. handleInputsChange(newInputs)
  80. }, [handleInputsChange])
  81. const handleUpdateCondition = useCallback<HandleUpdateCondition>((conditionId, newCondition) => {
  82. const newInputs = produce(inputsRef.current, (draft) => {
  83. const targetCondition = draft.break_conditions?.find(item => item.id === conditionId)
  84. if (targetCondition)
  85. Object.assign(targetCondition, newCondition)
  86. })
  87. handleInputsChange(newInputs)
  88. }, [handleInputsChange])
  89. const handleToggleConditionLogicalOperator = useCallback<HandleToggleConditionLogicalOperator>(() => {
  90. const newInputs = produce(inputsRef.current, (draft) => {
  91. draft.logical_operator = draft.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and
  92. })
  93. handleInputsChange(newInputs)
  94. }, [handleInputsChange])
  95. const handleAddSubVariableCondition = useCallback<HandleAddSubVariableCondition>((conditionId: string, key?: string) => {
  96. const newInputs = produce(inputsRef.current, (draft) => {
  97. const condition = draft.break_conditions?.find(item => item.id === conditionId)
  98. if (!condition)
  99. return
  100. if (!condition?.sub_variable_condition) {
  101. condition.sub_variable_condition = {
  102. logical_operator: LogicalOperator.and,
  103. conditions: [],
  104. }
  105. }
  106. const subVarCondition = condition.sub_variable_condition
  107. if (subVarCondition) {
  108. if (!subVarCondition.conditions)
  109. subVarCondition.conditions = []
  110. const svcComparisonOperators = getOperators(VarType.string, { key: key || '' })
  111. subVarCondition.conditions.push({
  112. id: uuid4(),
  113. key: key || '',
  114. varType: VarType.string,
  115. comparison_operator: (svcComparisonOperators && svcComparisonOperators.length) ? svcComparisonOperators[0] : undefined,
  116. value: '',
  117. })
  118. }
  119. })
  120. handleInputsChange(newInputs)
  121. }, [handleInputsChange])
  122. const handleRemoveSubVariableCondition = useCallback((conditionId: string, subConditionId: string) => {
  123. const newInputs = produce(inputsRef.current, (draft) => {
  124. const condition = draft.break_conditions?.find(item => item.id === conditionId)
  125. if (!condition)
  126. return
  127. if (!condition?.sub_variable_condition)
  128. return
  129. const subVarCondition = condition.sub_variable_condition
  130. if (subVarCondition)
  131. subVarCondition.conditions = subVarCondition.conditions.filter(item => item.id !== subConditionId)
  132. })
  133. handleInputsChange(newInputs)
  134. }, [handleInputsChange])
  135. const handleUpdateSubVariableCondition = useCallback<HandleUpdateSubVariableCondition>((conditionId, subConditionId, newSubCondition) => {
  136. const newInputs = produce(inputsRef.current, (draft) => {
  137. const targetCondition = draft.break_conditions?.find(item => item.id === conditionId)
  138. if (targetCondition && targetCondition.sub_variable_condition) {
  139. const targetSubCondition = targetCondition.sub_variable_condition.conditions.find(item => item.id === subConditionId)
  140. if (targetSubCondition)
  141. Object.assign(targetSubCondition, newSubCondition)
  142. }
  143. })
  144. handleInputsChange(newInputs)
  145. }, [handleInputsChange])
  146. const handleToggleSubVariableConditionLogicalOperator = useCallback<HandleToggleSubVariableConditionLogicalOperator>((conditionId) => {
  147. const newInputs = produce(inputsRef.current, (draft) => {
  148. const targetCondition = draft.break_conditions?.find(item => item.id === conditionId)
  149. if (targetCondition && targetCondition.sub_variable_condition)
  150. targetCondition.sub_variable_condition.logical_operator = targetCondition.sub_variable_condition.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and
  151. })
  152. handleInputsChange(newInputs)
  153. }, [handleInputsChange])
  154. const handleUpdateLoopCount = useCallback((value: number) => {
  155. const newInputs = produce(inputsRef.current, (draft) => {
  156. draft.loop_count = value
  157. })
  158. handleInputsChange(newInputs)
  159. }, [handleInputsChange])
  160. const handleAddLoopVariable = useCallback(() => {
  161. const newInputs = produce(inputsRef.current, (draft) => {
  162. if (!draft.loop_variables)
  163. draft.loop_variables = []
  164. draft.loop_variables.push({
  165. id: uuid4(),
  166. label: '',
  167. var_type: VarType.string,
  168. value_type: ValueType.constant,
  169. value: '',
  170. })
  171. })
  172. handleInputsChange(newInputs)
  173. }, [handleInputsChange])
  174. const handleRemoveLoopVariable = useCallback((id: string) => {
  175. const newInputs = produce(inputsRef.current, (draft) => {
  176. draft.loop_variables = draft.loop_variables?.filter(item => item.id !== id)
  177. })
  178. handleInputsChange(newInputs)
  179. }, [handleInputsChange])
  180. const handleUpdateLoopVariable = useCallback((id: string, updateData: any) => {
  181. const loopVariables = inputsRef.current.loop_variables || []
  182. const index = loopVariables.findIndex(item => item.id === id)
  183. const newInputs = produce(inputsRef.current, (draft) => {
  184. if (index > -1) {
  185. draft.loop_variables![index] = {
  186. ...draft.loop_variables![index],
  187. ...updateData,
  188. }
  189. }
  190. })
  191. handleInputsChange(newInputs)
  192. }, [handleInputsChange])
  193. return {
  194. readOnly,
  195. inputs,
  196. filterInputVar,
  197. childrenNodeVars,
  198. loopChildrenNodes,
  199. handleAddCondition,
  200. handleRemoveCondition,
  201. handleUpdateCondition,
  202. handleToggleConditionLogicalOperator,
  203. handleAddSubVariableCondition,
  204. handleUpdateSubVariableCondition,
  205. handleRemoveSubVariableCondition,
  206. handleToggleSubVariableConditionLogicalOperator,
  207. handleUpdateLoopCount,
  208. changeErrorResponseMode,
  209. handleAddLoopVariable,
  210. handleRemoveLoopVariable,
  211. handleUpdateLoopVariable,
  212. }
  213. }
  214. export default useConfig