diff --git a/packages/components/nodes/agentflow/Iteration/Iteration.ts b/packages/components/nodes/agentflow/Iteration/Iteration.ts index 145602b93e7..fc11b55e994 100644 --- a/packages/components/nodes/agentflow/Iteration/Iteration.ts +++ b/packages/components/nodes/agentflow/Iteration/Iteration.ts @@ -18,7 +18,7 @@ class Iteration_Agentflow implements INode { constructor() { this.label = 'Iteration' this.name = 'iterationAgentflow' - this.version = 1.0 + this.version = 1.1 this.type = 'Iteration' this.category = 'Agent Flows' this.description = 'Execute the nodes within the iteration block through N iterations' @@ -32,6 +32,25 @@ class Iteration_Agentflow implements INode { description: 'The input array to iterate over', acceptVariable: true, rows: 4 + }, + { + label: 'Output Structure', + name: 'iterationOutputStructure', + type: 'options', + description: 'How to structure the output from all iterations', + options: [ + { + label: 'Aggregated Text', + name: 'aggregatedText', + description: 'Join all iteration outputs into a single text separated by newlines' + }, + { + label: 'JSON Array', + name: 'jsonArray', + description: 'Preserve the input array structure — output[i] corresponds to the result of processing input[i]' + } + ], + default: 'aggregatedText' } ] } @@ -56,13 +75,15 @@ class Iteration_Agentflow implements INode { throw new Error('Invalid input array') } + const iterationOutputStructure = nodeData.inputs?.iterationOutputStructure ?? 'aggregatedText' const state = options.agentflowRuntime?.state as ICommonObject const returnOutput = { id: nodeData.id, name: this.name, input: { - iterationInput: iterationInputArray + iterationInput: iterationInputArray, + iterationOutputStructure }, output: {}, state diff --git a/packages/server/src/utils/buildAgentflow.ts b/packages/server/src/utils/buildAgentflow.ts index 5ad744df8ce..069990a4f21 100644 --- a/packages/server/src/utils/buildAgentflow.ts +++ b/packages/server/src/utils/buildAgentflow.ts @@ -1244,6 +1244,7 @@ const executeNode = async ({ } // Initialize array to collect results from iterations + const outputStructure = results.input?.iterationOutputStructure ?? 'aggregatedText' const iterationResults: string[] = [] // Execute sub-flow for each item in the iteration array @@ -1290,9 +1291,12 @@ const executeNode = async ({ productId }) - // Store the result + // Store the result. + // In jsonArray mode, always push to maintain 1:1 mapping with the input array. if (subFlowResult?.text) { iterationResults.push(subFlowResult.text) + } else if (outputStructure === 'jsonArray') { + iterationResults.push('') } // Add executed data from sub-flow to main execution data with appropriate iteration context @@ -1352,7 +1356,7 @@ const executeNode = async ({ results.output = { ...(results.output || {}), iterationResults, - content: iterationResults.join('\n') + content: outputStructure === 'jsonArray' ? JSON.stringify(iterationResults) : iterationResults.join('\n') } logger.debug(` 📊 Completed all iterations. Total results: ${iterationResults.length}`)