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-inspect-vars-crud.ts 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { fetchNodeInspectVars } from '@/service/workflow'
  2. import { useStore, useWorkflowStore } from '../store'
  3. import type { ValueSelector } from '../types'
  4. import type { VarInInspect } from '@/types/workflow'
  5. import { VarInInspectType } from '@/types/workflow'
  6. import {
  7. useConversationVarValues,
  8. useDeleteAllInspectorVars,
  9. useDeleteInspectVar,
  10. useDeleteNodeInspectorVars,
  11. useEditInspectorVar,
  12. useInvalidateConversationVarValues,
  13. useInvalidateSysVarValues,
  14. useResetConversationVar,
  15. useResetToLastRunValue,
  16. useSysVarValues,
  17. } from '@/service/use-workflow'
  18. import { useCallback } from 'react'
  19. import { isConversationVar, isENV, isSystemVar } from '../nodes/_base/components/variable/utils'
  20. import produce from 'immer'
  21. import type { Node } from '@/app/components/workflow/types'
  22. import { useNodesInteractionsWithoutSync } from './use-nodes-interactions-without-sync'
  23. import { useEdgesInteractionsWithoutSync } from './use-edges-interactions-without-sync'
  24. const useInspectVarsCrud = () => {
  25. const workflowStore = useWorkflowStore()
  26. const nodesWithInspectVars = useStore(s => s.nodesWithInspectVars)
  27. const {
  28. appId,
  29. setNodeInspectVars,
  30. setInspectVarValue,
  31. renameInspectVarName: renameInspectVarNameInStore,
  32. deleteAllInspectVars: deleteAllInspectVarsInStore,
  33. deleteNodeInspectVars: deleteNodeInspectVarsInStore,
  34. deleteInspectVar: deleteInspectVarInStore,
  35. setNodesWithInspectVars,
  36. resetToLastRunVar: resetToLastRunVarInStore,
  37. } = workflowStore.getState()
  38. const { data: conversationVars } = useConversationVarValues(appId)
  39. const invalidateConversationVarValues = useInvalidateConversationVarValues(appId)
  40. const { mutateAsync: doResetConversationVar } = useResetConversationVar(appId)
  41. const { mutateAsync: doResetToLastRunValue } = useResetToLastRunValue(appId)
  42. const { data: systemVars } = useSysVarValues(appId)
  43. const invalidateSysVarValues = useInvalidateSysVarValues(appId)
  44. const { mutateAsync: doDeleteAllInspectorVars } = useDeleteAllInspectorVars(appId)
  45. const { mutate: doDeleteNodeInspectorVars } = useDeleteNodeInspectorVars(appId)
  46. const { mutate: doDeleteInspectVar } = useDeleteInspectVar(appId)
  47. const { mutateAsync: doEditInspectorVar } = useEditInspectorVar(appId)
  48. const { handleCancelNodeSuccessStatus } = useNodesInteractionsWithoutSync()
  49. const { handleEdgeCancelRunningStatus } = useEdgesInteractionsWithoutSync()
  50. const getNodeInspectVars = useCallback((nodeId: string) => {
  51. const node = nodesWithInspectVars.find(node => node.nodeId === nodeId)
  52. return node
  53. }, [nodesWithInspectVars])
  54. const getVarId = useCallback((nodeId: string, varName: string) => {
  55. const node = getNodeInspectVars(nodeId)
  56. if (!node)
  57. return undefined
  58. const varId = node.vars.find((varItem) => {
  59. return varItem.selector[1] === varName
  60. })?.id
  61. return varId
  62. }, [getNodeInspectVars])
  63. const getInspectVar = useCallback((nodeId: string, name: string): VarInInspect | undefined => {
  64. const node = getNodeInspectVars(nodeId)
  65. if (!node)
  66. return undefined
  67. const variable = node.vars.find((varItem) => {
  68. return varItem.name === name
  69. })
  70. return variable
  71. }, [getNodeInspectVars])
  72. const hasSetInspectVar = useCallback((nodeId: string, name: string, sysVars: VarInInspect[], conversationVars: VarInInspect[]) => {
  73. const isEnv = isENV([nodeId])
  74. if (isEnv) // always have value
  75. return true
  76. const isSys = isSystemVar([nodeId])
  77. if (isSys)
  78. return sysVars.some(varItem => varItem.selector?.[1]?.replace('sys.', '') === name)
  79. const isChatVar = isConversationVar([nodeId])
  80. if (isChatVar)
  81. return conversationVars.some(varItem => varItem.selector?.[1] === name)
  82. return getInspectVar(nodeId, name) !== undefined
  83. }, [getInspectVar])
  84. const hasNodeInspectVars = useCallback((nodeId: string) => {
  85. return !!getNodeInspectVars(nodeId)
  86. }, [getNodeInspectVars])
  87. const fetchInspectVarValue = async (selector: ValueSelector) => {
  88. const nodeId = selector[0]
  89. const isSystemVar = nodeId === 'sys'
  90. const isConversationVar = nodeId === 'conversation'
  91. if (isSystemVar) {
  92. invalidateSysVarValues()
  93. return
  94. }
  95. if (isConversationVar) {
  96. invalidateConversationVarValues()
  97. return
  98. }
  99. const vars = await fetchNodeInspectVars(appId, nodeId)
  100. setNodeInspectVars(nodeId, vars)
  101. }
  102. // after last run would call this
  103. const appendNodeInspectVars = (nodeId: string, payload: VarInInspect[], allNodes: Node[]) => {
  104. const nodes = produce(nodesWithInspectVars, (draft) => {
  105. const nodeInfo = allNodes.find(node => node.id === nodeId)
  106. if (nodeInfo) {
  107. const index = draft.findIndex(node => node.nodeId === nodeId)
  108. if (index === -1) {
  109. draft.unshift({
  110. nodeId,
  111. nodeType: nodeInfo.data.type,
  112. title: nodeInfo.data.title,
  113. vars: payload,
  114. nodePayload: nodeInfo.data,
  115. })
  116. }
  117. else {
  118. draft[index].vars = payload
  119. }
  120. }
  121. })
  122. setNodesWithInspectVars(nodes)
  123. handleCancelNodeSuccessStatus(nodeId)
  124. }
  125. const hasNodeInspectVar = (nodeId: string, varId: string) => {
  126. const targetNode = nodesWithInspectVars.find(item => item.nodeId === nodeId)
  127. if(!targetNode || !targetNode.vars)
  128. return false
  129. return targetNode.vars.some(item => item.id === varId)
  130. }
  131. const deleteInspectVar = async (nodeId: string, varId: string) => {
  132. if(hasNodeInspectVar(nodeId, varId)) {
  133. await doDeleteInspectVar(varId)
  134. deleteInspectVarInStore(nodeId, varId)
  135. }
  136. }
  137. const resetConversationVar = async (varId: string) => {
  138. await doResetConversationVar(varId)
  139. invalidateConversationVarValues()
  140. }
  141. const deleteNodeInspectorVars = async (nodeId: string) => {
  142. if (hasNodeInspectVars(nodeId)) {
  143. await doDeleteNodeInspectorVars(nodeId)
  144. deleteNodeInspectVarsInStore(nodeId)
  145. }
  146. }
  147. const deleteAllInspectorVars = async () => {
  148. await doDeleteAllInspectorVars()
  149. await invalidateConversationVarValues()
  150. await invalidateSysVarValues()
  151. deleteAllInspectVarsInStore()
  152. handleEdgeCancelRunningStatus()
  153. }
  154. const editInspectVarValue = useCallback(async (nodeId: string, varId: string, value: any) => {
  155. await doEditInspectorVar({
  156. varId,
  157. value,
  158. })
  159. setInspectVarValue(nodeId, varId, value)
  160. if (nodeId === VarInInspectType.conversation)
  161. invalidateConversationVarValues()
  162. if (nodeId === VarInInspectType.system)
  163. invalidateSysVarValues()
  164. }, [doEditInspectorVar, invalidateConversationVarValues, invalidateSysVarValues, setInspectVarValue])
  165. const renameInspectVarName = async (nodeId: string, oldName: string, newName: string) => {
  166. const varId = getVarId(nodeId, oldName)
  167. if (!varId)
  168. return
  169. const newSelector = [nodeId, newName]
  170. await doEditInspectorVar({
  171. varId,
  172. name: newName,
  173. })
  174. renameInspectVarNameInStore(nodeId, varId, newSelector)
  175. }
  176. const isInspectVarEdited = useCallback((nodeId: string, name: string) => {
  177. const inspectVar = getInspectVar(nodeId, name)
  178. if (!inspectVar)
  179. return false
  180. return inspectVar.edited
  181. }, [getInspectVar])
  182. const resetToLastRunVar = async (nodeId: string, varId: string) => {
  183. const isSysVar = nodeId === 'sys'
  184. const data = await doResetToLastRunValue(varId)
  185. if(isSysVar)
  186. invalidateSysVarValues()
  187. else
  188. resetToLastRunVarInStore(nodeId, varId, data.value)
  189. }
  190. return {
  191. conversationVars: conversationVars || [],
  192. systemVars: systemVars || [],
  193. nodesWithInspectVars,
  194. hasNodeInspectVars,
  195. hasSetInspectVar,
  196. fetchInspectVarValue,
  197. editInspectVarValue,
  198. renameInspectVarName,
  199. appendNodeInspectVars,
  200. deleteInspectVar,
  201. deleteNodeInspectorVars,
  202. deleteAllInspectorVars,
  203. isInspectVarEdited,
  204. resetToLastRunVar,
  205. invalidateSysVarValues,
  206. resetConversationVar,
  207. invalidateConversationVarValues,
  208. }
  209. }
  210. export default useInspectVarsCrud