From 7fbff8c77789f8372ce81e5fe01318023dd27a0d Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Tue, 10 Oct 2023 23:11:06 -0500 Subject: [PATCH] PluginController --- .gitignore | 1 + .../Plugins/Models/PluginDef.cs | 8 ++ .../Plugins/PluginLoaderSettings.cs | 2 +- .../BotSharp.Core/BotSharp.Core.csproj | 2 +- .../BotSharpServiceCollectionExtensions.cs | 4 +- .../Infrastructures/PluginLoader.cs | 72 ----------- .../BotSharp.Core/Plugins/PluginLoader.cs | 122 ++++++++++++++++++ .../Controllers/AgentController.cs | 7 + .../Controllers/PluginController.cs | 25 ++++ .../AzureOpenAiPlugin.cs | 3 + .../BotSharp.Plugin.AzureOpenAI.csproj | 1 + .../BotSharp.Plugin.ChatbotUI.csproj | 1 + .../BotSharp.Plugin.GoogleAI.csproj | 1 + .../BotSharp.Plugin.HuggingFace.csproj | 1 + .../BotSharp.Plugin.KnowledgeBase.csproj | 1 + .../BotSharp.Plugin.LLamaSharp.csproj | 1 + .../BotSharp.Plugin.MetaAI.csproj | 1 + .../BotSharp.Plugin.MetaMessenger.csproj | 1 + .../BotSharp.Plugin.MongoStorage.csproj | 3 +- .../MongoStoragePlugin.cs | 3 + .../BotSharp.Plugin.PaddleSharp.csproj | 1 + .../BotSharp.Plugin.Qdrant.csproj | 1 + .../BotSharp.Plugin.RoutingSpeeder.csproj | 1 + .../BotSharp.Plugin.WeChat.csproj | 1 + 24 files changed, 188 insertions(+), 76 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginDef.cs delete mode 100644 src/Infrastructure/BotSharp.Core/Infrastructures/PluginLoader.cs create mode 100644 src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs create mode 100644 src/Infrastructure/BotSharp.OpenAPI/Controllers/PluginController.cs diff --git a/.gitignore b/.gitignore index b529228bf..4e3f182a3 100644 --- a/.gitignore +++ b/.gitignore @@ -287,3 +287,4 @@ __pycache__/ /docs/_build *.bin /src/WebStarter/data/conversations +XMLs diff --git a/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginDef.cs b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginDef.cs new file mode 100644 index 000000000..85128209e --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Plugins/Models/PluginDef.cs @@ -0,0 +1,8 @@ +namespace BotSharp.Abstraction.Plugins.Models; + +public class PluginDef +{ + public string Name { get; set; } + public string Description { get; set; } + public string Assembly { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Plugins/PluginLoaderSettings.cs b/src/Infrastructure/BotSharp.Abstraction/Plugins/PluginLoaderSettings.cs index 36b20d476..70564846f 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Plugins/PluginLoaderSettings.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Plugins/PluginLoaderSettings.cs @@ -1,6 +1,6 @@ namespace BotSharp.Abstraction.Plugins; -public class PluginLoaderSettings +public class PluginSettings { public string[] Assemblies { get; set; } = new string[0]; } diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 15cfd0b9f..1b789f1f5 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -52,7 +52,7 @@ - + diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 02a5f0505..16b95a8fc 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -11,6 +11,7 @@ using BotSharp.Abstraction.Routing; using BotSharp.Core.Routing.Hooks; using BotSharp.Abstraction.Routing.Models; +using BotSharp.Core.Plugins; namespace BotSharp.Core; @@ -106,8 +107,9 @@ public static IApplicationBuilder UseBotSharp(this IApplicationBuilder app) public static void RegisterPlugins(IServiceCollection services, IConfiguration config) { - var pluginSettings = new PluginLoaderSettings(); + var pluginSettings = new PluginSettings(); config.Bind("PluginLoader", pluginSettings); + services.AddSingleton(pluginSettings); var loader = new PluginLoader(services, config, pluginSettings); loader.Load(assembly => diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/PluginLoader.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/PluginLoader.cs deleted file mode 100644 index bd14a8275..000000000 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/PluginLoader.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Configuration; -using System.Drawing; -using System.IO; -using System.Reflection; - -namespace BotSharp.Core.Infrastructures; - -public class PluginLoader -{ - private readonly IServiceCollection _services; - private readonly IConfiguration _config; - private readonly PluginLoaderSettings _settings; - private static List _modules = new List(); - - public PluginLoader(IServiceCollection services, - IConfiguration config, - PluginLoaderSettings settings) - { - _services = services; - _config = config; - _settings = settings; - } - - public void Load(Action loaded) - { - var executingDir = Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName; - - _settings.Assemblies.ToList().ForEach(assemblyName => - { - var assemblyPath = Path.Combine(executingDir, assemblyName + ".dll"); - if (File.Exists(assemblyPath)) - { - var assembly = Assembly.Load(assemblyName); - - var modules = assembly.GetTypes() - .Where(x => x.GetInterface(nameof(IBotSharpPlugin)) != null) - .Select(x => Activator.CreateInstance(x) as IBotSharpPlugin) - .ToList(); - - foreach (var module in modules) - { - module.RegisterDI(_services, _config); - Console.WriteLine($"Loaded plugin {module.GetType().Name} from {assemblyName}.", Color.Green); - } - - loaded(assembly); - _modules.AddRange(modules); - } - else - { - Console.WriteLine($"Can't find assemble {assemblyPath}."); - } - }); - } - - public void Configure(IApplicationBuilder app) - { - if (_modules.Count == 0) - { - Console.WriteLine($"No plugin loaded. Please check whether the Load() method is called.", Color.Yellow); - } - - _modules.ForEach(module => - { - if (module.GetType().GetInterface(nameof(IBotSharpAppPlugin)) != null) - { - (module as IBotSharpAppPlugin).Configure(app); - } - }); - } -} diff --git a/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs new file mode 100644 index 000000000..0dae5b92c --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs @@ -0,0 +1,122 @@ +using BotSharp.Abstraction.Plugins.Models; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Xml; + +namespace BotSharp.Core.Plugins; + +public class PluginLoader +{ + private readonly IServiceCollection _services; + private readonly IConfiguration _config; + private readonly PluginSettings _settings; + private static List _modules = new List(); + private static List _plugins = new List(); + private static string _executingDir; + + public PluginLoader(IServiceCollection services, + IConfiguration config, + PluginSettings settings) + { + _services = services; + _config = config; + _settings = settings; + } + + public void Load(Action loaded) + { + _executingDir = Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName; + + _settings.Assemblies.ToList().ForEach(assemblyName => + { + var assemblyPath = Path.Combine(_executingDir, assemblyName + ".dll"); + if (File.Exists(assemblyPath)) + { + var assembly = Assembly.Load(assemblyName); + + var modules = assembly.GetTypes() + .Where(x => x.GetInterface(nameof(IBotSharpPlugin)) != null) + .Select(x => Activator.CreateInstance(x) as IBotSharpPlugin) + .ToList(); + + foreach (var module in modules) + { + module.RegisterDI(_services, _config); + string classSummary = GetSummaryComment(module.GetType()); + _modules.Add(module); + _plugins.Add(new PluginDef + { + Name = module.GetType().Name, + Description = classSummary, + Assembly = assemblyName + }); + Console.Write($"Loaded plugin "); + Console.Write(module.GetType().Name, Color.Green); + Console.WriteLine($" from {assemblyName}."); + if (!string.IsNullOrEmpty(classSummary)) + { + Console.WriteLine(classSummary); + } + } + + loaded(assembly); + } + else + { + Console.WriteLine($"Can't find assemble {assemblyPath}."); + } + }); + } + + public List GetPlugins() + { + return _plugins; + } + + public string GetSummaryComment(Type member) + { + string summary = string.Empty; + XmlDocument xmlDoc = new XmlDocument(); + + // Load the XML documentation file + var xmlFile = Path.Combine(_executingDir, $"{member.Module.Assembly.FullName.Split(',')[0]}.xml"); + if (!File.Exists(xmlFile)) + { + return ""; + } + xmlDoc.Load(xmlFile); // Replace with your actual XML documentation file name + + // Construct the XPath query to find the summary comment + string memberName = $"T:{member.FullName}"; + string xpath = $"/doc/members/member[@name='{memberName}']/summary"; + + // Find the summary comment using the XPath query + XmlNode summaryNode = xmlDoc.SelectSingleNode(xpath); + + if (summaryNode != null) + { + summary = summaryNode.InnerXml.Trim(); + } + + return summary; + } + + public void Configure(IApplicationBuilder app) + { + if (_modules.Count == 0) + { + Console.WriteLine($"No plugin loaded. Please check whether the Load() method is called.", Color.Yellow); + } + + _modules.ForEach(module => + { + if (module.GetType().GetInterface(nameof(IBotSharpAppPlugin)) != null) + { + (module as IBotSharpAppPlugin).Configure(app); + } + }); + } +} diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs index a4830d8d7..fe4206fae 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs @@ -18,6 +18,13 @@ public AgentController(IAgentService agentService, IServiceProvider services) _services = services; } + [HttpGet("/agent/{id}")] + public async Task GetAgent([FromRoute] string id) + { + var agent = await _agentService.GetAgent(id); + return AgentViewModel.FromAgent(agent); + } + [HttpGet("/agents")] public async Task> GetAgents() { diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/PluginController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/PluginController.cs new file mode 100644 index 000000000..23ba001b5 --- /dev/null +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/PluginController.cs @@ -0,0 +1,25 @@ +using BotSharp.Abstraction.Plugins.Models; +using BotSharp.Core.Plugins; + +namespace BotSharp.OpenAPI.Controllers; + +[Authorize] +[ApiController] +public class PluginController : ControllerBase +{ + private readonly IServiceProvider _services; + private readonly PluginSettings _settings; + + public PluginController(IServiceProvider services, PluginSettings settings) + { + _services = services; + _settings = settings; + } + + [HttpGet("/plugins")] + public List GetPlugins() + { + var loader = _services.GetRequiredService(); + return loader.GetPlugins(); + } +} diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs index 1232e6683..5a4047c9e 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs @@ -9,6 +9,9 @@ namespace BotSharp.Platform.AzureAi; +/// +/// Azure OpenAI Service +/// public class AzureOpenAiPlugin : IBotSharpPlugin { public void RegisterDI(IServiceCollection services, IConfiguration config) diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj b/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj index fbe81da8b..ea10eaece 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj b/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj index 78b077dd4..8d96e352f 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj index 44e87f6c9..12a2a4170 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/BotSharp.Plugin.GoogleAI.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.HuggingFace/BotSharp.Plugin.HuggingFace.csproj b/src/Plugins/BotSharp.Plugin.HuggingFace/BotSharp.Plugin.HuggingFace.csproj index d0c56c274..640b18fef 100644 --- a/src/Plugins/BotSharp.Plugin.HuggingFace/BotSharp.Plugin.HuggingFace.csproj +++ b/src/Plugins/BotSharp.Plugin.HuggingFace/BotSharp.Plugin.HuggingFace.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj b/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj index f6bf34083..28609e58f 100644 --- a/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj +++ b/src/Plugins/BotSharp.Plugin.KnowledgeBase/BotSharp.Plugin.KnowledgeBase.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.LLamaSharp/BotSharp.Plugin.LLamaSharp.csproj b/src/Plugins/BotSharp.Plugin.LLamaSharp/BotSharp.Plugin.LLamaSharp.csproj index 0a75a201f..986936bce 100644 --- a/src/Plugins/BotSharp.Plugin.LLamaSharp/BotSharp.Plugin.LLamaSharp.csproj +++ b/src/Plugins/BotSharp.Plugin.LLamaSharp/BotSharp.Plugin.LLamaSharp.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj index 1e2347693..7bf6a42ed 100644 --- a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj +++ b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj b/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj index 8c0499e5f..7ce8a94ee 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj @@ -5,6 +5,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/BotSharp.Plugin.MongoStorage.csproj b/src/Plugins/BotSharp.Plugin.MongoStorage/BotSharp.Plugin.MongoStorage.csproj index e85cf037a..028d61365 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/BotSharp.Plugin.MongoStorage.csproj +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/BotSharp.Plugin.MongoStorage.csproj @@ -5,10 +5,11 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True - + diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoStoragePlugin.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoStoragePlugin.cs index 644737ca3..d5b9e206e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoStoragePlugin.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoStoragePlugin.cs @@ -2,6 +2,9 @@ namespace BotSharp.Plugin.MongoStorage; +/// +/// MongoDB as the repository +/// public class MongoStoragePlugin : IBotSharpPlugin { public void RegisterDI(IServiceCollection services, IConfiguration config) diff --git a/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj b/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj index c76fa3e8f..3ec07837d 100644 --- a/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj +++ b/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj b/src/Plugins/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj index e02d44481..aa9ca00d0 100644 --- a/src/Plugins/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj +++ b/src/Plugins/BotSharp.Plugin.Qdrant/BotSharp.Plugin.Qdrant.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj index c588f6b2b..cc28ea407 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj @@ -6,6 +6,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True diff --git a/src/Plugins/BotSharp.Plugin.WeChat/BotSharp.Plugin.WeChat.csproj b/src/Plugins/BotSharp.Plugin.WeChat/BotSharp.Plugin.WeChat.csproj index d6f251572..e08f0f137 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/BotSharp.Plugin.WeChat.csproj +++ b/src/Plugins/BotSharp.Plugin.WeChat/BotSharp.Plugin.WeChat.csproj @@ -5,6 +5,7 @@ $(LangVersion) $(BotSharpVersion) $(GeneratePackageOnBuild) + True