// Copyright (c) Microsoft. All rights reserved.
using System.Diagnostics;
using Microsoft.Agents.AI.Workflows;
namespace Microsoft.Agents.AI.DurableTask;
///
/// Provides configuration options for managing durable workflows within an application.
///
[DebuggerDisplay("Workflows = {Workflows.Count}")]
public sealed class DurableWorkflowOptions
{
private readonly Dictionary _workflows = new(StringComparer.OrdinalIgnoreCase);
private readonly DurableOptions? _parentOptions;
///
/// Initializes a new instance of the class.
///
/// Optional parent options container for accessing related configuration.
internal DurableWorkflowOptions(DurableOptions? parentOptions = null)
{
this._parentOptions = parentOptions;
this.Executors = new ExecutorRegistry();
}
///
/// Gets the collection of workflows available in the current context, keyed by their unique names.
///
public IReadOnlyDictionary Workflows => this._workflows;
///
/// Gets the executor registry for direct executor lookup.
///
internal ExecutorRegistry Executors { get; }
///
/// Adds a workflow to the collection for processing or execution.
///
/// The workflow instance to add. Cannot be null.
///
/// When a workflow is added, any AI agent executors in the workflow will be automatically
/// registered with the if it was provided during construction.
///
/// Thrown when is null.
/// Thrown when the workflow does not have a valid name.
public void AddWorkflow(Workflow workflow)
{
ArgumentNullException.ThrowIfNull(workflow);
if (string.IsNullOrEmpty(workflow.Name))
{
throw new ArgumentException("Workflow must have a valid Name property.", nameof(workflow));
}
this._workflows[workflow.Name] = workflow;
RegisterExecutors(workflow, this.Executors);
DurableAgentsOptions? agentOptions = this._parentOptions?.Agents;
if (agentOptions is not null)
{
RegisterAgenticExecutors(workflow, agentOptions);
}
}
///
/// Adds a collection of workflows to the current instance.
///
/// The collection of objects to add. Cannot be .
public void AddWorkflows(IEnumerable workflows)
{
ArgumentNullException.ThrowIfNull(workflows);
foreach (var workflow in workflows)
{
this.AddWorkflow(workflow);
}
}
private static void RegisterExecutors(Workflow workflow, ExecutorRegistry registry)
{
foreach (KeyValuePair executor in workflow.ReflectExecutors())
{
int underscoreIndex = executor.Key.IndexOf('_');
string executorName = underscoreIndex > 0 ? executor.Key[..underscoreIndex] : executor.Key;
registry.Register(executorName, executor.Key, workflow);
}
}
private static void RegisterAgenticExecutors(Workflow workflow, DurableAgentsOptions agentOptions)
{
foreach (KeyValuePair executor in workflow.ReflectExecutors())
{
if (executor.Value.RawValue is AIAgent agent && agent.Name is not null && !agentOptions.ContainsAgent(agent.Name))
{
agentOptions.AddAIAgent(agent, workflowOnly: true);
}
}
}
}