// Copyright (c) Microsoft. All rights reserved. using Microsoft.Agents.AI.Workflows; namespace WorkflowExecutorsAndEdgesSample; /// /// This sample introduces the concepts of executors and edges in a workflow. /// /// Workflows are built from executors (processing units) connected by edges (data flow paths). /// In this example, we create a simple text processing pipeline that: /// 1. Takes input text and converts it to uppercase using an UppercaseExecutor /// 2. Takes the uppercase text and reverses it using a ReverseTextExecutor /// /// The executors are connected sequentially, so data flows from one to the next in order. /// For input "Hello, World!", the workflow produces "!DLROW ,OLLEH". /// public static class Program { private static async Task Main() { // Create the executors Func uppercaseFunc = s => s.ToUpperInvariant(); var uppercase = uppercaseFunc.BindAsExecutor("UppercaseExecutor"); ReverseTextExecutor reverse = new(); // Build the workflow by connecting executors sequentially WorkflowBuilder builder = new(uppercase); builder.AddEdge(uppercase, reverse).WithOutputFrom(reverse); var workflow = builder.Build(); // Execute the workflow with input data await using Run run = await InProcessExecution.RunAsync(workflow, "Hello, World!"); foreach (WorkflowEvent evt in run.NewEvents) { if (evt is ExecutorCompletedEvent executorComplete) { Console.WriteLine($"{executorComplete.ExecutorId}: {executorComplete.Data}"); } } } } /// /// Second executor: reverses the input text and completes the workflow. /// internal sealed class ReverseTextExecutor() : Executor("ReverseTextExecutor") { /// /// Processes the input message by reversing the text. /// /// The input text to reverse /// Workflow context for accessing workflow services and adding events /// The to monitor for cancellation requests. /// The default is . /// The input text reversed public override ValueTask HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default) { // Because we do not suppress it, the returned result will be yielded as an output from this executor. return ValueTask.FromResult(string.Concat(message.Reverse())); } }