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