Chore/remove app server functions from utils file (#3671)

* remove app server functions from utils file

* hide override config variables if its empty
This commit is contained in:
Henry Heng 2024-12-10 14:11:29 +00:00 committed by GitHub
parent ddca80d4e0
commit 5c5416240b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 55 additions and 16 deletions

View File

@ -914,7 +914,7 @@ const updateVectorStoreConfigOnly = async (data: ICommonObject) => {
) )
} }
} }
const saveVectorStoreConfig = async (data: ICommonObject) => { const saveVectorStoreConfig = async (data: ICommonObject, isStrictSave = true) => {
try { try {
const appServer = getRunningExpressApp() const appServer = getRunningExpressApp()
const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({
@ -932,6 +932,7 @@ const saveVectorStoreConfig = async (data: ICommonObject) => {
} else if (entity.embeddingConfig && !data.embeddingName && !data.embeddingConfig) { } else if (entity.embeddingConfig && !data.embeddingName && !data.embeddingConfig) {
data.embeddingConfig = JSON.parse(entity.embeddingConfig)?.config data.embeddingConfig = JSON.parse(entity.embeddingConfig)?.config
data.embeddingName = JSON.parse(entity.embeddingConfig)?.name data.embeddingName = JSON.parse(entity.embeddingConfig)?.name
if (isStrictSave) entity.embeddingConfig = null
} else if (!data.embeddingName && !data.embeddingConfig) { } else if (!data.embeddingName && !data.embeddingConfig) {
entity.embeddingConfig = null entity.embeddingConfig = null
} }
@ -944,6 +945,7 @@ const saveVectorStoreConfig = async (data: ICommonObject) => {
} else if (entity.vectorStoreConfig && !data.vectorStoreName && !data.vectorStoreConfig) { } else if (entity.vectorStoreConfig && !data.vectorStoreName && !data.vectorStoreConfig) {
data.vectorStoreConfig = JSON.parse(entity.vectorStoreConfig)?.config data.vectorStoreConfig = JSON.parse(entity.vectorStoreConfig)?.config
data.vectorStoreName = JSON.parse(entity.vectorStoreConfig)?.name data.vectorStoreName = JSON.parse(entity.vectorStoreConfig)?.name
if (isStrictSave) entity.vectorStoreConfig = null
} else if (!data.vectorStoreName && !data.vectorStoreConfig) { } else if (!data.vectorStoreName && !data.vectorStoreConfig) {
entity.vectorStoreConfig = null entity.vectorStoreConfig = null
} }
@ -956,6 +958,7 @@ const saveVectorStoreConfig = async (data: ICommonObject) => {
} else if (entity.recordManagerConfig && !data.recordManagerName && !data.recordManagerConfig) { } else if (entity.recordManagerConfig && !data.recordManagerName && !data.recordManagerConfig) {
data.recordManagerConfig = JSON.parse(entity.recordManagerConfig)?.config data.recordManagerConfig = JSON.parse(entity.recordManagerConfig)?.config
data.recordManagerName = JSON.parse(entity.recordManagerConfig)?.name data.recordManagerName = JSON.parse(entity.recordManagerConfig)?.name
if (isStrictSave) entity.recordManagerConfig = null
} else if (!data.recordManagerName && !data.recordManagerConfig) { } else if (!data.recordManagerName && !data.recordManagerConfig) {
entity.recordManagerConfig = null entity.recordManagerConfig = null
} }
@ -975,15 +978,15 @@ const saveVectorStoreConfig = async (data: ICommonObject) => {
} }
} }
const insertIntoVectorStore = async (data: ICommonObject) => { const insertIntoVectorStore = async (data: ICommonObject, isStrictSave = true) => {
try { try {
const appServer = getRunningExpressApp() const appServer = getRunningExpressApp()
const entity = await saveVectorStoreConfig(data) const entity = await saveVectorStoreConfig(data, isStrictSave)
entity.status = DocumentStoreStatus.UPSERTING entity.status = DocumentStoreStatus.UPSERTING
await appServer.AppDataSource.getRepository(DocumentStore).save(entity) await appServer.AppDataSource.getRepository(DocumentStore).save(entity)
// TODO: to be moved into a worker thread... // TODO: to be moved into a worker thread...
const indexResult = await _insertIntoVectorStoreWorkerThread(data) const indexResult = await _insertIntoVectorStoreWorkerThread(data, isStrictSave)
return indexResult return indexResult
} catch (error) { } catch (error) {
throw new InternalFlowiseError( throw new InternalFlowiseError(
@ -993,10 +996,10 @@ const insertIntoVectorStore = async (data: ICommonObject) => {
} }
} }
const _insertIntoVectorStoreWorkerThread = async (data: ICommonObject) => { const _insertIntoVectorStoreWorkerThread = async (data: ICommonObject, isStrictSave = true) => {
try { try {
const appServer = getRunningExpressApp() const appServer = getRunningExpressApp()
const entity = await saveVectorStoreConfig(data) const entity = await saveVectorStoreConfig(data, isStrictSave)
let upsertHistory: Record<string, any> = {} let upsertHistory: Record<string, any> = {}
const chatflowid = data.storeId // fake chatflowid because this is not tied to any chatflow const chatflowid = data.storeId // fake chatflowid because this is not tied to any chatflow
@ -1520,7 +1523,7 @@ const upsertDocStoreMiddleware = async (
recordManagerConfig recordManagerConfig
} }
const res = await insertIntoVectorStore(insertData) const res = await insertIntoVectorStore(insertData, false)
res.docId = newDocId res.docId = newDocId
return res return res

View File

@ -16,6 +16,7 @@ import { IDepthQueue, IReactFlowNode } from '../../Interface'
import { ICommonObject, INodeData } from 'flowise-components' import { ICommonObject, INodeData } from 'flowise-components'
import { convertToOpenAIFunction } from '@langchain/core/utils/function_calling' import { convertToOpenAIFunction } from '@langchain/core/utils/function_calling'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { Variable } from '../../database/entities/Variable'
const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n' const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n'
const ARTIFACTS_PREFIX = '\n\n----FLOWISE_ARTIFACTS----\n\n' const ARTIFACTS_PREFIX = '\n\n----FLOWISE_ARTIFACTS----\n\n'
@ -59,6 +60,7 @@ const buildAndInitTool = async (chatflowid: string, _chatId?: string, _apiMessag
} }
startingNodeIds = [...new Set(startingNodeIds)] startingNodeIds = [...new Set(startingNodeIds)]
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
const reactFlowNodes = await buildFlow({ const reactFlowNodes = await buildFlow({
@ -77,6 +79,7 @@ const buildAndInitTool = async (chatflowid: string, _chatId?: string, _apiMessag
appDataSource: appServer.AppDataSource, appDataSource: appServer.AppDataSource,
apiOverrideStatus, apiOverrideStatus,
nodeOverrides, nodeOverrides,
availableVariables,
variableOverrides variableOverrides
}) })
@ -99,6 +102,7 @@ const buildAndInitTool = async (chatflowid: string, _chatId?: string, _apiMessag
[], [],
flowDataObj, flowDataObj,
'', '',
availableVariables,
variableOverrides variableOverrides
) )
let nodeToExecuteData = reactFlowNodeData let nodeToExecuteData = reactFlowNodeData

View File

@ -45,6 +45,7 @@ import { replaceInputsWithConfig, resolveVariables } from '.'
import { InternalFlowiseError } from '../errors/internalFlowiseError' import { InternalFlowiseError } from '../errors/internalFlowiseError'
import { getErrorMessage } from '../errors/utils' import { getErrorMessage } from '../errors/utils'
import logger from './logger' import logger from './logger'
import { Variable } from '../database/entities/Variable'
/** /**
* Build Agent Graph * Build Agent Graph
@ -114,6 +115,7 @@ export const buildAgentGraph = async (
} }
/*** Get API Config ***/ /*** Get API Config ***/
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
// Initialize nodes like ChatModels, Tools, etc. // Initialize nodes like ChatModels, Tools, etc.
@ -135,6 +137,7 @@ export const buildAgentGraph = async (
overrideConfig: incomingInput?.overrideConfig, overrideConfig: incomingInput?.overrideConfig,
apiOverrideStatus, apiOverrideStatus,
nodeOverrides, nodeOverrides,
availableVariables,
variableOverrides, variableOverrides,
cachePool: appServer.cachePool, cachePool: appServer.cachePool,
isUpsert: false, isUpsert: false,
@ -519,6 +522,7 @@ const compileMultiAgentsGraph = async (params: MultiAgentsGraphParams) => {
const workerNodes = reactFlowNodes.filter((node) => workerNodeIds.includes(node.data.id)) const workerNodes = reactFlowNodes.filter((node) => workerNodeIds.includes(node.data.id))
/*** Get API Config ***/ /*** Get API Config ***/
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
let supervisorWorkers: { [key: string]: IMultiAgentNode[] } = {} let supervisorWorkers: { [key: string]: IMultiAgentNode[] } = {}
@ -540,6 +544,7 @@ const compileMultiAgentsGraph = async (params: MultiAgentsGraphParams) => {
chatHistory, chatHistory,
overrideConfig, overrideConfig,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
@ -581,6 +586,7 @@ const compileMultiAgentsGraph = async (params: MultiAgentsGraphParams) => {
chatHistory, chatHistory,
overrideConfig, overrideConfig,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
@ -753,6 +759,9 @@ const compileSeqAgentsGraph = async (params: SeqAgentsGraphParams) => {
let conditionalToolNodes: Record<string, { source: ISeqAgentNode; toolNodes: ISeqAgentNode[] }> = {} let conditionalToolNodes: Record<string, { source: ISeqAgentNode; toolNodes: ISeqAgentNode[] }> = {}
let bindModel: Record<string, any> = {} let bindModel: Record<string, any> = {}
let interruptToolNodeNames = [] let interruptToolNodeNames = []
/*** Get API Config ***/
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
const initiateNode = async (node: IReactFlowNode) => { const initiateNode = async (node: IReactFlowNode) => {
@ -771,6 +780,7 @@ const compileSeqAgentsGraph = async (params: SeqAgentsGraphParams) => {
chatHistory, chatHistory,
overrideConfig, overrideConfig,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )

View File

@ -57,6 +57,7 @@ import { getErrorMessage } from '../errors/utils'
import { ChatMessage } from '../database/entities/ChatMessage' import { ChatMessage } from '../database/entities/ChatMessage'
import { IAction } from 'flowise-components' import { IAction } from 'flowise-components'
import { FLOWISE_METRIC_COUNTERS, FLOWISE_COUNTER_STATUS } from '../Interface.Metrics' import { FLOWISE_METRIC_COUNTERS, FLOWISE_COUNTER_STATUS } from '../Interface.Metrics'
import { Variable } from '../database/entities/Variable'
/** /**
* Build Chatflow * Build Chatflow
@ -350,6 +351,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id)) const startingNodes = nodes.filter((nd) => startingNodeIds.includes(nd.id))
/*** Get API Config ***/ /*** Get API Config ***/
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
logger.debug(`[server]: Start building chatflow ${chatflowid}`) logger.debug(`[server]: Start building chatflow ${chatflowid}`)
@ -373,6 +375,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
overrideConfig: incomingInput?.overrideConfig, overrideConfig: incomingInput?.overrideConfig,
apiOverrideStatus, apiOverrideStatus,
nodeOverrides, nodeOverrides,
availableVariables,
variableOverrides, variableOverrides,
cachePool: appServer.cachePool, cachePool: appServer.cachePool,
isUpsert: false, isUpsert: false,
@ -427,6 +430,7 @@ export const utilBuildChatflow = async (req: Request, isInternal: boolean = fals
chatHistory, chatHistory,
flowData, flowData,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
nodeToExecuteData = reactFlowNodeData nodeToExecuteData = reactFlowNodeData

View File

@ -1,3 +1,7 @@
/**
* Strictly no getRepository, appServer here, must be passed as parameter
*/
import path from 'path' import path from 'path'
import fs from 'fs' import fs from 'fs'
import logger from './logger' import logger from './logger'
@ -17,6 +21,7 @@ import {
IOverrideConfig, IOverrideConfig,
IReactFlowEdge, IReactFlowEdge,
IReactFlowNode, IReactFlowNode,
IVariable,
IVariableDict, IVariableDict,
IVariableOverride, IVariableOverride,
IncomingInput IncomingInput
@ -439,6 +444,7 @@ type BuildFlowParams = {
overrideConfig?: ICommonObject overrideConfig?: ICommonObject
apiOverrideStatus?: boolean apiOverrideStatus?: boolean
nodeOverrides?: INodeOverrides nodeOverrides?: INodeOverrides
availableVariables?: IVariable[]
variableOverrides?: IVariableOverride[] variableOverrides?: IVariableOverride[]
cachePool?: CachePool cachePool?: CachePool
isUpsert?: boolean isUpsert?: boolean
@ -470,6 +476,7 @@ export const buildFlow = async ({
overrideConfig, overrideConfig,
apiOverrideStatus = false, apiOverrideStatus = false,
nodeOverrides = {}, nodeOverrides = {},
availableVariables = [],
variableOverrides = [], variableOverrides = [],
cachePool, cachePool,
isUpsert, isUpsert,
@ -534,6 +541,7 @@ export const buildFlow = async ({
chatHistory, chatHistory,
flowData, flowData,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
@ -727,9 +735,12 @@ export const clearSessionMemory = async (
} }
} }
const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: ICommonObject, variableOverrides?: ICommonObject[]) => { const getGlobalVariable = async (
const variables = await appDataSource.getRepository(Variable).find() appDataSource: DataSource,
overrideConfig?: ICommonObject,
availableVariables: IVariable[] = [],
variableOverrides?: ICommonObject[]
) => {
// override variables defined in overrideConfig // override variables defined in overrideConfig
// nodeData.inputs.vars is an Object, check each property and override the variable // nodeData.inputs.vars is an Object, check each property and override the variable
if (overrideConfig?.vars && variableOverrides) { if (overrideConfig?.vars && variableOverrides) {
@ -740,14 +751,14 @@ const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: ICo
continue // Skip this variable if it's not enabled for override continue // Skip this variable if it's not enabled for override
} }
const foundVar = variables.find((v) => v.name === propertyName) const foundVar = availableVariables.find((v) => v.name === propertyName)
if (foundVar) { if (foundVar) {
// even if the variable was defined as runtime, we override it with static value // even if the variable was defined as runtime, we override it with static value
foundVar.type = 'static' foundVar.type = 'static'
foundVar.value = overrideConfig.vars[propertyName] foundVar.value = overrideConfig.vars[propertyName]
} else { } else {
// add it the variables, if not found locally in the db // add it the variables, if not found locally in the db
variables.push({ availableVariables.push({
name: propertyName, name: propertyName,
type: 'static', type: 'static',
value: overrideConfig.vars[propertyName], value: overrideConfig.vars[propertyName],
@ -760,8 +771,8 @@ const getGlobalVariable = async (appDataSource: DataSource, overrideConfig?: ICo
} }
let vars = {} let vars = {}
if (variables.length) { if (availableVariables.length) {
for (const item of variables) { for (const item of availableVariables) {
let value = item.value let value = item.value
// read from .env file // read from .env file
@ -797,6 +808,7 @@ export const getVariableValue = async (
isAcceptVariable = false, isAcceptVariable = false,
flowData?: ICommonObject, flowData?: ICommonObject,
uploadedFilesContent?: string, uploadedFilesContent?: string,
availableVariables: IVariable[] = [],
variableOverrides: ICommonObject[] = [] variableOverrides: ICommonObject[] = []
) => { ) => {
const isObject = typeof paramValue === 'object' const isObject = typeof paramValue === 'object'
@ -839,7 +851,7 @@ export const getVariableValue = async (
} }
if (variableFullPath.startsWith('$vars.')) { if (variableFullPath.startsWith('$vars.')) {
const vars = await getGlobalVariable(appDataSource, flowData, variableOverrides) const vars = await getGlobalVariable(appDataSource, flowData, availableVariables, variableOverrides)
const variableValue = get(vars, variableFullPath.replace('$vars.', '')) const variableValue = get(vars, variableFullPath.replace('$vars.', ''))
if (variableValue) { if (variableValue) {
variableDict[`{{${variableFullPath}}}`] = variableValue variableDict[`{{${variableFullPath}}}`] = variableValue
@ -949,6 +961,7 @@ export const resolveVariables = async (
chatHistory: IMessage[], chatHistory: IMessage[],
flowData?: ICommonObject, flowData?: ICommonObject,
uploadedFilesContent?: string, uploadedFilesContent?: string,
availableVariables: IVariable[] = [],
variableOverrides: ICommonObject[] = [] variableOverrides: ICommonObject[] = []
): Promise<INodeData> => { ): Promise<INodeData> => {
let flowNodeData = cloneDeep(reactFlowNodeData) let flowNodeData = cloneDeep(reactFlowNodeData)
@ -969,6 +982,7 @@ export const resolveVariables = async (
undefined, undefined,
flowData, flowData,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
resolvedInstances.push(resolvedInstance) resolvedInstances.push(resolvedInstance)
@ -985,6 +999,7 @@ export const resolveVariables = async (
isAcceptVariable, isAcceptVariable,
flowData, flowData,
uploadedFilesContent, uploadedFilesContent,
availableVariables,
variableOverrides variableOverrides
) )
paramsObj[key] = resolvedInstance paramsObj[key] = resolvedInstance

View File

@ -25,6 +25,7 @@ import { StatusCodes } from 'http-status-codes'
import { getErrorMessage } from '../errors/utils' import { getErrorMessage } from '../errors/utils'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../Interface.Metrics' import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../Interface.Metrics'
import { Variable } from '../database/entities/Variable'
/** /**
* Upsert documents * Upsert documents
* @param {Request} req * @param {Request} req
@ -157,6 +158,7 @@ export const upsertVector = async (req: Request, isInternal: boolean = false) =>
const { startingNodeIds, depthQueue } = getStartingNodes(filteredGraph, stopNodeId) const { startingNodeIds, depthQueue } = getStartingNodes(filteredGraph, stopNodeId)
/*** Get API Config ***/ /*** Get API Config ***/
const availableVariables = await appServer.AppDataSource.getRepository(Variable).find()
const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow) const { nodeOverrides, variableOverrides, apiOverrideStatus } = getAPIOverrideConfig(chatflow)
// For "files" input, add a new node override with the actual input name such as pdfFile, txtFile, etc. // For "files" input, add a new node override with the actual input name such as pdfFile, txtFile, etc.
@ -189,6 +191,7 @@ export const upsertVector = async (req: Request, isInternal: boolean = false) =>
overrideConfig: incomingInput?.overrideConfig, overrideConfig: incomingInput?.overrideConfig,
apiOverrideStatus, apiOverrideStatus,
nodeOverrides, nodeOverrides,
availableVariables,
variableOverrides, variableOverrides,
cachePool: appServer.cachePool, cachePool: appServer.cachePool,
isUpsert, isUpsert,

View File

@ -400,7 +400,7 @@ const OverrideConfig = ({ dialogProps }) => {
</Stack> </Stack>
</Card> </Card>
)} )}
{variableOverrides && ( {variableOverrides && variableOverrides.length > 0 && (
<Card sx={{ borderColor: theme.palette.primary[200] + 75, p: 2 }} variant='outlined'> <Card sx={{ borderColor: theme.palette.primary[200] + 75, p: 2 }} variant='outlined'>
<Stack sx={{ mt: 1, mb: 2, ml: 1, alignItems: 'center' }} direction='row' spacing={2}> <Stack sx={{ mt: 1, mb: 2, ml: 1, alignItems: 'center' }} direction='row' spacing={2}>
<IconVariable /> <IconVariable />