Eliminate route file configuration.
This commit is contained in:
parent
d46fc73ce7
commit
a13ef3007b
|
|
@ -6,7 +6,5 @@ public interface IAgentRouting
|
|||
{
|
||||
string AgentId { get; }
|
||||
Task<Agent> LoadRouter();
|
||||
RoutingItem[] GetRoutingRecords();
|
||||
RoutingItem GetRecordByAgentId(string id);
|
||||
RoutingItem GetRecordByName(string name);
|
||||
RoutingRule[] GetRulesByName(string name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System.Text.Json.Serialization;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
|
|
@ -48,6 +48,22 @@ public class Agent
|
|||
|
||||
public bool IsPublic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow to be routed
|
||||
/// </summary>
|
||||
public bool AllowRouting { get; set; }
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile by channel
|
||||
/// </summary>
|
||||
public List<string> Profiles { get; set; }
|
||||
= new List<string>();
|
||||
|
||||
public List<RoutingRule> RoutingRules { get; set; }
|
||||
= new List<RoutingRule>();
|
||||
|
||||
public override string ToString()
|
||||
=> $"{Name} {Id}";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Repositories;
|
||||
|
|
@ -10,8 +8,6 @@ public interface IBotSharpRepository
|
|||
IQueryable<Agent> Agents { get; }
|
||||
IQueryable<UserAgent> UserAgents { get; }
|
||||
IQueryable<Conversation> Conversations { get; }
|
||||
IQueryable<RoutingItem> RoutingItems { get; }
|
||||
IQueryable<RoutingProfile> RoutingProfiles { get; }
|
||||
|
||||
int Transaction<TTableInterface>(Action action);
|
||||
void Add<TTableInterface>(object entity);
|
||||
|
|
@ -37,11 +33,4 @@ public interface IBotSharpRepository
|
|||
Conversation GetConversation(string conversationId);
|
||||
List<Conversation> GetConversations(string userId);
|
||||
#endregion
|
||||
|
||||
#region Routing
|
||||
List<RoutingItem> CreateRoutingItems(List<RoutingItem> routingItems);
|
||||
List<RoutingProfile> CreateRoutingProfiles(List<RoutingProfile> profiles);
|
||||
void DeleteRoutingItems();
|
||||
void DeleteRoutingProfiles();
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing;
|
||||
|
||||
public interface IRoutingService
|
||||
{
|
||||
Task<List<RoutingItem>> CreateRoutingItems(List<RoutingItem> routingItems);
|
||||
Task<List<RoutingProfile>> CreateRoutingProfiles(List<RoutingProfile> routingProfiles);
|
||||
Task DeleteRoutingItems();
|
||||
Task DeleteRoutingProfiles();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
public class RoutingItem
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("agent_id")]
|
||||
public string AgentId { get; set; } = string.Empty;
|
||||
|
||||
|
|
@ -16,16 +12,5 @@ public class RoutingItem
|
|||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("required")]
|
||||
public List<string> RequiredFields { get; set; } = new List<string>();
|
||||
|
||||
[JsonPropertyName("redirect_to")]
|
||||
public string? RedirectTo { get; set; }
|
||||
|
||||
[JsonPropertyName("disabled")]
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
public string[] RequiredFields { get; set; } = new string[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
public class RoutingProfile
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonPropertyName("agent_ids")]
|
||||
public List<string> AgentIds { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
namespace BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
public class RoutingRule
|
||||
{
|
||||
[JsonIgnore]
|
||||
public string AgentId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string AgentName { get; set; }
|
||||
|
||||
public string Field { get; set; }
|
||||
|
||||
public bool Required { get; set; }
|
||||
|
||||
public string? RedirectTo { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{AgentName} {Field}";
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ global using System.Text;
|
|||
global using System.Linq;
|
||||
global using System.Threading.Tasks;
|
||||
global using System.ComponentModel.DataAnnotations;
|
||||
global using System.Text.Json.Serialization;
|
||||
global using BotSharp.Abstraction.Agents.Models;
|
||||
global using BotSharp.Abstraction.Conversations.Models;
|
||||
global using BotSharp.Abstraction.Agents.Enums;
|
||||
|
|
@ -9,7 +9,6 @@ using BotSharp.Abstraction.Templating;
|
|||
using BotSharp.Core.Instructs;
|
||||
using BotSharp.Abstraction.Instructs;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Core.Routing.Services;
|
||||
|
||||
namespace BotSharp.Core;
|
||||
|
||||
|
|
@ -20,7 +19,6 @@ public static class BotSharpServiceCollectionExtensions
|
|||
services.AddScoped<IUserService, UserService>();
|
||||
|
||||
services.AddScoped<IAgentService, AgentService>();
|
||||
services.AddScoped<IRoutingService, RoutingService>();
|
||||
|
||||
var agentSettings = new AgentSettings();
|
||||
config.Bind("Agent", agentSettings);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,10 @@ public partial class ConversationService
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
agent = await agentService.LoadAgent(fn.CurrentAgentId);
|
||||
|
||||
wholeDialogs.Add(fn);
|
||||
if (fn.FunctionName != "route_to_agent")
|
||||
{
|
||||
wholeDialogs.Add(fn);
|
||||
}
|
||||
|
||||
await GetChatCompletionsAsyncRecursively(agent,
|
||||
wholeDialogs,
|
||||
|
|
@ -99,13 +102,16 @@ public partial class ConversationService
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Add to dialog history
|
||||
// The server had an error processing your request. Sorry about that!
|
||||
// _storage.Append(conversationId, preAgentId, fn);
|
||||
|
||||
// After function is executed, pass the result to LLM to get a natural response
|
||||
wholeDialogs.Add(fn);
|
||||
if (fn.FunctionName != "route_to_agent")
|
||||
{
|
||||
wholeDialogs.Add(fn);
|
||||
}
|
||||
|
||||
await GetChatCompletionsAsyncRecursively(agent,
|
||||
wholeDialogs,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using BotSharp.Core.Routing;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
|
|
@ -16,10 +15,6 @@ public class BotSharpDbContext : Database, IBotSharpRepository
|
|||
|
||||
public IQueryable<Conversation> Conversations => throw new NotImplementedException();
|
||||
|
||||
public IQueryable<RoutingItem> RoutingItems => throw new NotImplementedException();
|
||||
|
||||
public IQueryable<RoutingProfile> RoutingProfiles => throw new NotImplementedException();
|
||||
|
||||
|
||||
public int Transaction<TTableInterface>(Action action)
|
||||
{
|
||||
|
|
@ -143,27 +138,4 @@ public class BotSharpDbContext : Database, IBotSharpRepository
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Routing
|
||||
public List<RoutingItem> CreateRoutingItems(List<RoutingItem> routingItems)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<RoutingProfile> CreateRoutingProfiles(List<RoutingProfile> profiles)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DeleteRoutingItems()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DeleteRoutingProfiles()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@ using System.IO;
|
|||
using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using MongoDB.Driver;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Xml.Linq;
|
||||
using static Tensorflow.TensorShapeProto.Types;
|
||||
|
||||
namespace BotSharp.Core.Repository;
|
||||
|
||||
|
|
@ -135,48 +131,6 @@ public class FileRepository : IBotSharpRepository
|
|||
}
|
||||
}
|
||||
|
||||
private List<RoutingItem> _routingItems;
|
||||
public IQueryable<RoutingItem> RoutingItems
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_routingItems.IsNullOrEmpty())
|
||||
{
|
||||
return _routingItems.AsQueryable();
|
||||
}
|
||||
|
||||
_routingItems = new List<RoutingItem>();
|
||||
var filePath = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, "route.json");
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
_routingItems = JsonSerializer.Deserialize<List<RoutingItem>>(File.ReadAllText(filePath), _options);
|
||||
}
|
||||
|
||||
return _routingItems.AsQueryable();
|
||||
}
|
||||
}
|
||||
|
||||
private List<RoutingProfile> _routingProfiles;
|
||||
public IQueryable<RoutingProfile> RoutingProfiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_routingProfiles.IsNullOrEmpty())
|
||||
{
|
||||
return _routingProfiles.AsQueryable();
|
||||
}
|
||||
|
||||
_routingProfiles = new List<RoutingProfile>();
|
||||
var filePath = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, "routing-profile.json");
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
_routingProfiles = JsonSerializer.Deserialize<List<RoutingProfile>>(File.ReadAllText(filePath), _options);
|
||||
}
|
||||
|
||||
return _routingProfiles.AsQueryable();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add<TTableInterface>(object entity)
|
||||
{
|
||||
if (entity is Conversation conversation)
|
||||
|
|
@ -680,28 +634,6 @@ public class FileRepository : IBotSharpRepository
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region Routing
|
||||
public void DeleteRoutingItems()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DeleteRoutingProfiles()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<RoutingItem> CreateRoutingItems(List<RoutingItem> routingItems)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<RoutingProfile> CreateRoutingProfiles(List<RoutingProfile> profiles)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
private string GetAgentDataDir(string agentId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Functions;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
|
@ -33,8 +34,13 @@ public class RouteToAgentFn : IFunctionCallback
|
|||
}
|
||||
else
|
||||
{
|
||||
message.CurrentAgentId = agentId;
|
||||
message.ExecutionResult = $"Routed to {args.AgentName}";
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.Agents.FirstOrDefault(x => x.Name.ToLower() == args.AgentName.ToLower());
|
||||
if (record != null)
|
||||
{
|
||||
message.CurrentAgentId = record.Id;
|
||||
message.ExecutionResult = $"Routing to {args.AgentName}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,23 +57,23 @@ public class RouteToAgentFn : IFunctionCallback
|
|||
{
|
||||
var args = JsonSerializer.Deserialize<RoutingArgs>(message.FunctionArgs);
|
||||
var router = _services.GetRequiredService<IAgentRouting>();
|
||||
var routingRule = router.GetRecordByName(args.AgentName);
|
||||
|
||||
if (routingRule == null)
|
||||
var routingRules = router.GetRulesByName(args.AgentName);
|
||||
|
||||
if (routingRules == null || !routingRules.Any())
|
||||
{
|
||||
agentId = message.CurrentAgentId;
|
||||
message.ExecutionResult = $"Can't find agent {args.AgentName}";
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
agentId = routingRule.AgentId;
|
||||
agentId = routingRules.First().AgentId;
|
||||
// Add routed agent
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "route_to", agentId);
|
||||
|
||||
// Check required fields
|
||||
var root = JsonSerializer.Deserialize<JsonElement>(message.FunctionArgs);
|
||||
var missingFields = new List<string>();
|
||||
foreach (var field in routingRule.RequiredFields)
|
||||
foreach (var field in routingRules.Where(x => x.Required).Select(x => x.Field))
|
||||
{
|
||||
if (!root.EnumerateObject().Any(x => x.Name == field))
|
||||
{
|
||||
|
|
@ -96,16 +102,17 @@ public class RouteToAgentFn : IFunctionCallback
|
|||
{
|
||||
// Add field to args
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "missing_fields", missingFields);
|
||||
message.ExecutionResult = $"missing some information: [{string.Join(',', missingFields)}]";
|
||||
message.ExecutionResult = $"missing some information: {string.Join(',', missingFields)}";
|
||||
|
||||
// Handle redirect
|
||||
var routingRule = routingRules.FirstOrDefault(x => missingFields.Contains(x.Field));
|
||||
if (!string.IsNullOrEmpty(routingRule.RedirectTo))
|
||||
{
|
||||
agentId = routingRule.RedirectTo;
|
||||
var agent = router.GetRecordByAgentId(agentId);
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.Agents.First(x => x.Id == routingRule.RedirectTo);
|
||||
|
||||
// Add redirected agent
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", agent.Name);
|
||||
message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", record.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,34 +31,44 @@ public class Router : IAgentRouting
|
|||
#if !DEBUG
|
||||
[MemoryCache(10 * 60)]
|
||||
#endif
|
||||
public RoutingItem[] GetRoutingRecords()
|
||||
protected RoutingRule[] GetRoutingRecords()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
|
||||
var records = db.RoutingItems.ToArray();
|
||||
var profiles = db.RoutingProfiles.ToList();
|
||||
|
||||
if (!profiles.IsNullOrEmpty())
|
||||
var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray();
|
||||
var records = agents.SelectMany(x =>
|
||||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var name = state.GetState("channel");
|
||||
var specifiedProfile = profiles.FirstOrDefault(x => x.Name == name);
|
||||
if (specifiedProfile != null)
|
||||
x.RoutingRules.ForEach(r =>
|
||||
{
|
||||
records = records.Where(x => specifiedProfile.AgentIds.Contains(x.AgentId)).ToArray();
|
||||
}
|
||||
r.AgentId = x.Id;
|
||||
r.AgentName = x.Name;
|
||||
});
|
||||
return x.RoutingRules;
|
||||
}).ToArray();
|
||||
|
||||
// Filter agents by profile
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var name = state.GetState("channel");
|
||||
var specifiedProfile = agents.FirstOrDefault(x => x.Profiles.Contains(name));
|
||||
if (specifiedProfile != null)
|
||||
{
|
||||
records = records.Where(x => specifiedProfile.Profiles.Contains(name)).ToArray();
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
|
||||
public RoutingItem GetRecordByName(string name)
|
||||
public RoutingRule[] GetRulesByName(string name)
|
||||
{
|
||||
return GetRoutingRecords().FirstOrDefault(x => x.Name.ToLower() == name.ToLower());
|
||||
return GetRoutingRecords()
|
||||
.Where(x => x.AgentName.ToLower() == name.ToLower())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public RoutingItem GetRecordByAgentId(string id)
|
||||
public RoutingRule[] GetRulesByAgentId(string id)
|
||||
{
|
||||
return GetRoutingRecords().FirstOrDefault(x => x.AgentId == id);
|
||||
return GetRoutingRecords()
|
||||
.Where(x => x.AgentId == id)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
public class RoutingHook : AgentHookBase
|
||||
|
|
@ -9,10 +12,19 @@ public class RoutingHook : AgentHookBase
|
|||
|
||||
public override bool OnInstructionLoaded(string template, Dictionary<string, object> dict)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray();
|
||||
|
||||
var router = _services.GetRequiredService<IAgentRouting>();
|
||||
dict["routing_records"] = router.GetRoutingRecords()
|
||||
.Where(x => !x.Disabled)
|
||||
.ToList();
|
||||
dict["routing_records"] = agents.Select(x => new RoutingItem
|
||||
{
|
||||
AgentId = x.Id,
|
||||
Description = x.Description,
|
||||
Name = x.Name,
|
||||
RequiredFields = x.RoutingRules.Where(x => x.Required)
|
||||
.Select(x => x.Field)
|
||||
.ToArray()
|
||||
}).ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,66 +0,0 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Routing.Services;
|
||||
|
||||
public partial class RoutingService
|
||||
{
|
||||
public async Task<List<RoutingItem>> CreateRoutingItems(List<RoutingItem> routingItems)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var items = FetchRoutingItemsFromFile();
|
||||
|
||||
if (items.IsNullOrEmpty())
|
||||
{
|
||||
items = routingItems?.ToList() ?? new List<RoutingItem>();
|
||||
}
|
||||
|
||||
var savedItems = db.CreateRoutingItems(items);
|
||||
return await Task.FromResult(savedItems.ToList());
|
||||
}
|
||||
|
||||
public async Task<List<RoutingProfile>> CreateRoutingProfiles(List<RoutingProfile> routingProfiles)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var profiles = FetchRoutingProfilesFromFile();
|
||||
|
||||
if (profiles.IsNullOrEmpty())
|
||||
{
|
||||
profiles = routingProfiles?.ToList() ?? new List<RoutingProfile>();
|
||||
}
|
||||
|
||||
var savedProfiles = db.CreateRoutingProfiles(profiles);
|
||||
return await Task.FromResult(savedProfiles.ToList());
|
||||
}
|
||||
|
||||
private List<RoutingItem> FetchRoutingItemsFromFile()
|
||||
{
|
||||
var routingItems = new List<RoutingItem>();
|
||||
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
|
||||
var agentSettings = _services.GetRequiredService<AgentSettings>();
|
||||
var filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "route.json");
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
routingItems = JsonSerializer.Deserialize<List<RoutingItem>>(File.ReadAllText(filePath), _options);
|
||||
}
|
||||
|
||||
return routingItems ?? new List<RoutingItem>();
|
||||
}
|
||||
|
||||
private List<RoutingProfile> FetchRoutingProfilesFromFile()
|
||||
{
|
||||
var routingProfiles = new List<RoutingProfile>();
|
||||
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
|
||||
var agentSettings = _services.GetRequiredService<AgentSettings>();
|
||||
var filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "routing-profile.json");
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
routingProfiles = JsonSerializer.Deserialize<List<RoutingProfile>>(File.ReadAllText(filePath), _options);
|
||||
}
|
||||
|
||||
return routingProfiles ?? new List<RoutingProfile>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Core.Routing.Services;
|
||||
|
||||
public partial class RoutingService
|
||||
{
|
||||
public async Task DeleteRoutingItems()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
db.DeleteRoutingItems();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task DeleteRoutingProfiles()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
db.DeleteRoutingProfiles();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Routing.Services;
|
||||
|
||||
public partial class RoutingService : IRoutingService
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly JsonSerializerOptions _options;
|
||||
|
||||
public RoutingService(IServiceProvider service)
|
||||
{
|
||||
_services = service;
|
||||
_options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ using BotSharp.Abstraction.Agents.Models;
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
|
|
@ -40,8 +41,9 @@ public class Simulator
|
|||
response.FunctionArgs = JsonSerializer.Serialize(args.Parameters.Arguments);
|
||||
|
||||
var router = _services.GetRequiredService<IAgentRouting>();
|
||||
var record = router.GetRecordByName(args.Parameters.AgentName);
|
||||
response.CurrentAgentId = record.AgentId;
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.Agents.First(x => x.Name.ToLower() == args.Parameters.AgentName);
|
||||
response.CurrentAgentId = record.Id;
|
||||
}
|
||||
else if (args.Function == "interrupt_task_execution")
|
||||
{
|
||||
|
|
@ -84,8 +86,9 @@ public class Simulator
|
|||
|
||||
// Retrieve information from specific agent
|
||||
var router = _services.GetRequiredService<IAgentRouting>();
|
||||
var record = router.GetRecordByName(args.Parameters.AgentName);
|
||||
response = await SendMessageToAgent(record.AgentId, new List<RoleDialogModel>
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.Agents.First(x => x.Name.ToLower() == args.Parameters.AgentName);
|
||||
response = await SendMessageToAgent(record.Id, new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel(AgentRole.User, args.Parameters.Question)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
using BotSharp.Abstraction.ApiAdapters;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.OpenAPI.ViewModels.Routing;
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
public class RoutingController : ControllerBase, IApiAdapter
|
||||
{
|
||||
private readonly IRoutingService _routingService;
|
||||
public RoutingController(IRoutingService routingService)
|
||||
{
|
||||
_routingService = routingService;
|
||||
}
|
||||
|
||||
[HttpPost("/routing/items")]
|
||||
public async Task<List<RoutingItemViewModel>> CreateRoutingItems(List<RoutingItemCreationModel> routingItems)
|
||||
{
|
||||
var items = routingItems?.Select(x => x.ToRoutingItem())?.ToList() ?? new List<RoutingItem>();
|
||||
var savedItems = await _routingService.CreateRoutingItems(items);
|
||||
return savedItems.Select(x => RoutingItemViewModel.FromRoutingItem(x)).ToList();
|
||||
}
|
||||
|
||||
[HttpPost("/routing/profiles")]
|
||||
public async Task<List<RoutingProfileViewModel>> CreateRoutingProfiles(List<RoutingProfileCreationModel> routingProfiles)
|
||||
{
|
||||
var profiles = routingProfiles?.Select(x => x.ToRoutingProfile())?.ToList() ?? new List<RoutingProfile>();
|
||||
var savedProfiles = await _routingService.CreateRoutingProfiles(profiles);
|
||||
return savedProfiles.Select(x => RoutingProfileViewModel.FromRoutingProfile(x)).ToList();
|
||||
}
|
||||
|
||||
[HttpDelete("/routing/items")]
|
||||
public async Task RemoveRoutingItems()
|
||||
{
|
||||
await _routingService.DeleteRoutingItems();
|
||||
}
|
||||
|
||||
[HttpDelete("/routing/profiles")]
|
||||
public async Task RemoveRoutingProfiles()
|
||||
{
|
||||
await _routingService.DeleteRoutingProfiles();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Routing;
|
||||
|
||||
public class RoutingItemCreationModel
|
||||
{
|
||||
public string AgentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public List<string> RequiredFields { get; set; } = new List<string>();
|
||||
public string? RedirectTo { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public RoutingItem ToRoutingItem()
|
||||
{
|
||||
return new RoutingItem
|
||||
{
|
||||
AgentId = AgentId,
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
RequiredFields = RequiredFields,
|
||||
RedirectTo = RedirectTo,
|
||||
Disabled = Disabled
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Routing;
|
||||
|
||||
public class RoutingItemViewModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string AgentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public List<string> RequiredFields { get; set; } = new List<string>();
|
||||
public string? RedirectTo { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public static RoutingItemViewModel FromRoutingItem(RoutingItem routingItem)
|
||||
{
|
||||
return new RoutingItemViewModel
|
||||
{
|
||||
Id = routingItem.Id,
|
||||
AgentId = routingItem.AgentId,
|
||||
Name = routingItem.Name,
|
||||
Description = routingItem.Description,
|
||||
RequiredFields = routingItem.RequiredFields,
|
||||
RedirectTo = routingItem.RedirectTo,
|
||||
Disabled = routingItem.Disabled
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Routing;
|
||||
|
||||
public class RoutingProfileCreationModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<string> AgentIds { get; set; }
|
||||
|
||||
public RoutingProfile ToRoutingProfile()
|
||||
{
|
||||
return new RoutingProfile
|
||||
{
|
||||
Name = Name,
|
||||
AgentIds = AgentIds,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Routing;
|
||||
|
||||
public class RoutingProfileViewModel
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<string> AgentIds { get; set; }
|
||||
|
||||
public static RoutingProfileViewModel FromRoutingProfile(RoutingProfile profile)
|
||||
{
|
||||
return new RoutingProfileViewModel
|
||||
{
|
||||
Id = profile.Id,
|
||||
Name = profile.Name,
|
||||
AgentIds = profile.AgentIds,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
|
|
@ -137,54 +136,6 @@ public class MongoRepository : IBotSharpRepository
|
|||
}
|
||||
}
|
||||
|
||||
private List<RoutingItem> _routingItems;
|
||||
public IQueryable<RoutingItem> RoutingItems
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_routingItems.IsNullOrEmpty())
|
||||
{
|
||||
return _routingItems.AsQueryable();
|
||||
}
|
||||
|
||||
var routingItemDocs = _dc.RoutingItems?.AsQueryable()?.ToList() ?? new List<RoutingItemCollection>();
|
||||
_routingItems = routingItemDocs.Select(x => new RoutingItem
|
||||
{
|
||||
Id = x.Id.ToString(),
|
||||
AgentId = x.AgentId.ToString(),
|
||||
Description = x.Description,
|
||||
RequiredFields = x.RequiredFields,
|
||||
RedirectTo = x.RedirectTo.ToString(),
|
||||
Disabled = x.Disabled
|
||||
}).ToList();
|
||||
|
||||
return _routingItems.AsQueryable();
|
||||
}
|
||||
}
|
||||
|
||||
private List<RoutingProfile> _routingProfiles;
|
||||
public IQueryable<RoutingProfile> RoutingProfiles
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_routingProfiles.IsNullOrEmpty())
|
||||
{
|
||||
return _routingProfiles.AsQueryable();
|
||||
}
|
||||
|
||||
var routingProfilDocs = _dc.RoutingProfiles?.AsQueryable()?.ToList() ?? new List<RoutingProfileCollection>();
|
||||
_routingProfiles = routingProfilDocs.Select(x => new RoutingProfile
|
||||
{
|
||||
Id = x.Id.ToString(),
|
||||
Name = x.Name,
|
||||
AgentIds = x.AgentIds?.Select(x => x.ToString())?.ToList() ?? new List<string>()
|
||||
}).ToList();
|
||||
|
||||
return _routingProfiles.AsQueryable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<string> _changedTableNames = new List<string>();
|
||||
public void Add<TTableInterface>(object entity)
|
||||
{
|
||||
|
|
@ -667,60 +618,4 @@ public class MongoRepository : IBotSharpRepository
|
|||
_dc.Users.InsertOne(userCollection);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Routing
|
||||
public void DeleteRoutingItems()
|
||||
{
|
||||
_dc.RoutingItems.DeleteMany(Builders<RoutingItemCollection>.Filter.Empty);
|
||||
}
|
||||
|
||||
public void DeleteRoutingProfiles()
|
||||
{
|
||||
_dc.RoutingProfiles.DeleteMany(Builders<RoutingProfileCollection>.Filter.Empty);
|
||||
}
|
||||
|
||||
public List<RoutingItem> CreateRoutingItems(List<RoutingItem> routingItems)
|
||||
{
|
||||
var collections = routingItems?.Select(x => new RoutingItemCollection
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AgentId = Guid.Parse(x.AgentId),
|
||||
Name = x.Name,
|
||||
Description = x.Description,
|
||||
RequiredFields = x.RequiredFields,
|
||||
RedirectTo = !string.IsNullOrEmpty(x.RedirectTo) ? Guid.Parse(x.RedirectTo) : null,
|
||||
Disabled = x.Disabled
|
||||
})?.ToList() ?? new List<RoutingItemCollection>();
|
||||
|
||||
_dc.RoutingItems.InsertMany(collections);
|
||||
return collections.Select(x => new RoutingItem
|
||||
{
|
||||
Id = x.Id.ToString(),
|
||||
AgentId = x.AgentId.ToString(),
|
||||
Name = x.Name,
|
||||
Description = x.Description,
|
||||
RequiredFields = x.RequiredFields,
|
||||
RedirectTo = x.RedirectTo?.ToString(),
|
||||
Disabled = x.Disabled
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public List<RoutingProfile> CreateRoutingProfiles(List<RoutingProfile> profiles)
|
||||
{
|
||||
var collections = profiles?.Select(x => new RoutingProfileCollection
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = x.Name,
|
||||
AgentIds = x.AgentIds.Select(x => Guid.Parse(x)).ToList()
|
||||
})?.ToList() ?? new List<RoutingProfileCollection>();
|
||||
|
||||
_dc.RoutingProfiles.InsertMany(collections);
|
||||
return collections.Select(x => new RoutingProfile
|
||||
{
|
||||
Id = x.Id.ToString(),
|
||||
Name = x.Name,
|
||||
AgentIds = x.AgentIds.Select(x => x.ToString()).ToList()
|
||||
}).ToList();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue