2023-10-20 23:57:45 +00:00
|
|
|
using BotSharp.Abstraction.Routing.Settings;
|
|
|
|
|
|
2024-02-28 16:21:14 +00:00
|
|
|
namespace BotSharp.Core.Routing;
|
2023-10-02 20:16:35 +00:00
|
|
|
|
2024-02-28 16:21:14 +00:00
|
|
|
public class RoutingContext : IRoutingContext
|
2023-10-02 20:16:35 +00:00
|
|
|
{
|
2024-01-26 04:32:48 +00:00
|
|
|
private readonly IServiceProvider _services;
|
2023-10-20 23:57:45 +00:00
|
|
|
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)
|
2023-10-20 23:57:45 +00:00
|
|
|
{
|
2024-01-26 04:32:48 +00:00
|
|
|
_services = services;
|
2023-10-20 23:57:45 +00:00
|
|
|
_setting = setting;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-28 20:40:59 +00:00
|
|
|
public int AgentCount => _stack.Count;
|
|
|
|
|
public string ConversationId => _conversationId;
|
|
|
|
|
public string MessageId => _messageId;
|
|
|
|
|
|
2023-10-02 20:16:35 +00:00
|
|
|
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>
|
2023-10-02 20:16:35 +00:00
|
|
|
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-02 20:16:35 +00:00
|
|
|
|
2023-10-29 01:54:10 +00:00
|
|
|
public bool IsEmpty => !_stack.Any();
|
2024-02-28 20:40:59 +00:00
|
|
|
|
2023-10-20 23:57:45 +00:00
|
|
|
public string GetCurrentAgentId()
|
|
|
|
|
{
|
2024-02-29 02:45:01 +00:00
|
|
|
if (_stack.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-20 23:57:45 +00:00
|
|
|
return _stack.Peek();
|
|
|
|
|
}
|
2023-10-02 20:16:35 +00:00
|
|
|
|
2024-02-28 20:40:59 +00:00
|
|
|
public void Push(string agentId, string? reason = null)
|
2023-10-02 20:16:35 +00:00
|
|
|
{
|
|
|
|
|
if (_stack.Count == 0 || _stack.Peek() != agentId)
|
|
|
|
|
{
|
2024-02-28 16:21:14 +00:00
|
|
|
var preAgentId = _stack.Count == 0 ? agentId : _stack.Peek();
|
2023-10-02 20:16:35 +00:00
|
|
|
_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();
|
2023-10-02 20:16:35 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pop current agent
|
|
|
|
|
/// </summary>
|
2024-02-28 20:40:59 +00:00
|
|
|
public void Pop(string? reason = null)
|
2023-10-02 20:16:35 +00:00
|
|
|
{
|
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
|
|
|
}
|
2023-10-02 20:16:35 +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-01-26 22:23:10 +00:00
|
|
|
{
|
2024-02-28 16:21:14 +00:00
|
|
|
var fromAgent = agentId;
|
|
|
|
|
var toAgent = agentId;
|
|
|
|
|
|
2024-01-26 22:23:10 +00:00
|
|
|
if (_stack.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
_stack.Push(agentId);
|
|
|
|
|
}
|
|
|
|
|
else if (_stack.Peek() != agentId)
|
|
|
|
|
{
|
2024-02-28 16:21:14 +00:00
|
|
|
fromAgent = _stack.Peek();
|
2024-01-26 22:23:10 +00:00
|
|
|
_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-01-26 22:23:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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();
|
2023-10-02 20:16:35 +00:00
|
|
|
}
|
2024-02-28 20:40:59 +00:00
|
|
|
|
|
|
|
|
public void SetMessageId(string conversationId, string messageId)
|
|
|
|
|
{
|
|
|
|
|
_conversationId = conversationId;
|
|
|
|
|
_messageId = messageId;
|
|
|
|
|
}
|
2023-10-02 20:16:35 +00:00
|
|
|
}
|