.NET: [BREAKING] refactor: Normalize WorkflowBuilder APIs (#1935)

* [BREAKING] refactor: Normalize WorkflowBuilder APIs

* "partitioner" => "assigner"
* normalize ordering so sources always to the left of targets for edges
* normalize parameter ordering so sources and targets are always first arguments
* remove `params` (users should use collection expressions instead)

* refactor: Align name with Python
This commit is contained in:
Jacob Alber
2025-11-05 14:50:01 -05:00
committed by GitHub
Unverified
parent 33f84f9ed2
commit 94a5ba3448
12 changed files with 96 additions and 67 deletions
@@ -23,8 +23,8 @@ internal static class WorkflowFactory
// Build the workflow by adding executors and connecting them
return new WorkflowBuilder(startExecutor)
.AddFanOutEdge(startExecutor, targets: [frenchAgent, englishAgent])
.AddFanInEdge(aggregationExecutor, sources: [frenchAgent, englishAgent])
.AddFanOutEdge(startExecutor, [frenchAgent, englishAgent])
.AddFanInEdge([frenchAgent, englishAgent], aggregationExecutor)
.WithOutputFrom(aggregationExecutor)
.Build();
}
@@ -52,8 +52,8 @@ public static class Program
// Build the workflow by adding executors and connecting them
var workflow = new WorkflowBuilder(startExecutor)
.AddFanOutEdge(startExecutor, targets: [physicist, chemist])
.AddFanInEdge(aggregationExecutor, sources: [physicist, chemist])
.AddFanOutEdge(startExecutor, [physicist, chemist])
.AddFanInEdge([physicist, chemist], aggregationExecutor)
.WithOutputFrom(aggregationExecutor)
.Build();
@@ -62,10 +62,10 @@ public static class Program
// Step 4: Build the concurrent workflow with fan-out/fan-in pattern
return new WorkflowBuilder(splitter)
.AddFanOutEdge(splitter, targets: [.. mappers]) // Split -> many mappers
.AddFanInEdge(shuffler, sources: [.. mappers]) // All mappers -> shuffle
.AddFanOutEdge(shuffler, targets: [.. reducers]) // Shuffle -> many reducers
.AddFanInEdge(completion, sources: [.. reducers]) // All reducers -> completion
.AddFanOutEdge(splitter, [.. mappers]) // Split -> many mappers
.AddFanInEdge([.. mappers], shuffler) // All mappers -> shuffle
.AddFanOutEdge(shuffler, [.. reducers]) // Shuffle -> many reducers
.AddFanInEdge([.. reducers], completion) // All reducers -> completion
.WithOutputFrom(completion)
.Build();
}
@@ -60,13 +60,13 @@ public static class Program
WorkflowBuilder builder = new(emailAnalysisExecutor);
builder.AddFanOutEdge(
emailAnalysisExecutor,
targets: [
[
handleSpamExecutor,
emailAssistantExecutor,
emailSummaryExecutor,
handleUncertainExecutor,
],
partitioner: GetPartitioner()
GetTargetAssigner()
)
// After the email assistant writes a response, it will be sent to the send email executor
.AddEdge(emailAssistantExecutor, sendEmailExecutor)
@@ -105,7 +105,7 @@ public static class Program
/// Creates a partitioner for routing messages based on the analysis result.
/// </summary>
/// <returns>A function that takes an analysis result and returns the target partitions.</returns>
private static Func<AnalysisResult?, int, IEnumerable<int>> GetPartitioner()
private static Func<AnalysisResult?, int, IEnumerable<int>> GetTargetAssigner()
{
return (analysisResult, targetCount) =>
{
@@ -24,8 +24,8 @@ internal static class WorkflowHelper
// Build the workflow by adding executors and connecting them
return new WorkflowBuilder(startExecutor)
.AddFanOutEdge(startExecutor, targets: [frenchAgent, englishAgent])
.AddFanInEdge(aggregationExecutor, sources: [frenchAgent, englishAgent])
.AddFanOutEdge(startExecutor, [frenchAgent, englishAgent])
.AddFanInEdge([frenchAgent, englishAgent], aggregationExecutor)
.WithOutputFrom(aggregationExecutor)
.Build();
}
@@ -26,8 +26,8 @@ public static class Program
// Build the workflow by connecting executors sequentially
var workflow = new WorkflowBuilder(fileRead)
.AddFanOutEdge(fileRead, targets: [wordCount, paragraphCount])
.AddFanInEdge(aggregate, sources: [wordCount, paragraphCount])
.AddFanOutEdge(fileRead, [wordCount, paragraphCount])
.AddFanInEdge([wordCount, paragraphCount], aggregate)
.WithOutputFrom(aggregate)
.Build();