diff --git a/docs/static/screenshots/agent-builder-agents.png b/docs/static/screenshots/agent-builder-agents.png index 611f5a07..5f8643a9 100644 Binary files a/docs/static/screenshots/agent-builder-agents.png and b/docs/static/screenshots/agent-builder-agents.png differ diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs index e6599836..2b22d0da 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Repositories.Filters; + namespace BotSharp.Abstraction.Agents; /// @@ -7,7 +9,7 @@ public interface IAgentService { Task CreateAgent(Agent agent); Task RefreshAgents(); - Task> GetAgents(bool? allowRouting = null); + Task> GetAgents(AgentFilter filter); /// /// Load agent configurations and trigger hooks diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs index 251af6b0..b74ae777 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs @@ -62,6 +62,7 @@ public class Agent public bool AllowRouting { get; set; } public bool Disabled { get; set; } + public string IconUrl { get; set; } /// /// Profile by channel diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs index 1e05f8a6..b5da6d36 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/Filters/AgentFilter.cs @@ -6,5 +6,6 @@ public class AgentFilter public bool? Disabled { get; set; } public bool? AllowRouting { get; set; } public bool? IsPublic { get; set; } + public bool? IsRouter { get; set; } public List? AgentIds { get; set; } } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs index 13099add..17b4f75d 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs @@ -8,9 +8,8 @@ public partial class AgentService #if !DEBUG [MemoryCache(10 * 60)] #endif - public async Task> GetAgents(bool? allowRouting = null) + public async Task> GetAgents(AgentFilter filter) { - var filter = new AgentFilter { AllowRouting = allowRouting }; var agents = _db.GetAgents(filter); return await Task.FromResult(agents); } diff --git a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs index a2de0992..d15f2f23 100644 --- a/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs +++ b/src/Infrastructure/BotSharp.Core/Planning/NaivePlanner.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Planning; +using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Settings; using BotSharp.Abstraction.Templating; @@ -108,7 +109,10 @@ public class NaivePlanner : IPlaner private void FixMalformedResponse(FunctionCallFromLlm args) { var agentService = _services.GetRequiredService(); - var agents = agentService.GetAgents(allowRouting: true).Result; + var agents = agentService.GetAgents(new AgentFilter + { + AllowRouting = true + }).Result; var malformed = false; // Sometimes it populate malformed Function in Agent name diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index e7d7347a..dbba2f75 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -6,24 +6,26 @@ using BotSharp.Abstraction.Agents.Models; using MongoDB.Driver; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Repositories.Filters; -using BotSharp.Abstraction.Utilities; -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Repositories.Models; +using BotSharp.Abstraction.Routing.Settings; namespace BotSharp.Core.Repository; public class FileRepository : IBotSharpRepository { + private readonly IServiceProvider _services; private readonly BotSharpDatabaseSettings _dbSettings; private readonly AgentSettings _agentSettings; private readonly ConversationSetting _conversationSettings; private JsonSerializerOptions _options; public FileRepository( + IServiceProvider services, BotSharpDatabaseSettings dbSettings, AgentSettings agentSettings, ConversationSetting conversationSettings) { + _services = services; _dbSettings = dbSettings; _agentSettings = agentSettings; _conversationSettings = conversationSettings; @@ -542,6 +544,14 @@ public class FileRepository : IBotSharpRepository query = query.Where(x => x.IsPublic == filter.IsPublic); } + if (filter.IsRouter.HasValue) + { + var route = _services.GetRequiredService(); + query = filter.IsRouter.Value ? + query.Where(x => x.Id == route.AgentId) : + query.Where(x => x.Id != route.AgentId); + } + if (filter.AgentIds != null) { query = query.Where(x => filter.AgentIds.Contains(x.Id)); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index 465cb977..24f8a61b 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -21,9 +21,9 @@ public class AgentController : ControllerBase } [HttpGet("/agents")] - public async Task> GetAgents() + public async Task> GetAgents([FromQuery] AgentFilter filter) { - var agents = await _agentService.GetAgents(); + var agents = await _agentService.GetAgents(filter); return agents.Select(x => AgentViewModel.FromAgent(x)).ToList(); } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs index 8e7b16a7..49d7d095 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Agents/AgentViewModel.cs @@ -21,6 +21,8 @@ public class AgentViewModel [JsonPropertyName("allow_routing")] public bool AllowRouting { get; set; } public bool Disabled { get; set; } + [JsonPropertyName("icon_url")] + public string IconUrl { get; set; } public List Profiles { get; set; } [JsonPropertyName("routing_rules")] @@ -51,6 +53,7 @@ public class AgentViewModel Samples = agent.Samples, IsPublic= agent.IsPublic, Disabled = agent.Disabled, + IconUrl = agent.IconUrl, AllowRouting = agent.AllowRouting, Profiles = agent.Profiles, RoutingRules = agent.RoutingRules, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index 1d111062..7a967f2a 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -4,6 +4,7 @@ using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Models; using BotSharp.Abstraction.Routing.Models; +using BotSharp.Abstraction.Routing.Settings; using BotSharp.Abstraction.Users.Models; using BotSharp.Plugin.MongoStorage.Collections; using BotSharp.Plugin.MongoStorage.Models; @@ -461,6 +462,14 @@ public class MongoRepository : IBotSharpRepository query = query.Where(x => x.IsPublic == filter.IsPublic); } + if (filter.IsRouter.HasValue) + { + var route = _services.GetRequiredService(); + query = filter.IsRouter.Value ? + query.Where(x => x.Id == route.AgentId) : + query.Where(x => x.Id != route.AgentId); + } + if (filter.AgentIds != null) { query = query.Where(x => filter.AgentIds.Contains(x.Id)); diff --git a/src/WebStarter/Program.cs b/src/WebStarter/Program.cs index db1ecfde..497fbf4e 100644 --- a/src/WebStarter/Program.cs +++ b/src/WebStarter/Program.cs @@ -71,4 +71,9 @@ app.UseBotSharp(); app.UseCors("MyCorsPolicy"); #endif +// Host BotSharp UI built in adapter-static +app.UseFileServer(); +app.UseDefaultFiles(); +app.UseStaticFiles(); + app.Run(); diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 2e72e571..ff79aa88 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -68,5 +68,9 @@ + + + + diff --git a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json index af5d7e1a..0394958a 100644 --- a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json +++ b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json @@ -4,5 +4,6 @@ "createdDateTime": "2023-08-18T14:39:32.2349685Z", "updatedDateTime": "2023-08-18T14:39:32.2349686Z", "id": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a", + "iconUrl": "https://cdn.iconscout.com/icon/premium/png-256-thumb/route-1613278-1368497.png", "isPublic": true } \ No newline at end of file diff --git a/src/WebStarter/wwwroot/favicon.ico b/src/WebStarter/wwwroot/favicon.ico new file mode 100644 index 00000000..9fe5f32e Binary files /dev/null and b/src/WebStarter/wwwroot/favicon.ico differ diff --git a/tests/BotSharp.Plugin.PizzaBot/documents/RDD-ChicagoThinCrust.pdf b/tests/BotSharp.Plugin.PizzaBot/documents/RDD-ChicagoThinCrust.pdf new file mode 100644 index 00000000..7e5276ef Binary files /dev/null and b/tests/BotSharp.Plugin.PizzaBot/documents/RDD-ChicagoThinCrust.pdf differ diff --git a/tests/BotSharp.Plugin.PizzaBot/documents/pizza-recipebooklet-1.pdf b/tests/BotSharp.Plugin.PizzaBot/documents/pizza-recipebooklet-1.pdf new file mode 100644 index 00000000..17ca6704 Binary files /dev/null and b/tests/BotSharp.Plugin.PizzaBot/documents/pizza-recipebooklet-1.pdf differ