// Copyright (c) Microsoft. All rights reserved. using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Agents.AI.Workflows.Specialized; using Microsoft.Shared.Diagnostics; namespace Microsoft.Agents.AI.Workflows; /// /// Provides a builder for specifying group chat relationships between agents and building the resulting workflow. /// public sealed class GroupChatWorkflowBuilder { private readonly Func, GroupChatManager> _managerFactory; private readonly HashSet _participants = new(AIAgentIDEqualityComparer.Instance); private string _name = string.Empty; private string _description = string.Empty; internal GroupChatWorkflowBuilder(Func, GroupChatManager> managerFactory) => this._managerFactory = managerFactory; /// /// Adds the specified as participants to the group chat workflow. /// /// The agents to add as participants. /// This instance of the . public GroupChatWorkflowBuilder AddParticipants(params IEnumerable agents) { Throw.IfNull(agents); foreach (var agent in agents) { if (agent is null) { Throw.ArgumentNullException(nameof(agents), "One or more target agents are null."); } this._participants.Add(agent); } return this; } /// /// Sets the human-readable name for the workflow. /// /// The name of the workflow. /// This instance of the . public GroupChatWorkflowBuilder WithName(string name) { this._name = name; return this; } /// /// Sets the description for the workflow. /// /// The description of what the workflow does. /// This instance of the . public GroupChatWorkflowBuilder WithDescription(string description) { this._description = description; return this; } /// /// Builds a composed of agents that operate via group chat, with the next /// agent to process messages selected by the group chat manager. /// /// The workflow built based on the group chat in the builder. public Workflow Build() { AIAgent[] agents = this._participants.ToArray(); AIAgentHostOptions options = new() { ReassignOtherAgentsAsUsers = true, ForwardIncomingMessages = true }; Dictionary agentMap = agents.ToDictionary(a => a, a => a.BindAsExecutor(options)); Func> groupChatHostFactory = (id, sessionId) => new(new GroupChatHost(id, agents, agentMap, this._managerFactory)); ExecutorBinding host = groupChatHostFactory.BindExecutor(nameof(GroupChatHost)); WorkflowBuilder builder = new(host); if (!string.IsNullOrEmpty(this._name)) { builder = builder.WithName(this._name); } if (!string.IsNullOrEmpty(this._description)) { builder = builder.WithDescription(this._description); } foreach (var participant in agentMap.Values) { builder .AddEdge(host, participant) .AddEdge(participant, host); } return builder.WithOutputFrom(host).Build(); } }