// Copyright (c) Microsoft. All rights reserved.
using System.Diagnostics;
using Microsoft.Agents.AI.Workflows;
namespace Microsoft.Agents.AI.DurableTask.Workflows;
///
/// 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);
///
/// Initializes a new instance of the class.
///
/// Optional parent options container for accessing related configuration.
internal DurableWorkflowOptions(DurableOptions? parentOptions = null)
{
this.ParentOptions = parentOptions;
}
///
/// Gets the parent container, if available.
///
internal DurableOptions? ParentOptions { get; }
///
/// 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; } = new();
///
/// Adds a workflow to the collection for processing or execution.
///
/// The workflow instance to add. Cannot be null.
///
/// When a workflow is added, all executors are registered in the executor registry.
/// Any AI agent executors will also be automatically registered with the
/// if available.
///
/// 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;
this.RegisterWorkflowExecutors(workflow);
}
///
/// Adds a collection of workflows to the current instance.
///
/// The collection of objects to add.
/// Thrown when is null.
public void AddWorkflows(params Workflow[] workflows)
{
ArgumentNullException.ThrowIfNull(workflows);
foreach (Workflow workflow in workflows)
{
this.AddWorkflow(workflow);
}
}
///
/// Registers all executors from a workflow, including AI agents if agent options are available.
///
private void RegisterWorkflowExecutors(Workflow workflow)
{
DurableAgentsOptions? agentOptions = this.ParentOptions?.Agents;
foreach ((string executorId, ExecutorBinding binding) in workflow.ReflectExecutors())
{
string executorName = WorkflowNamingHelper.GetExecutorName(executorId);
this.Executors.Register(executorName, executorId, workflow);
TryRegisterAgent(binding, agentOptions);
}
}
///
/// Registers an AI agent with the agent options if the binding contains an unregistered agent.
///
private static void TryRegisterAgent(ExecutorBinding binding, DurableAgentsOptions? agentOptions)
{
if (agentOptions is null)
{
return;
}
if (binding.RawValue is AIAgent { Name: not null } agent
&& !agentOptions.ContainsAgent(agent.Name))
{
agentOptions.AddAIAgent(agent);
}
}
}