您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

use-inspect-vars-crud.ts 8.9KB

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