fix(core): Route split in batches chains through loop output (#32968)

This commit is contained in:
Albert Alises 2026-06-25 13:09:41 +02:00 committed by GitHub
parent 7b4a10fc70
commit 7830ceccf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 2 deletions

View File

@ -681,6 +681,36 @@ describe('New SDK API', () => {
// Process Item loops back to Split In Batches via nextBatch()
expect(json.connections['Process Item'].main[0]![0].node).toBe('Process Batches');
});
it('chains nodes after a bare splitInBatches builder from the loop output', () => {
const t = createTrigger('Start');
const defineScenarios = createNode('Define Scenarios');
const loop = splitInBatches({
version: 3,
config: {
name: 'Loop Each Item',
parameters: { batchSize: 1, options: {} },
},
});
const generatePrompt = createNode('Generate Prompt');
const extractPrompt = createNode('Extract Prompt');
const logResult = createNode('Log Result');
const wf = workflow('test', 'Agentic AI Image Generator')
.add(t)
.to(defineScenarios)
.to(loop)
.to(generatePrompt)
.to(extractPrompt)
.to(logResult)
.to(nextBatch(loop));
const json = wf.toJSON();
expect(json.connections['Loop Each Item'].main[0] ?? []).toEqual([]);
expect(json.connections['Loop Each Item'].main[1]![0].node).toBe('Generate Prompt');
expect(json.connections['Log Result'].main[0]![0].node).toBe('Loop Each Item');
});
});
describe('API Integration: Complete Workflow Examples', () => {

View File

@ -345,8 +345,9 @@ class WorkflowBuilderImpl implements WorkflowBuilder {
}
}
this._currentNode = headName;
this._currentOutput = 0;
const continuation = thenHandler.handleThen?.(nodeOrComposite, headName, 0, ctx);
this._currentNode = continuation?.currentNode ?? headName;
this._currentOutput = continuation?.currentOutput ?? 0;
return this;
}

View File

@ -130,8 +130,30 @@ export const splitInBatchesHandler: CompositeHandlerPlugin<SplitInBatchesBuilder
processingSibBuilders.delete(input);
}
},
handleThen(
input: SplitInBatchesBuilderShape,
currentNode: string,
): {
currentNode: string;
currentOutput: number;
} {
return {
currentNode,
currentOutput: hasConfiguredTargets(input) ? 0 : 1,
};
},
};
function hasConfiguredTargets(input: SplitInBatchesBuilderShape): boolean {
return (
'_doneTarget' in input ||
'_eachTarget' in input ||
(input._doneBatches !== undefined && input._doneBatches.length > 0) ||
(input._eachBatches !== undefined && input._eachBatches.length > 0)
);
}
/**
* Process named syntax: splitInBatches(sibNode, { done: ..., each: ... })
*/