From de3621f8bf2190ef937534bdfbfc64c6fedf7eee Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Mon, 25 Nov 2024 16:13:40 -0600 Subject: [PATCH] dynamic register fluid model --- .../Templating/ITemplateRender.cs | 1 + .../BotSharp.Core/Agents/AgentPlugin.cs | 3 ++ .../Agents/Services/AgentService.Rendering.cs | 19 +++++--- .../BotSharp.Core/BotSharpCoreExtensions.cs | 4 ++ .../Conversations/ConversationPlugin.cs | 4 +- .../Templating/TemplateRender.cs | 47 ++++++++++++++++++- .../Hooks/SqlDriverAgentHook.cs | 19 ++++++++ .../SqlDriverPlugin.cs | 1 + 8 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverAgentHook.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Templating/ITemplateRender.cs b/src/Infrastructure/BotSharp.Abstraction/Templating/ITemplateRender.cs index e5ddeb61..82eff1c1 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Templating/ITemplateRender.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Templating/ITemplateRender.cs @@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Templating; public interface ITemplateRender { string Render(string template, Dictionary dict); + void Register(Type type); } diff --git a/src/Infrastructure/BotSharp.Core/Agents/AgentPlugin.cs b/src/Infrastructure/BotSharp.Core/Agents/AgentPlugin.cs index 2f51f1dd..cfbc541f 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/AgentPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/AgentPlugin.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Plugins.Models; using BotSharp.Abstraction.Settings; +using BotSharp.Abstraction.Templating; using BotSharp.Abstraction.Users.Enums; using Microsoft.Extensions.Configuration; @@ -33,6 +34,8 @@ public class AgentPlugin : IBotSharpPlugin services.AddScoped(provider => { var settingService = provider.GetRequiredService(); + var render = provider.GetRequiredService(); + render.Register(typeof(AgentSettings)); return settingService.Bind("Agent"); }); } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs index e9617d17..ba76e310 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs @@ -9,13 +9,16 @@ public partial class AgentService public string RenderedInstruction(Agent agent) { var render = _services.GetRequiredService(); - // update states var conv = _services.GetRequiredService(); + + // update states foreach (var t in conv.States.GetStates()) { agent.TemplateDict[t.Key] = t.Value; } - return render.Render(agent.Instruction, agent.TemplateDict); + + var res = render.Render(agent.Instruction, agent.TemplateDict); + return res; } public bool RenderFunction(Agent agent, FunctionDef def) @@ -108,16 +111,18 @@ public partial class AgentService public string RenderedTemplate(Agent agent, string templateName) { - // render liquid template - var render = _services.GetRequiredService(); - var template = agent.Templates.First(x => x.Name == templateName).Content; - // update states var conv = _services.GetRequiredService(); + var render = _services.GetRequiredService(); + + var template = agent.Templates.First(x => x.Name == templateName).Content; + + // update states foreach (var t in conv.States.GetStates()) { agent.TemplateDict[t.Key] = t.Value; } + // render liquid template var content = render.Render(template, agent.TemplateDict); HookEmitter.Emit(_services, async hook => @@ -126,4 +131,4 @@ public partial class AgentService return content; } -} +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs index a60fb4fd..c5e33a4b 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs @@ -12,6 +12,8 @@ using BotSharp.Core.Processors; using StackExchange.Redis; using BotSharp.Core.Infrastructures.Events; using BotSharp.Core.Roles.Services; +using BotSharp.Abstraction.Templating; +using BotSharp.Core.Templating; namespace BotSharp.Core; @@ -24,6 +26,8 @@ public static class BotSharpCoreExtensions services.AddSingleton(x => interpreterSettings); services.AddSingleton(); + // Register template render + services.AddSingleton(); services.AddScoped(); services.AddScoped(); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs b/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs index a9be6fd2..e2b11afb 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/ConversationPlugin.cs @@ -30,6 +30,8 @@ public class ConversationPlugin : IBotSharpPlugin services.AddScoped(provider => { var settingService = provider.GetRequiredService(); + var render = provider.GetRequiredService(); + render.Register(typeof(ConversationSetting)); return settingService.Bind("Conversation"); }); @@ -48,8 +50,6 @@ public class ConversationPlugin : IBotSharpPlugin // Rich content messaging services.AddScoped(); - // Register template render - services.AddSingleton(); services.AddScoped(); services.AddScoped(); diff --git a/src/Infrastructure/BotSharp.Core/Templating/TemplateRender.cs b/src/Infrastructure/BotSharp.Core/Templating/TemplateRender.cs index 33b27177..c16a8c4b 100644 --- a/src/Infrastructure/BotSharp.Core/Templating/TemplateRender.cs +++ b/src/Infrastructure/BotSharp.Core/Templating/TemplateRender.cs @@ -1,10 +1,10 @@ -using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Models; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Templating; using BotSharp.Abstraction.Translation.Models; using Fluid; +using System.Collections; +using System.Reflection; namespace BotSharp.Core.Templating; @@ -48,4 +48,47 @@ public class TemplateRender : ITemplateRender return template; } } + + + public void Register(Type type) + { + if (type == null || IsStringType(type)) return; + + if (IsListType(type)) + { + if (type.IsGenericType) + { + var genericType = type.GetGenericArguments()[0]; + Register(genericType); + } + } + else if (IsTrackToNextLevel(type)) + { + _options.MemberAccessStrategy.Register(type); + var props = type.GetProperties(); + foreach (var prop in props) + { + Register(prop.PropertyType); + } + } + } + + + #region Private methods + private static bool IsStringType(Type type) + { + return type == typeof(string); + } + + private static bool IsListType(Type type) + { + var interfaces = type.GetTypeInfo().ImplementedInterfaces; + return type.IsArray || interfaces.Any(x => x.Name == typeof(IEnumerable).Name); + } + + private static bool IsTrackToNextLevel(Type type) + { + return type.IsClass || type.IsInterface || type.IsAbstract; + } + #endregion } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverAgentHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverAgentHook.cs new file mode 100644 index 00000000..53b7866f --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverAgentHook.cs @@ -0,0 +1,19 @@ +using BotSharp.Abstraction.Agents.Settings; + +namespace BotSharp.Plugin.SqlDriver.Hooks; + +public class SqlDriverAgentHook : AgentHookBase, IAgentHook +{ + public override string SelfId => BuiltInAgentId.Planner; + + public SqlDriverAgentHook(IServiceProvider services, AgentSettings settings) + : base(services, settings) + { + } + + public override void OnAgentLoaded(Agent agent) + { + var dbType = SqlDriverHelper.GetDatabaseType(_services); + agent.TemplateDict["db_type"] = dbType; + } +} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs index 6a618e34..6bb17014 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs @@ -27,6 +27,7 @@ public class SqlDriverPlugin : IBotSharpPlugin services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); }