BotSharp/src/Infrastructure/BotSharp.Core/Routing/RoutingContext.cs

150 lines
3.7 KiB
C#
Raw Normal View History

using BotSharp.Abstraction.Routing.Settings;
2024-02-28 16:21:14 +00:00
namespace BotSharp.Core.Routing;
2024-02-28 16:21:14 +00:00
public class RoutingContext : IRoutingContext
{
2024-01-26 04:32:48 +00:00
private readonly IServiceProvider _services;
private readonly RoutingSettings _setting;
2024-01-26 04:32:48 +00:00
private string[] _routerAgentIds;
2024-02-28 20:40:59 +00:00
private string _conversationId;
private string _messageId;
2024-01-26 04:32:48 +00:00
public RoutingContext(IServiceProvider services, RoutingSettings setting)
{
2024-01-26 04:32:48 +00:00
_services = services;
_setting = setting;
}
2024-02-28 20:40:59 +00:00
public int AgentCount => _stack.Count;
public string ConversationId => _conversationId;
public string MessageId => _messageId;
private Stack<string> _stack { get; set; }
= new Stack<string>();
/// <summary>
/// Intent name
/// </summary>
public string IntentName { get; set; }
2023-10-27 01:23:06 +00:00
/// <summary>
2024-01-13 21:17:40 +00:00
/// Agent that can handle user original goal.
2023-10-27 01:23:06 +00:00
/// </summary>
public string OriginAgentId
2024-01-26 04:32:48 +00:00
{
get
{
if (_routerAgentIds == null)
{
var agentService = _services.GetRequiredService<IAgentService>();
_routerAgentIds = agentService.GetAgents(new AgentFilter
{
Type = AgentType.Routing
}).Result.Items
.Select(x => x.Id).ToArray();
}
return _stack.Where(x => !_routerAgentIds.Contains(x)).Last();
}
}
2023-10-29 01:54:10 +00:00
public bool IsEmpty => !_stack.Any();
2024-02-28 20:40:59 +00:00
public string GetCurrentAgentId()
{
2024-02-29 02:45:01 +00:00
if (_stack.Count == 0)
{
return string.Empty;
}
return _stack.Peek();
}
2024-02-28 20:40:59 +00:00
public void Push(string agentId, string? reason = null)
{
if (_stack.Count == 0 || _stack.Peek() != agentId)
{
2024-02-28 16:21:14 +00:00
var preAgentId = _stack.Count == 0 ? agentId : _stack.Peek();
_stack.Push(agentId);
2024-02-28 16:21:14 +00:00
HookEmitter.Emit<IRoutingHook>(_services, async hook =>
2024-02-28 20:40:59 +00:00
await hook.OnAgentEnqueued(agentId, preAgentId, reason: reason)
2024-02-28 16:21:14 +00:00
).Wait();
}
}
/// <summary>
/// Pop current agent
/// </summary>
2024-02-28 20:40:59 +00:00
public void Pop(string? reason = null)
{
2024-02-28 16:21:14 +00:00
if (_stack.Count == 0)
{
return;
}
var agentId = _stack.Pop();
2024-02-29 02:41:21 +00:00
var currentAgentId = GetCurrentAgentId();
2024-02-28 16:21:14 +00:00
HookEmitter.Emit<IRoutingHook>(_services, async hook =>
2024-02-29 02:41:21 +00:00
await hook.OnAgentDequeued(agentId, currentAgentId, reason: reason)
2024-02-28 16:21:14 +00:00
).Wait();
2023-10-29 01:54:10 +00:00
}
2024-02-28 20:40:59 +00:00
public string PreviousAgentId()
{
if (_stack.Count == 1)
{
return GetCurrentAgentId();
}
else if (_stack.Count > 1)
{
return _stack.ToArray()[1];
}
return string.Empty;
}
public void Replace(string agentId, string? reason = null)
{
2024-02-28 16:21:14 +00:00
var fromAgent = agentId;
var toAgent = agentId;
if (_stack.Count == 0)
{
_stack.Push(agentId);
}
else if (_stack.Peek() != agentId)
{
2024-02-28 16:21:14 +00:00
fromAgent = _stack.Peek();
_stack.Pop();
_stack.Push(agentId);
2024-02-28 16:21:14 +00:00
HookEmitter.Emit<IRoutingHook>(_services, async hook =>
2024-02-28 20:40:59 +00:00
await hook.OnAgentReplaced(fromAgent, toAgent, reason: reason)
2024-02-28 16:21:14 +00:00
).Wait();
}
}
2024-02-28 20:40:59 +00:00
public void Empty(string? reason = null)
2023-10-29 01:54:10 +00:00
{
2024-02-28 16:21:14 +00:00
if (_stack.Count == 0)
{
return;
}
var agentId = GetCurrentAgentId();
2023-10-29 01:54:10 +00:00
_stack.Clear();
2024-02-28 16:21:14 +00:00
HookEmitter.Emit<IRoutingHook>(_services, async hook =>
2024-02-28 20:40:59 +00:00
await hook.OnAgentQueueEmptied(agentId, reason: reason)
2024-02-28 16:21:14 +00:00
).Wait();
}
2024-02-28 20:40:59 +00:00
public void SetMessageId(string conversationId, string messageId)
{
_conversationId = conversationId;
_messageId = messageId;
}
}