// 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); } } } }