mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 21:00:58 +03:00
Feature/Add ability to get vars from text input (#2986)
add ability to get vars from text input
This commit is contained in:
@@ -503,7 +503,14 @@ export const buildFlow = async ({
|
||||
|
||||
if (isUpsert) upsertHistory['flowData'] = saveUpsertFlowData(flowNodeData, upsertHistory)
|
||||
|
||||
const reactFlowNodeData: INodeData = resolveVariables(flowNodeData, flowNodes, question, chatHistory)
|
||||
const reactFlowNodeData: INodeData = await resolveVariables(
|
||||
appDataSource,
|
||||
flowNodeData,
|
||||
flowNodes,
|
||||
question,
|
||||
chatHistory,
|
||||
overrideConfig
|
||||
)
|
||||
|
||||
if (isUpsert && stopNodeId && nodeId === stopNodeId) {
|
||||
logger.debug(`[server]: Upserting ${reactFlowNode.data.label} (${reactFlowNode.data.id})`)
|
||||
@@ -691,6 +698,53 @@ export const clearSessionMemory = async (
|
||||
}
|
||||
}
|
||||
|
||||
const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: 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) {
|
||||
for (const propertyName of Object.getOwnPropertyNames(overrideConfig.vars)) {
|
||||
const foundVar = variables.find((v) => v.name === propertyName)
|
||||
if (foundVar) {
|
||||
// even if the variable was defined as runtime, we override it with static value
|
||||
foundVar.type = 'static'
|
||||
foundVar.value = overrideConfig.vars[propertyName]
|
||||
} else {
|
||||
// add it the variables, if not found locally in the db
|
||||
variables.push({
|
||||
name: propertyName,
|
||||
type: 'static',
|
||||
value: overrideConfig.vars[propertyName],
|
||||
id: '',
|
||||
updatedDate: new Date(),
|
||||
createdDate: new Date()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let vars = {}
|
||||
if (variables.length) {
|
||||
for (const item of variables) {
|
||||
let value = item.value
|
||||
|
||||
// read from .env file
|
||||
if (item.type === 'runtime') {
|
||||
value = process.env[item.name] ?? ''
|
||||
}
|
||||
|
||||
Object.defineProperty(vars, item.name, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: value
|
||||
})
|
||||
}
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
/**
|
||||
* Get variable value from outputResponses.output
|
||||
* @param {string} paramValue
|
||||
@@ -699,12 +753,14 @@ export const clearSessionMemory = async (
|
||||
* @param {boolean} isAcceptVariable
|
||||
* @returns {string}
|
||||
*/
|
||||
export const getVariableValue = (
|
||||
export const getVariableValue = async (
|
||||
appDataSource: DataSource,
|
||||
paramValue: string | object,
|
||||
reactFlowNodes: IReactFlowNode[],
|
||||
question: string,
|
||||
chatHistory: IMessage[],
|
||||
isAcceptVariable = false
|
||||
isAcceptVariable = false,
|
||||
overrideConfig?: ICommonObject
|
||||
) => {
|
||||
const isObject = typeof paramValue === 'object'
|
||||
let returnVal = (isObject ? JSON.stringify(paramValue) : paramValue) ?? ''
|
||||
@@ -740,6 +796,15 @@ export const getVariableValue = (
|
||||
variableDict[`{{${variableFullPath}}}`] = handleEscapeCharacters(convertChatHistoryToText(chatHistory), false)
|
||||
}
|
||||
|
||||
if (variableFullPath.startsWith('$vars.')) {
|
||||
const vars = await getGlobalVariable(appDataSource, overrideConfig)
|
||||
const variableValue = get(vars, variableFullPath.replace('$vars.', ''))
|
||||
if (variableValue) {
|
||||
variableDict[`{{${variableFullPath}}}`] = variableValue
|
||||
returnVal = returnVal.split(`{{${variableFullPath}}}`).join(variableValue)
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve values with following case.
|
||||
// 1: <variableNodeId>.data.instance
|
||||
// 2: <variableNodeId>.data.instance.pathtokey
|
||||
@@ -826,35 +891,53 @@ export const getVariableValue = (
|
||||
* @param {string} question
|
||||
* @returns {INodeData}
|
||||
*/
|
||||
export const resolveVariables = (
|
||||
export const resolveVariables = async (
|
||||
appDataSource: DataSource,
|
||||
reactFlowNodeData: INodeData,
|
||||
reactFlowNodes: IReactFlowNode[],
|
||||
question: string,
|
||||
chatHistory: IMessage[]
|
||||
): INodeData => {
|
||||
chatHistory: IMessage[],
|
||||
overrideConfig?: ICommonObject
|
||||
): Promise<INodeData> => {
|
||||
let flowNodeData = cloneDeep(reactFlowNodeData)
|
||||
const types = 'inputs'
|
||||
|
||||
const getParamValues = (paramsObj: ICommonObject) => {
|
||||
const getParamValues = async (paramsObj: ICommonObject) => {
|
||||
for (const key in paramsObj) {
|
||||
const paramValue: string = paramsObj[key]
|
||||
if (Array.isArray(paramValue)) {
|
||||
const resolvedInstances = []
|
||||
for (const param of paramValue) {
|
||||
const resolvedInstance = getVariableValue(param, reactFlowNodes, question, chatHistory)
|
||||
const resolvedInstance = await getVariableValue(
|
||||
appDataSource,
|
||||
param,
|
||||
reactFlowNodes,
|
||||
question,
|
||||
chatHistory,
|
||||
undefined,
|
||||
overrideConfig
|
||||
)
|
||||
resolvedInstances.push(resolvedInstance)
|
||||
}
|
||||
paramsObj[key] = resolvedInstances
|
||||
} else {
|
||||
const isAcceptVariable = reactFlowNodeData.inputParams.find((param) => param.name === key)?.acceptVariable ?? false
|
||||
const resolvedInstance = getVariableValue(paramValue, reactFlowNodes, question, chatHistory, isAcceptVariable)
|
||||
const resolvedInstance = await getVariableValue(
|
||||
appDataSource,
|
||||
paramValue,
|
||||
reactFlowNodes,
|
||||
question,
|
||||
chatHistory,
|
||||
isAcceptVariable,
|
||||
overrideConfig
|
||||
)
|
||||
paramsObj[key] = resolvedInstance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const paramsObj = flowNodeData[types] ?? {}
|
||||
getParamValues(paramsObj)
|
||||
await getParamValues(paramsObj)
|
||||
|
||||
return flowNodeData
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user