dynamic register fluid model

This commit is contained in:
Jicheng Lu 2024-11-25 16:13:40 -06:00
parent 65d5e2cf12
commit de3621f8bf
8 changed files with 87 additions and 11 deletions

View file

@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Templating;
public interface ITemplateRender
{
string Render(string template, Dictionary<string, object> dict);
void Register(Type type);
}

View file

@ -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<ISettingService>();
var render = provider.GetRequiredService<ITemplateRender>();
render.Register(typeof(AgentSettings));
return settingService.Bind<AgentSettings>("Agent");
});
}

View file

@ -9,13 +9,16 @@ public partial class AgentService
public string RenderedInstruction(Agent agent)
{
var render = _services.GetRequiredService<ITemplateRender>();
// update states
var conv = _services.GetRequiredService<IConversationService>();
// 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<ITemplateRender>();
var template = agent.Templates.First(x => x.Name == templateName).Content;
// update states
var conv = _services.GetRequiredService<IConversationService>();
var render = _services.GetRequiredService<ITemplateRender>();
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<IContentGeneratingHook>(_services, async hook =>
@ -126,4 +131,4 @@ public partial class AgentService
return content;
}
}
}

View file

@ -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<DistributedLocker>();
// Register template render
services.AddSingleton<ITemplateRender, TemplateRender>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IRoleService, RoleService>();

View file

@ -30,6 +30,8 @@ public class ConversationPlugin : IBotSharpPlugin
services.AddScoped(provider =>
{
var settingService = provider.GetRequiredService<ISettingService>();
var render = provider.GetRequiredService<ITemplateRender>();
render.Register(typeof(ConversationSetting));
return settingService.Bind<ConversationSetting>("Conversation");
});
@ -48,8 +50,6 @@ public class ConversationPlugin : IBotSharpPlugin
// Rich content messaging
services.AddScoped<IRichContentService, RichContentService>();
// Register template render
services.AddSingleton<ITemplateRender, TemplateRender>();
services.AddScoped<IResponseTemplateService, ResponseTemplateService>();
services.AddScoped<IExecutor, InstructExecutor>();

View file

@ -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
}

View file

@ -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;
}
}

View file

@ -27,6 +27,7 @@ public class SqlDriverPlugin : IBotSharpPlugin
services.AddScoped<DbKnowledgeService>();
services.AddScoped<IPlanningHook, SqlDriverPlanningHook>();
services.AddScoped<IKnowledgeHook, SqlDriverKnowledgeHook>();
services.AddScoped<IAgentHook, SqlDriverAgentHook>();
services.AddScoped<IConversationHook, SqlDriverConversationHook>();
services.AddScoped<IAgentUtilityHook, SqlUtilityHook>();
}