// Copyright (c) Microsoft Corporation. All rights reserved. // Graph.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace AutoGen.Core; public class Graph { private readonly List transitions = new List(); public Graph() { } public Graph(IEnumerable? transitions) { if (transitions != null) { this.transitions.AddRange(transitions); } } public void AddTransition(Transition transition) { transitions.Add(transition); } /// /// Get the transitions of the workflow. /// public IEnumerable Transitions => transitions; /// /// Get the next available agents that the messages can be transit to. /// /// the from agent /// messages /// A list of agents that the messages can be transit to public async Task> TransitToNextAvailableAgentsAsync(IAgent fromAgent, IEnumerable messages) { var nextAgents = new List(); var availableTransitions = transitions.FindAll(t => t.From == fromAgent) ?? Enumerable.Empty(); foreach (var transition in availableTransitions) { if (await transition.CanTransitionAsync(messages)) { nextAgents.Add(transition.To); } } return nextAgents; } } /// /// Represents a transition between two agents. /// public class Transition { private readonly IAgent _from; private readonly IAgent _to; private readonly Func, Task>? _canTransition; /// /// Create a new instance of . /// This constructor is used for testing purpose only. /// To create a new instance of , use . /// /// from agent /// to agent /// detect if the transition is allowed, default to be always true internal Transition(IAgent from, IAgent to, Func, Task>? canTransitionAsync = null) { _from = from; _to = to; _canTransition = canTransitionAsync; } /// /// Create a new instance of . /// /// " public static Transition Create(TFromAgent from, TToAgent to, Func, Task>? canTransitionAsync = null) where TFromAgent : IAgent where TToAgent : IAgent { return new Transition(from, to, (fromAgent, toAgent, messages) => canTransitionAsync?.Invoke((TFromAgent)fromAgent, (TToAgent)toAgent, messages) ?? Task.FromResult(true)); } public IAgent From => _from; public IAgent To => _to; /// /// Check if the transition is allowed. /// /// messages public Task CanTransitionAsync(IEnumerable messages) { if (_canTransition == null) { return Task.FromResult(true); } return _canTransition(this.From, this.To, messages); } }