Forráskód Böngészése

feat: support var auto rename in prompt editor (#3510)

Joel 1 éve
szülő
commit
570a5c72a9

+ 51 - 29
web/app/components/workflow/nodes/_base/components/variable/utils.ts

@@ -233,6 +233,16 @@ const matchNotSystemVars = (prompts: string[]) => {
   return uniqVars
 }
 
+const replaceOldVarInText = (text: string, oldVar: ValueSelector, newVar: ValueSelector) => {
+  if (!text || typeof text !== 'string')
+    return text
+
+  if (!newVar || newVar.length === 0)
+    return text
+
+  return text.replaceAll(`{{#${oldVar.join('.')}#}}`, `{{#${newVar.join('.')}#}}`)
+}
+
 export const getNodeUsedVars = (node: Node): ValueSelector[] => {
   const { data } = node
   const { type } = data
@@ -349,14 +359,21 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new
       }
       case BlockEnum.LLM: {
         const payload = data as LLMNodeType
-        // TODO: update in inputs
-        // if (payload.variables) {
-        //   payload.variables = payload.variables.map((v) => {
-        //     if (v.value_selector.join('.') === oldVarSelector.join('.'))
-        //       v.value_selector = newVarSelector
-        //     return v
-        //   })
-        // }
+        const isChatModel = payload.model?.mode === 'chat'
+        if (isChatModel) {
+          payload.prompt_template = (payload.prompt_template as PromptItem[]).map((prompt) => {
+            return {
+              ...prompt,
+              text: replaceOldVarInText(prompt.text, oldVarSelector, newVarSelector),
+            }
+          })
+        }
+        else {
+          payload.prompt_template = {
+            ...payload.prompt_template,
+            text: replaceOldVarInText((payload.prompt_template as PromptItem).text, oldVarSelector, newVarSelector),
+          }
+        }
         if (payload.context?.variable_selector?.join('.') === oldVarSelector.join('.'))
           payload.context.variable_selector = newVarSelector
 
@@ -408,30 +425,35 @@ export const updateNodeVars = (oldNode: Node, oldVarSelector: ValueSelector, new
         break
       }
       case BlockEnum.HttpRequest: {
-        // TODO: update in inputs
-        // const payload = data as HttpNodeType
-        // if (payload.variables) {
-        //   payload.variables = payload.variables.map((v) => {
-        //     if (v.value_selector.join('.') === oldVarSelector.join('.'))
-        //       v.value_selector = newVarSelector
-        //     return v
-        //   })
-        // }
+        const payload = data as HttpNodeType
+        payload.url = replaceOldVarInText(payload.url, oldVarSelector, newVarSelector)
+        payload.headers = replaceOldVarInText(payload.headers, oldVarSelector, newVarSelector)
+        payload.params = replaceOldVarInText(payload.params, oldVarSelector, newVarSelector)
+        payload.body.data = replaceOldVarInText(payload.body.data, oldVarSelector, newVarSelector)
         break
       }
       case BlockEnum.Tool: {
-        // TODO: update in inputs
-        // const payload = data as ToolNodeType
-        // if (payload.tool_parameters) {
-        //   payload.tool_parameters = payload.tool_parameters.map((v) => {
-        //     if (v.type === VarKindType.static)
-        //       return v
-
-        //     if (v.value_selector?.join('.') === oldVarSelector.join('.'))
-        //       v.value_selector = newVarSelector
-        //     return v
-        //   })
-        // }
+        const payload = data as ToolNodeType
+        const hasShouldRenameVar = Object.keys(payload.tool_parameters)?.filter(key => payload.tool_parameters[key].type !== ToolVarType.constant)
+        if (hasShouldRenameVar) {
+          Object.keys(payload.tool_parameters).forEach((key) => {
+            const value = payload.tool_parameters[key]
+            const { type } = value
+            if (type === ToolVarType.variable) {
+              payload.tool_parameters[key] = {
+                ...value,
+                value: newVarSelector,
+              }
+            }
+
+            if (type === ToolVarType.mixed) {
+              payload.tool_parameters[key] = {
+                ...value,
+                value: replaceOldVarInText(payload.tool_parameters[key].value as string, oldVarSelector, newVarSelector),
+              }
+            }
+          })
+        }
         break
       }
       case BlockEnum.VariableAssigner: {

+ 7 - 1
web/app/components/workflow/nodes/start/use-config.ts

@@ -28,11 +28,13 @@ const useConfig = (id: string, payload: StartNodeType) => {
     setFalse: hideRemoveVarConfirm,
   }] = useBoolean(false)
   const [removedVar, setRemovedVar] = useState<ValueSelector>([])
+  const [removedIndex, setRemoveIndex] = useState(0)
   const handleVarListChange = useCallback((newList: InputVar[], moreInfo?: { index: number; payload: MoreInfo }) => {
     if (moreInfo?.payload?.type === ChangeType.remove) {
       if (isVarUsedInNodes([id, moreInfo?.payload?.payload?.beforeKey || ''])) {
         showRemoveVarConfirm()
         setRemovedVar([id, moreInfo?.payload?.payload?.beforeKey || ''])
+        setRemoveIndex(moreInfo?.index as number)
         return
       }
     }
@@ -48,9 +50,13 @@ const useConfig = (id: string, payload: StartNodeType) => {
   }, [handleOutVarRenameChange, id, inputs, isVarUsedInNodes, setInputs, showRemoveVarConfirm])
 
   const removeVarInNode = useCallback(() => {
+    const newInputs = produce(inputs, (draft) => {
+      draft.variables.splice(removedIndex, 1)
+    })
+    setInputs(newInputs)
     removeUsedVarInNodes(removedVar)
     hideRemoveVarConfirm()
-  }, [hideRemoveVarConfirm, removeUsedVarInNodes, removedVar])
+  }, [hideRemoveVarConfirm, inputs, removeUsedVarInNodes, removedIndex, removedVar, setInputs])
 
   const handleAddVariable = useCallback((payload: InputVar) => {
     const newInputs = produce(inputs, (draft: StartNodeType) => {