mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 15:00:57 +03:00
Enable/disable variables in override configuration (#3467)
* Add ability to enable/disable which variables can be overriden during external predictions * Remove duplicated code * Remove rate limit and allowed domains tab from chatflow configuration * Show tooltip in api code dialog for override config properties * Fix server crash when override config is not available * update UI for chatflow config security, file upload * Fix UI issues in security tab of chatflow configuration dialog * Fix override config options not updating when nodes change * Fix crash in api code dialog when overrideConfig is not available for a chatflow/agentflow. Also fix input config in api code dialog not updating when nodes change. * Refactor override config and add override config for variables * Update api code dialog - update how override config is read and show variable overrides * Update how node and variable overrides are read and resolved * Prevent api code dialog mounting on page load and only mount when api code dialog button is clicked. this should fix loading incorrect data. * Fix variables list not showing when overrideConfig is not available * add overrideconfig to agentflow and upsert vector * temporarily removed enable overrideconfig on upsert, fix linting issues --------- Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import path from 'path'
|
||||
import fs from 'fs'
|
||||
import logger from './logger'
|
||||
import {
|
||||
IChatFlow,
|
||||
IComponentCredentials,
|
||||
IComponentNodes,
|
||||
ICredentialDataDecrypted,
|
||||
@@ -434,6 +435,9 @@ type BuildFlowParams = {
|
||||
apiMessageId: string
|
||||
appDataSource: DataSource
|
||||
overrideConfig?: ICommonObject
|
||||
apiOverrideStatus?: boolean
|
||||
nodeOverrides?: ICommonObject
|
||||
variableOverrides?: ICommonObject[]
|
||||
cachePool?: CachePool
|
||||
isUpsert?: boolean
|
||||
stopNodeId?: string
|
||||
@@ -462,6 +466,9 @@ export const buildFlow = async ({
|
||||
chatflowid,
|
||||
appDataSource,
|
||||
overrideConfig,
|
||||
apiOverrideStatus = false,
|
||||
nodeOverrides = {},
|
||||
variableOverrides = [],
|
||||
cachePool,
|
||||
isUpsert,
|
||||
stopNodeId,
|
||||
@@ -509,7 +516,11 @@ export const buildFlow = async ({
|
||||
const newNodeInstance = new nodeModule.nodeClass()
|
||||
|
||||
let flowNodeData = cloneDeep(reactFlowNode.data)
|
||||
if (overrideConfig) flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig)
|
||||
|
||||
// Only override the config if its status is true
|
||||
if (overrideConfig && apiOverrideStatus) {
|
||||
flowNodeData = replaceInputsWithConfig(flowNodeData, overrideConfig, nodeOverrides)
|
||||
}
|
||||
|
||||
if (isUpsert) upsertHistory['flowData'] = saveUpsertFlowData(flowNodeData, upsertHistory)
|
||||
|
||||
@@ -520,7 +531,8 @@ export const buildFlow = async ({
|
||||
question,
|
||||
chatHistory,
|
||||
flowData,
|
||||
uploadedFilesContent
|
||||
uploadedFilesContent,
|
||||
variableOverrides
|
||||
)
|
||||
|
||||
if (isUpsert && stopNodeId && nodeId === stopNodeId) {
|
||||
@@ -713,13 +725,19 @@ export const clearSessionMemory = async (
|
||||
}
|
||||
}
|
||||
|
||||
const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: ICommonObject) => {
|
||||
const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: ICommonObject, variableOverrides?: ICommonObject[]) => {
|
||||
const variables = await appDataSource.getRepository(Variable).find()
|
||||
|
||||
// override variables defined in overrideConfig
|
||||
// nodeData.inputs.vars is an Object, check each property and override the variable
|
||||
if (overrideConfig?.vars) {
|
||||
if (overrideConfig?.vars && variableOverrides) {
|
||||
for (const propertyName of Object.getOwnPropertyNames(overrideConfig.vars)) {
|
||||
// Check if this variable is enabled for override
|
||||
const override = variableOverrides.find((v) => v.name === propertyName)
|
||||
if (!override?.enabled) {
|
||||
continue // Skip this variable if it's not enabled for override
|
||||
}
|
||||
|
||||
const foundVar = variables.find((v) => v.name === propertyName)
|
||||
if (foundVar) {
|
||||
// even if the variable was defined as runtime, we override it with static value
|
||||
@@ -776,7 +794,8 @@ export const getVariableValue = async (
|
||||
chatHistory: IMessage[],
|
||||
isAcceptVariable = false,
|
||||
flowData?: ICommonObject,
|
||||
uploadedFilesContent?: string
|
||||
uploadedFilesContent?: string,
|
||||
variableOverrides: ICommonObject[] = []
|
||||
) => {
|
||||
const isObject = typeof paramValue === 'object'
|
||||
const initialValue = (isObject ? JSON.stringify(paramValue) : paramValue) ?? ''
|
||||
@@ -818,7 +837,7 @@ export const getVariableValue = async (
|
||||
}
|
||||
|
||||
if (variableFullPath.startsWith('$vars.')) {
|
||||
const vars = await getGlobalVariable(appDataSource, flowData)
|
||||
const vars = await getGlobalVariable(appDataSource, flowData, variableOverrides)
|
||||
const variableValue = get(vars, variableFullPath.replace('$vars.', ''))
|
||||
if (variableValue) {
|
||||
variableDict[`{{${variableFullPath}}}`] = variableValue
|
||||
@@ -927,7 +946,8 @@ export const resolveVariables = async (
|
||||
question: string,
|
||||
chatHistory: IMessage[],
|
||||
flowData?: ICommonObject,
|
||||
uploadedFilesContent?: string
|
||||
uploadedFilesContent?: string,
|
||||
variableOverrides: ICommonObject[] = []
|
||||
): Promise<INodeData> => {
|
||||
let flowNodeData = cloneDeep(reactFlowNodeData)
|
||||
const types = 'inputs'
|
||||
@@ -946,7 +966,8 @@ export const resolveVariables = async (
|
||||
chatHistory,
|
||||
undefined,
|
||||
flowData,
|
||||
uploadedFilesContent
|
||||
uploadedFilesContent,
|
||||
variableOverrides
|
||||
)
|
||||
resolvedInstances.push(resolvedInstance)
|
||||
}
|
||||
@@ -961,7 +982,8 @@ export const resolveVariables = async (
|
||||
chatHistory,
|
||||
isAcceptVariable,
|
||||
flowData,
|
||||
uploadedFilesContent
|
||||
uploadedFilesContent,
|
||||
variableOverrides
|
||||
)
|
||||
paramsObj[key] = resolvedInstance
|
||||
}
|
||||
@@ -978,18 +1000,28 @@ export const resolveVariables = async (
|
||||
* Loop through each inputs and replace their value with override config values
|
||||
* @param {INodeData} flowNodeData
|
||||
* @param {ICommonObject} overrideConfig
|
||||
* @param {ICommonObject} nodeOverrides
|
||||
* @returns {INodeData}
|
||||
*/
|
||||
export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: ICommonObject) => {
|
||||
export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig: ICommonObject, nodeOverrides: ICommonObject) => {
|
||||
const types = 'inputs'
|
||||
|
||||
const isParameterEnabled = (nodeType: string, paramName: string): boolean => {
|
||||
if (!nodeOverrides[nodeType]) return false
|
||||
const parameter = nodeOverrides[nodeType].find((param: any) => param.name === paramName)
|
||||
return parameter?.enabled ?? false
|
||||
}
|
||||
|
||||
const getParamValues = (inputsObj: ICommonObject) => {
|
||||
for (const config in overrideConfig) {
|
||||
// If overrideConfig[key] is object
|
||||
if (overrideConfig[config] && typeof overrideConfig[config] === 'object') {
|
||||
const nodeIds = Object.keys(overrideConfig[config])
|
||||
if (nodeIds.includes(flowNodeData.id)) {
|
||||
inputsObj[config] = overrideConfig[config][flowNodeData.id]
|
||||
// Check if this parameter is enabled for this node type
|
||||
if (isParameterEnabled(flowNodeData.label, config)) {
|
||||
inputsObj[config] = overrideConfig[config][flowNodeData.id]
|
||||
}
|
||||
continue
|
||||
} else if (nodeIds.some((nodeId) => nodeId.includes(flowNodeData.name))) {
|
||||
/*
|
||||
@@ -1001,6 +1033,11 @@ export const replaceInputsWithConfig = (flowNodeData: INodeData, overrideConfig:
|
||||
}
|
||||
}
|
||||
|
||||
// Only proceed if the parameter is enabled for this node type
|
||||
if (!isParameterEnabled(flowNodeData.label, config)) {
|
||||
continue
|
||||
}
|
||||
|
||||
let paramValue = inputsObj[config]
|
||||
const overrideConfigValue = overrideConfig[config]
|
||||
if (overrideConfigValue) {
|
||||
@@ -1600,3 +1637,16 @@ export const aMonthAgo = () => {
|
||||
date.setMonth(new Date().getMonth() - 1)
|
||||
return date
|
||||
}
|
||||
|
||||
export const getAPIOverrideConfig = (chatflow: IChatFlow) => {
|
||||
try {
|
||||
const apiConfig = chatflow.apiConfig ? JSON.parse(chatflow.apiConfig) : {}
|
||||
const nodeOverrides = apiConfig.overrideConfig && apiConfig.overrideConfig.nodes ? apiConfig.overrideConfig.nodes : {}
|
||||
const variableOverrides = apiConfig.overrideConfig && apiConfig.overrideConfig.variables ? apiConfig.overrideConfig.variables : []
|
||||
const apiOverrideStatus = apiConfig.overrideConfig && apiConfig.overrideConfig.status ? apiConfig.overrideConfig.status : false
|
||||
|
||||
return { nodeOverrides, variableOverrides, apiOverrideStatus }
|
||||
} catch (error) {
|
||||
return { nodeOverrides: {}, variableOverrides: [], apiOverrideStatus: false }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user