// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.Workflows;
using Microsoft.Agents.AI.Workflows.Checkpointing;
namespace Microsoft.Agents.AI.DurableTask;
///
/// Represents an executor in the workflow with its metadata.
///
/// The unique identifier of the executor.
/// Indicates whether this executor is an agentic executor.
/// The request port if this executor is a request port executor; otherwise, null.
public sealed record WorkflowExecutorInfo(string ExecutorId, bool IsAgenticExecutor, RequestPort? RequestPort = null)
{
///
/// Gets a value indicating whether this executor is a request port executor (human-in-the-loop).
///
public bool IsRequestPortExecutor => this.RequestPort is not null;
}
///
/// Represents a level of executors that can be executed in parallel (Fan-Out).
/// All executors in the same level have their dependencies satisfied by previous levels.
///
/// The level number (0-based, starting from the root executor).
/// The executors that can run in parallel at this level.
/// Indicates if this level is a Fan-In point (has executors with multiple predecessors).
public sealed record WorkflowExecutionLevel(int Level, List Executors, bool IsFanIn);
///
/// Provides helper methods for analyzing and executing workflows.
///
public static class WorkflowHelper
{
///
/// Accepts a workflow instance and returns a list of executors with metadata in the order they should be executed.
///
/// The workflow instance to analyze.
/// A list of executor information in topological order (execution order).
public static List GetExecutorsFromWorkflowInOrder(Workflow workflow)
{
WorkflowExecutionPlan plan = GetExecutionPlan(workflow);
// Flatten the levels into a single list for backward compatibility
List result = [];
foreach (WorkflowExecutionLevel level in plan.Levels)
{
result.AddRange(level.Executors);
}
return result;
}
///
/// Analyzes the workflow and returns an execution plan that supports Fan-Out/Fan-In patterns.
/// Executors at the same level can be executed in parallel (Fan-Out).
/// Fan-In points are identified where multiple executors converge.
///
/// The workflow instance to analyze.
/// An execution plan with parallel execution levels.
public static WorkflowExecutionPlan GetExecutionPlan(Workflow workflow)
{
ArgumentNullException.ThrowIfNull(workflow);
Dictionary executors = workflow.ReflectExecutors();
Dictionary> edges = workflow.ReflectEdges();
Dictionary<(string SourceId, string TargetId), Func