MCPcopy Index your code
hub / github.com/FlowiseAI/Flowise / resolveVariables

Function resolveVariables

packages/server/src/utils/buildAgentflow.ts:241–640  ·  view source on GitHub ↗
(
    reactFlowNodeData: INodeData,
    question: string,
    form: Record<string, any>,
    flowConfig: IFlowConfig | undefined,
    availableVariables: Variable[],
    variableOverrides: IVariableOverride[],
    uploadedFilesContent: string,
    chatHistory: IMessage[],
    componentNodes: IComponentNodes,
    agentFlowExecutedData?: IAgentflowExecutedData[],
    iterationContext?: ICommonObject,
    loopCounts?: Map<string, number>,
    webhook?: Record<string, any>
)

Source from the content-addressed store, hash-verified

239}
240
241export const resolveVariables = async (
242 reactFlowNodeData: INodeData,
243 question: string,
244 form: Record<string, any>,
245 flowConfig: IFlowConfig | undefined,
246 availableVariables: Variable[],
247 variableOverrides: IVariableOverride[],
248 uploadedFilesContent: string,
249 chatHistory: IMessage[],
250 componentNodes: IComponentNodes,
251 agentFlowExecutedData?: IAgentflowExecutedData[],
252 iterationContext?: ICommonObject,
253 loopCounts?: Map<string, number>,
254 webhook?: Record<string, any>
255): Promise<INodeData> => {
256 let flowNodeData = cloneDeep(reactFlowNodeData)
257 const types = 'inputs'
258
259 const resolveNodeReference = async (value: any): Promise<any> => {
260 // If value is an array, process each element
261 if (Array.isArray(value)) {
262 return Promise.all(value.map((item) => resolveNodeReference(item)))
263 }
264
265 // If value is an object, process each property
266 if (typeof value === 'object' && value !== null) {
267 const resolvedObj: any = {}
268 for (const [key, val] of Object.entries(value)) {
269 resolvedObj[key] = await resolveNodeReference(val)
270 }
271 return resolvedObj
272 }
273
274 // If value is not a string, return as is
275 if (typeof value !== 'string') return value
276
277 // Convert legacy HTML content to markdown, preserving any markdown syntax within.
278 // Legacy content from old getHTML() starts with a TipTap block tag (e.g. <p>text</p>).
279 // Anchor with ^ to avoid matching intentional HTML/XML tags in user prompts
280 // (e.g. <instruction><div>...</div></instruction>).
281 if (/^\s*<(?:p|div|h[1-6]|ul|ol|blockquote|pre|table)\b/i.test(value)) {
282 const turndownService = new TurndownService()
283 // Disable escaping so markdown characters (e.g. ###, -, *) inside HTML are preserved as-is
284 turndownService.escape = (str: string) => str
285 value = turndownService.turndown(value)
286 }
287
288 const matches = value.match(/{{(.*?)}}/g)
289
290 if (!matches) return value
291
292 let resolvedValue = value
293 for (const match of matches) {
294 // Remove {{ }} and trim whitespace
295 const reference = match.replace(/[{}]/g, '').trim()
296 const variableFullPath = reference
297
298 if (variableFullPath === QUESTION_VAR_PREFIX) {

Callers 1

executeNodeFunction · 0.70

Calls 1

getParamValuesFunction · 0.70

Tested by

no test coverage detected