diff --git a/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs b/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs
index e1f71e2311..da691e7d48 100644
--- a/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs
+++ b/dotnet/samples/GettingStarted/Workflows/Concurrent/Concurrent/Program.cs
@@ -52,8 +52,8 @@ private static async Task Main()
// 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, "fan-out", targets: [physicist, chemist])
+ .AddFanInEdge(aggregationExecutor, "fan-in", sources: [physicist, chemist])
.WithOutputFrom(aggregationExecutor)
.Build();
diff --git a/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs b/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs
index 9fd4b66e70..c0fa88df75 100644
--- a/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs
+++ b/dotnet/samples/GettingStarted/Workflows/Concurrent/MapReduce/Program.cs
@@ -62,10 +62,10 @@ public static Workflow BuildWorkflow()
// 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, "Splitting", targets: [.. mappers]) // Split -> many mappers
+ .AddFanInEdge(shuffler, "fan-in", sources: [.. mappers]) // All mappers -> shuffle
+ .AddFanOutEdge(shuffler, "Shuffling", targets: [.. reducers]) // Shuffle -> many reducers
+ .AddFanInEdge(completion, "fan-in", sources: [.. reducers]) // All reducers -> completion
.WithOutputFrom(completion)
.Build();
}
diff --git a/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs b/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs
index 6f4cfdf38b..99c14d57c2 100644
--- a/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs
+++ b/dotnet/samples/GettingStarted/Workflows/SharedStates/Program.cs
@@ -26,8 +26,8 @@ private static async Task Main()
// Build the workflow by connecting executors sequentially
var workflow = new WorkflowBuilder(fileRead)
- .AddFanOutEdge(fileRead, targets: [wordCount, paragraphCount])
- .AddFanInEdge(aggregate, sources: [wordCount, paragraphCount])
+ .AddFanOutEdge(fileRead, null, targets: [wordCount, paragraphCount])
+ .AddFanInEdge(aggregate, null, sources: [wordCount, paragraphCount])
.WithOutputFrom(aggregate)
.Build();
diff --git a/dotnet/samples/GettingStarted/Workflows/_Foundational/01_ExecutorsAndEdges/Program.cs b/dotnet/samples/GettingStarted/Workflows/_Foundational/01_ExecutorsAndEdges/Program.cs
index af1dcb50d9..0ba4236db1 100644
--- a/dotnet/samples/GettingStarted/Workflows/_Foundational/01_ExecutorsAndEdges/Program.cs
+++ b/dotnet/samples/GettingStarted/Workflows/_Foundational/01_ExecutorsAndEdges/Program.cs
@@ -27,7 +27,7 @@ private static async Task Main()
// Build the workflow by connecting executors sequentially
WorkflowBuilder builder = new(uppercase);
- builder.AddEdge(uppercase, reverse).WithOutputFrom(reverse);
+ builder.AddEdge(uppercase, reverse, false, "custom label").WithOutputFrom(reverse);
var workflow = builder.Build();
// Execute the workflow with input data
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/DirectEdgeData.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/DirectEdgeData.cs
index 2119bd775b..7d61c939cd 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows/DirectEdgeData.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows/DirectEdgeData.cs
@@ -11,7 +11,7 @@ namespace Microsoft.Agents.AI.Workflows;
///
public sealed class DirectEdgeData : EdgeData
{
- internal DirectEdgeData(string sourceId, string sinkId, EdgeId id, PredicateT? condition = null) : base(id)
+ internal DirectEdgeData(string sourceId, string sinkId, EdgeId id, PredicateT? condition = null, string? label = null) : base(id, label)
{
this.SourceId = sourceId;
this.SinkId = sinkId;
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/EdgeData.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/EdgeData.cs
index 7771b3966e..570bc79bc0 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows/EdgeData.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows/EdgeData.cs
@@ -14,10 +14,16 @@ public abstract class EdgeData
///
internal abstract EdgeConnection Connection { get; }
- internal EdgeData(EdgeId id)
+ internal EdgeData(EdgeId id, string? label = null)
{
this.Id = id;
+ this.Label = label;
}
internal EdgeId Id { get; }
+
+ ///
+ /// An optional label for the edge, allowing for arbitrary metadata to be associated with it.
+ ///
+ public string? Label { get; }
}
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/FanInEdgeData.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/FanInEdgeData.cs
index 0cb2b38378..1132fca334 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows/FanInEdgeData.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows/FanInEdgeData.cs
@@ -10,7 +10,7 @@ namespace Microsoft.Agents.AI.Workflows;
///
internal sealed class FanInEdgeData : EdgeData
{
- internal FanInEdgeData(List sourceIds, string sinkId, EdgeId id) : base(id)
+ internal FanInEdgeData(List sourceIds, string sinkId, EdgeId id, string? label) : base(id, label)
{
this.SourceIds = sourceIds;
this.SinkId = sinkId;
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/FanOutEdgeData.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/FanOutEdgeData.cs
index 9d9ddf4cea..86a940c1b6 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows/FanOutEdgeData.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows/FanOutEdgeData.cs
@@ -13,7 +13,7 @@ namespace Microsoft.Agents.AI.Workflows;
///
internal sealed class FanOutEdgeData : EdgeData
{
- internal FanOutEdgeData(string sourceId, List sinkIds, EdgeId edgeId, AssignerF? assigner = null) : base(edgeId)
+ internal FanOutEdgeData(string sourceId, List sinkIds, EdgeId edgeId, AssignerF? assigner = null, string? label = null) : base(edgeId, label)
{
this.SourceId = sourceId;
this.SinkIds = sinkIds;
diff --git a/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs b/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs
index e180650935..4b6ffae650 100644
--- a/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs
+++ b/dotnet/src/Microsoft.Agents.AI.Workflows/SwitchBuilder.cs
@@ -84,7 +84,7 @@ internal WorkflowBuilder ReduceToFanOut(WorkflowBuilder builder, ExecutorBinding
List<(Func