Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/Override config vars #3524

Merged
merged 1 commit into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/server/src/utils/buildAgentGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion packages/server/src/utils/buildChatflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
74 changes: 53 additions & 21 deletions packages/server/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 => {
Expand All @@ -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
}
Expand Down
Loading