use-config.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { useCallback, useMemo } from 'react'
  2. import produce from 'immer'
  3. import { useStoreApi } from 'reactflow'
  4. import { isEqual } from 'lodash-es'
  5. import { VarType } from '../../types'
  6. import type { ValueSelector, Var } from '../../types'
  7. import { type AssignerNodeType, WriteMode } from './types'
  8. import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
  9. import {
  10. useIsChatMode,
  11. useNodesReadOnly,
  12. useWorkflow,
  13. useWorkflowVariables,
  14. } from '@/app/components/workflow/hooks'
  15. const useConfig = (id: string, payload: AssignerNodeType) => {
  16. const { nodesReadOnly: readOnly } = useNodesReadOnly()
  17. const isChatMode = useIsChatMode()
  18. const store = useStoreApi()
  19. const { getBeforeNodesInSameBranch } = useWorkflow()
  20. const {
  21. getNodes,
  22. } = store.getState()
  23. const currentNode = getNodes().find(n => n.id === id)
  24. const isInIteration = payload.isInIteration
  25. const iterationNode = isInIteration ? getNodes().find(n => n.id === currentNode!.parentId) : null
  26. const availableNodes = useMemo(() => {
  27. return getBeforeNodesInSameBranch(id)
  28. }, [getBeforeNodesInSameBranch, id])
  29. const { inputs, setInputs } = useNodeCrud<AssignerNodeType>(id, payload)
  30. const { getCurrentVariableType } = useWorkflowVariables()
  31. const assignedVarType = getCurrentVariableType({
  32. parentNode: iterationNode,
  33. valueSelector: inputs.assigned_variable_selector || [],
  34. availableNodes,
  35. isChatMode,
  36. isConstant: false,
  37. })
  38. const isSupportAppend = useCallback((varType: VarType) => {
  39. return [VarType.arrayString, VarType.arrayNumber, VarType.arrayObject].includes(varType)
  40. }, [])
  41. const isCurrSupportAppend = useMemo(() => isSupportAppend(assignedVarType), [assignedVarType, isSupportAppend])
  42. const handleAssignedVarChanges = useCallback((variable: ValueSelector | string) => {
  43. const newInputs = produce(inputs, (draft) => {
  44. draft.assigned_variable_selector = variable as ValueSelector
  45. draft.input_variable_selector = []
  46. const newVarType = getCurrentVariableType({
  47. parentNode: iterationNode,
  48. valueSelector: draft.assigned_variable_selector || [],
  49. availableNodes,
  50. isChatMode,
  51. isConstant: false,
  52. })
  53. if (inputs.write_mode === WriteMode.Append && !isSupportAppend(newVarType))
  54. draft.write_mode = WriteMode.Overwrite
  55. })
  56. setInputs(newInputs)
  57. }, [inputs, setInputs, getCurrentVariableType, iterationNode, availableNodes, isChatMode, isSupportAppend])
  58. const writeModeTypes = [WriteMode.Overwrite, WriteMode.Append, WriteMode.Clear]
  59. const handleWriteModeChange = useCallback((writeMode: WriteMode) => {
  60. return () => {
  61. const newInputs = produce(inputs, (draft) => {
  62. draft.write_mode = writeMode
  63. if (inputs.write_mode === WriteMode.Clear)
  64. draft.input_variable_selector = []
  65. })
  66. setInputs(newInputs)
  67. }
  68. }, [inputs, setInputs])
  69. const toAssignedVarType = useMemo(() => {
  70. const { write_mode } = inputs
  71. if (write_mode === WriteMode.Overwrite)
  72. return assignedVarType
  73. if (write_mode === WriteMode.Append) {
  74. if (assignedVarType === VarType.arrayString)
  75. return VarType.string
  76. if (assignedVarType === VarType.arrayNumber)
  77. return VarType.number
  78. if (assignedVarType === VarType.arrayObject)
  79. return VarType.object
  80. }
  81. return VarType.string
  82. }, [assignedVarType, inputs])
  83. const filterAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => {
  84. return selector.join('.').startsWith('conversation')
  85. }, [])
  86. const filterToAssignedVar = useCallback((varPayload: Var, selector: ValueSelector) => {
  87. if (isEqual(selector, inputs.assigned_variable_selector))
  88. return false
  89. if (inputs.write_mode === WriteMode.Overwrite) {
  90. return varPayload.type === assignedVarType
  91. }
  92. else if (inputs.write_mode === WriteMode.Append) {
  93. switch (assignedVarType) {
  94. case VarType.arrayString:
  95. return varPayload.type === VarType.string
  96. case VarType.arrayNumber:
  97. return varPayload.type === VarType.number
  98. case VarType.arrayObject:
  99. return varPayload.type === VarType.object
  100. default:
  101. return false
  102. }
  103. }
  104. return true
  105. }, [inputs.assigned_variable_selector, inputs.write_mode, assignedVarType])
  106. const handleToAssignedVarChange = useCallback((value: ValueSelector | string) => {
  107. const newInputs = produce(inputs, (draft) => {
  108. draft.input_variable_selector = value as ValueSelector
  109. })
  110. setInputs(newInputs)
  111. }, [inputs, setInputs])
  112. return {
  113. readOnly,
  114. inputs,
  115. handleAssignedVarChanges,
  116. assignedVarType,
  117. isSupportAppend: isCurrSupportAppend,
  118. writeModeTypes,
  119. handleWriteModeChange,
  120. filterAssignedVar,
  121. filterToAssignedVar,
  122. handleToAssignedVarChange,
  123. toAssignedVarType,
  124. }
  125. }
  126. export default useConfig