From 1ccd97685c056f3684c77822fb473c186dc17205 Mon Sep 17 00:00:00 2001 From: Henry Heng Date: Sat, 16 Nov 2024 14:03:29 +0000 Subject: [PATCH] Bugfix/Override config vars (#3524) update bugfix for override config vars --- packages/server/src/utils/buildAgentGraph.ts | 9 ++- packages/server/src/utils/buildChatflow.ts | 7 +- packages/server/src/utils/index.ts | 74 ++++++++++++++------ 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/packages/server/src/utils/buildAgentGraph.ts b/packages/server/src/utils/buildAgentGraph.ts index 440ebb00747..3b9c94d2d43 100644 --- a/packages/server/src/utils/buildAgentGraph.ts +++ b/packages/server/src/utils/buildAgentGraph.ts @@ -529,7 +529,8 @@ const compileMultiAgentsGraph = async (params: MultiAgentsGraphParams) => { const newNodeInstance = new nodeModule.nodeClass() let flowNodeData = cloneDeep(workerNode.data) - if (overrideConfig && apiOverrideStatus) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides) + if (overrideConfig && apiOverrideStatus) + flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides, variableOverrides) flowNodeData = await resolveVariables( appServer.AppDataSource, flowNodeData, @@ -569,7 +570,8 @@ const compileMultiAgentsGraph = async (params: MultiAgentsGraphParams) => { let flowNodeData = cloneDeep(supervisorNode.data) - if (overrideConfig && apiOverrideStatus) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides) + if (overrideConfig && apiOverrideStatus) + flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides, variableOverrides) flowNodeData = await resolveVariables( appServer.AppDataSource, flowNodeData, @@ -758,7 +760,8 @@ const compileSeqAgentsGraph = async (params: SeqAgentsGraphParams) => { const newNodeInstance = new nodeModule.nodeClass() flowNodeData = cloneDeep(node.data) - if (overrideConfig && apiOverrideStatus) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides) + if (overrideConfig && apiOverrideStatus) + flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides, variableOverrides) flowNodeData = await resolveVariables( appServer.AppDataSource, flowNodeData, diff --git a/packages/server/src/utils/buildChatflow.ts b/packages/server/src/utils/buildChatflow.ts index 1e61278bfff..43836bee25f 100644 --- a/packages/server/src/utils/buildChatflow.ts +++ b/packages/server/src/utils/buildChatflow.ts @@ -388,7 +388,12 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals // Only override the config if its status is true if (incomingInput.overrideConfig && apiOverrideStatus) { - nodeToExecute.data = replaceInputsWithConfig(nodeToExecute.data, incomingInput.overrideConfig, nodeOverrides) + nodeToExecute.data = replaceInputsWithConfig( + nodeToExecute.data, + incomingInput.overrideConfig, + nodeOverrides, + variableOverrides + ) } const flowData: ICommonObject = { diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index 3392f21b276..9410a1b51be 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -519,7 +519,7 @@ export const buildFlow = async ({ // Only override the config if its status is true if (overrideConfig && apiOverrideStatus) { - flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides) + flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides, variableOverrides) } if (isUpsert) upsertHistory['flowData'] = saveUpsertFlowData(flowNodeData, upsertHistory) @@ -1001,9 +1001,15 @@ export const resolveVariables = async ( * @param {INodeData} flowNodeData * @param {ICommonObject} overrideConfig * @param {ICommonObject} nodeOverrides + * @param {ICommonObject[]} variableOverrides * @returns {INodeData} */ -export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: ICommonObject, nodeOverrides: ICommonObject) => { +export const replaceInputsWithConfig = ( + flowNodeData: INodeData, + overrideConfig: ICommonObject, + nodeOverrides: ICommonObject, + variableOverrides: ICommonObject[] +) => { const types = 'inputs' const isParameterEnabled = (nodeType: string, paramName: string): boolean => { @@ -1014,28 +1020,54 @@ export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: const getParamValues = (inputsObj: ICommonObject) => { for (const config in overrideConfig) { - // Always allow analytics config: https://docs.flowiseai.com/using-flowise/analytic#api - if (config !== 'analytics') { - // If overrideConfig[key] is object - if (overrideConfig[config] && typeof overrideConfig[config] === 'object') { - const nodeIds = Object.keys(overrideConfig[config]) - if (nodeIds.includes(flowNodeData.id)) { - // Check if this parameter is enabled for this node type - if (isParameterEnabled(flowNodeData.label, config)) { - inputsObj[config] = overrideConfig[config][flowNodeData.id] + /** + * Several conditions: + * 1. If config is 'analytics', always allow it + * 2. If config is 'vars', check its object and filter out the variables that are not enabled for override + * 3. If typeof config is an object, check if the node id is in the overrideConfig object and if the parameter (systemMessagePrompt) is enabled + * Example: + * "systemMessagePrompt": { + * "chatPromptTemplate_0": "You are an assistant" + * } + * 4. If typeof config is a string, check if the parameter is enabled + * Example: + * "systemMessagePrompt": "You are an assistant" + */ + + if (config === 'analytics') { + // pass + } else if (config === 'vars') { + if (typeof overrideConfig[config] === 'object') { + const filteredVars: ICommonObject = {} + + const vars = overrideConfig[config] + for (const variable in vars) { + const override = variableOverrides.find((v) => v.name === variable) + if (!override?.enabled) { + continue // Skip this variable if it's not enabled for override } - continue - } else if (nodeIds.some((nodeId) => nodeId.includes(flowNodeData.name))) { - /* - * "systemMessagePrompt": { - * "chatPromptTemplate_0": "You are an assistant" <---- continue for loop if current node is chatPromptTemplate_1 - * } - */ - continue + filteredVars[variable] = vars[variable] } + overrideConfig[config] = filteredVars } - - // Only proceed if the parameter is enabled for this node type + } else if (overrideConfig[config] && typeof overrideConfig[config] === 'object') { + const nodeIds = Object.keys(overrideConfig[config]) + if (nodeIds.includes(flowNodeData.id)) { + // Check if this parameter is enabled + if (isParameterEnabled(flowNodeData.label, config)) { + inputsObj[config] = overrideConfig[config][flowNodeData.id] + } + continue + } else if (nodeIds.some((nodeId) => nodeId.includes(flowNodeData.name))) { + /* + * "systemMessagePrompt": { + * "chatPromptTemplate_0": "You are an assistant" <---- continue for loop if current node is chatPromptTemplate_1 + * } + */ + continue + } + } else { + // Only proceed if the parameter is enabled if (!isParameterEnabled(flowNodeData.label, config)) { continue }