From f3f2eabb89155d255ef69f6f6b551c128a0c0cab Mon Sep 17 00:00:00 2001 From: Henry Heng Date: Tue, 21 Oct 2025 15:07:33 +0100 Subject: [PATCH] Fix/variable resolution to support arrays of config objects (#5348) variable resolution to support arrays of config objects - Added handling for arrays of config objects in the resolveVariables function. - Implemented a recursive search for config values to process all matching parameters, improving flexibility in variable resolution. --- packages/server/src/utils/buildAgentflow.ts | 48 +++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/server/src/utils/buildAgentflow.ts b/packages/server/src/utils/buildAgentflow.ts index 241c29c91..98b1c55f2 100644 --- a/packages/server/src/utils/buildAgentflow.ts +++ b/packages/server/src/utils/buildAgentflow.ts @@ -489,6 +489,14 @@ export const resolveVariables = async ( return } + // Handle arrays of config objects + if (Array.isArray(configObj)) { + for (const item of configObj) { + await processConfigParams(item, configParamWithAcceptVariables) + } + return + } + for (const [key, value] of Object.entries(configObj)) { // Only resolve variables for parameters that accept them // Example: requestsGetHeaders is in configParamWithAcceptVariables, so resolve "Bearer {{ $vars.TOKEN }}" @@ -528,12 +536,44 @@ export const resolveVariables = async ( // STEP 5: Look for the config object (paramName + "Config") // Example: Look for "agentSelectedToolConfig" in the inputs const configParamName = paramWithLoadConfig + 'Config' - const configValue = findParamValue(paramsObj, configParamName) - // STEP 6: Process config object to resolve variables + // Find all config values (handle arrays) + const findAllConfigValues = (obj: any, paramName: string): any[] => { + const results: any[] = [] + + if (typeof obj !== 'object' || obj === null) { + return results + } + + // Handle arrays (e.g., agentTools array) + if (Array.isArray(obj)) { + for (const item of obj) { + results.push(...findAllConfigValues(item, paramName)) + } + return results + } + + // Direct property match + if (Object.prototype.hasOwnProperty.call(obj, paramName)) { + results.push(obj[paramName]) + } + + // Recursively search nested objects + for (const value of Object.values(obj)) { + results.push(...findAllConfigValues(value, paramName)) + } + + return results + } + + const configValues = findAllConfigValues(paramsObj, configParamName) + + // STEP 6: Process all config objects to resolve variables // Example: Resolve "Bearer {{ $vars.TOKEN }}" in requestsGetHeaders - if (configValue && configParamWithAcceptVariables.length > 0) { - await processConfigParams(configValue, configParamWithAcceptVariables) + if (configValues.length > 0 && configParamWithAcceptVariables.length > 0) { + for (const configValue of configValues) { + await processConfigParams(configValue, configParamWithAcceptVariables) + } } } }