Skip to content

.NET: No API support for labels in Edges (for workflow visualizations) #1499

@joslat

Description

@joslat

Summary

The WorkflowBuilder API lacks support for adding labels or annotations to workflow edges. This makes it impossible to document edge purpose, data flow, or business logic directly in workflow visualizations.

Edge labels are essential for:
• Self-documenting workflows - Understanding workflow logic without examining code
• Conditional edge clarity - Explaining what conditions mean (e.g., "High Quality" vs "Low Quality")
• Data flow documentation - Showing what data flows between executors
• Stakeholder communication - Making diagrams understandable to non-technical audiences

Both Mermaid and DOT/Graphviz formats support labeled edges, but there's no way to specify labels in the workflow builder API.


Current Behavior

There is no way to add labels to edges when building workflows:

// ❌ No label parameter available
var workflow = new WorkflowBuilder(startExecutor)
    .AddEdge(source, target, 
        condition: result => result.IsValid,
        label: "Validation Passed")  // ❌ Not supported - compile error
    .Build();

// ❌ No fluent API for adding labels
var workflow = new WorkflowBuilder(startExecutor)
    .AddEdge(source, target)
        .WithLabel("Processes approved requests")  // ❌ Not supported
    .Build();

// ❌ No metadata or annotation support
var workflow = new WorkflowBuilder(startExecutor)
    .AddEdge(source, target, 
        metadata: new { Label = "Success path" })  // ❌ Not supported
    .Build();

Current AddEdge signatures (all lack label support):

// Regular edge
WorkflowBuilder AddEdge(Executor source, Executor target)

// Conditional edge
WorkflowBuilder AddEdge(Executor source, Executor target, Func<object?, bool> condition)

// Fan-out edge
WorkflowBuilder AddFanOutEdge(Executor source, params Executor[] targets)

// Fan-in edge
WorkflowBuilder AddFanInEdge(Executor target, params Executor[] sources)

Impact:
• Cannot document edge purpose inline
• Conditional edges all look identical (e.g., "High Quality" vs "Low Quality" are indistinguishable)
• Must rely on external documentation or code comments
• Visualizations lack context for business logic
• Difficult to explain workflows to non-technical stakeholders


Expected Behavior

Provide API support for adding labels to edges and have them also appear in both Mermaid and DOT visualizations:

// Option A: Label parameter (simplest approach)
var workflow = new WorkflowBuilder(qualityCheckExecutor)
    .AddEdge(qualityCheckExecutor, approvalExecutor, 
        condition: result => result.IsHighQuality == true,
        label: "High Quality")  // ✅ Label appears in visualization
    .AddEdge(qualityCheckExecutor, rejectionExecutor, 
        condition: result => result.IsHighQuality == false,
        label: "Low Quality")   // ✅ Label appears in visualization
    .AddEdge(approvalExecutor, notificationExecutor,
        label: "Success notification")  // ✅ Works for non-conditional edges too
    .Build();

// Option B: Fluent API (more expressive)
var workflow = new WorkflowBuilder(qualityCheckExecutor)
    .AddEdge(qualityCheckExecutor, approvalExecutor)
        .WithCondition(result => result.IsHighQuality)
        .WithLabel("High Quality Response")
    .AddEdge(qualityCheckExecutor, rejectionExecutor)
        .WithCondition(result => !result.IsHighQuality)
        .WithLabel("Needs Improvement")
    .Build();

// Option C: Edge configuration action
var workflow = new WorkflowBuilder(qualityCheckExecutor)
    .AddEdge(qualityCheckExecutor, approvalExecutor, edge => edge
        .WithCondition(result => result.IsHighQuality)
        .WithLabel("High Quality")
        .WithDescription("Response meets all quality standards"))  // Optional extended metadata
    .Build();

Expected Mermaid Output:

flowchart TD
    QualityCheck["Quality Check Executor"];
    Approval["Approval Executor"];
    Rejection["Rejection Executor"];
    Notify["Notification Executor"];
    
    QualityCheck -->|"High Quality"| Approval;
    QualityCheck -->|"Low Quality"| Rejection;
    Approval -->|"Success notification"| Notify;

Expected DOT Output:

digraph workflow {
    QualityCheck -> Approval [label="High Quality"];
    QualityCheck -> Rejection [label="Low Quality"];
    Approval -> Notify [label="Success notification"];
}

Example of a rendered workflow:
Image
Much clearer, right? ;)

Benefits:

  1. Self-documenting workflows - Purpose is clear from the diagram
  2. Better conditional clarity - Each condition has a meaningful label
  3. Data flow visibility - Can document what data flows along edges
  4. Professional diagrams - Ready to share with stakeholders
  5. Consistency - Both Mermaid and DOT support labels

Use Cases

Use Case 1: Conditional Workflow (Quality Check)

var workflow = new WorkflowBuilder(qualityCheck)
    .AddEdge(qualityCheck, approval, 
        condition: r => r.Score >= 90,
        label: "Score ≥ 90 (Excellent)")
    .AddEdge(qualityCheck, review, 
        condition: r => r.Score >= 70 && r.Score < 90,
        label: "Score 70-89 (Good)")
    .AddEdge(qualityCheck, rejection, 
        condition: r => r.Score < 70,
        label: "Score < 70 (Poor)")
    .Build();

Benefit: Instantly understand the scoring thresholds from the diagram

Use Case 2: Data Transformation Pipeline

var workflow = new WorkflowBuilder(inputParser)
    .AddEdge(inputParser, validator, label: "Raw JSON")
    .AddEdge(validator, transformer, label: "Validated data")
    .AddEdge(transformer, enricher, label: "Normalized schema")
    .AddEdge(enricher, output, label: "Enriched with metadata")
    .Build();

Benefit: Understand data transformations at each stage

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions