Function templating response.
This commit is contained in:
parent
9393508a46
commit
4dcb00ca83
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace BotSharp.Abstraction.Templating;
|
||||||
|
|
||||||
|
public interface IResponseTemplateService
|
||||||
|
{
|
||||||
|
Task<string> RenderFunctionResponse(string agentId, RoleDialogModel fn);
|
||||||
|
}
|
||||||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Abstraction.Templating;
|
||||||
|
|
||||||
public interface ITemplateRender
|
public interface ITemplateRender
|
||||||
{
|
{
|
||||||
bool Render(Agent agent, Dictionary<string, object> dict);
|
string Render(string template, Dictionary<string, object> dict);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@ global using System.Text;
|
||||||
global using System.Threading.Tasks;
|
global using System.Threading.Tasks;
|
||||||
global using System.ComponentModel.DataAnnotations;
|
global using System.ComponentModel.DataAnnotations;
|
||||||
global using BotSharp.Abstraction.Agents.Models;
|
global using BotSharp.Abstraction.Agents.Models;
|
||||||
|
global using BotSharp.Abstraction.Conversations.Models;
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using BotSharp.Abstraction.Agents.Models;
|
using BotSharp.Abstraction.Agents.Models;
|
||||||
|
using BotSharp.Abstraction.Templating;
|
||||||
using BotSharp.Core.Templating;
|
using BotSharp.Core.Templating;
|
||||||
|
|
||||||
namespace BotSharp.Core.Agents.Services;
|
namespace BotSharp.Core.Agents.Services;
|
||||||
|
|
@ -45,8 +46,8 @@ public partial class AgentService
|
||||||
}
|
}
|
||||||
|
|
||||||
// render liquid template
|
// render liquid template
|
||||||
var render = _services.GetRequiredService<TemplateRender>();
|
var render = _services.GetRequiredService<ITemplateRender>();
|
||||||
render.Render(agent, templateDict);
|
agent.Instruction = render.Render(agent.Instruction, templateDict);
|
||||||
|
|
||||||
_logger.LogInformation($"Loaded agent {agent}.");
|
_logger.LogInformation($"Loaded agent {agent}.");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using BotSharp.Core.Plugins.Knowledges.Services;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using BotSharp.Abstraction.Routing.Settings;
|
using BotSharp.Abstraction.Routing.Settings;
|
||||||
|
using BotSharp.Abstraction.Templating;
|
||||||
|
|
||||||
namespace BotSharp.Core;
|
namespace BotSharp.Core;
|
||||||
|
|
||||||
|
|
@ -42,7 +43,8 @@ public static class BotSharpServiceCollectionExtensions
|
||||||
RegisterPlugins(services, config);
|
RegisterPlugins(services, config);
|
||||||
|
|
||||||
// Register template render
|
// Register template render
|
||||||
services.AddSingleton<TemplateRender>();
|
services.AddSingleton<ITemplateRender, TemplateRender>();
|
||||||
|
services.AddScoped<IResponseTemplateService, ResponseTemplateService>();
|
||||||
|
|
||||||
// Register router
|
// Register router
|
||||||
var routingSettings = new RoutingSettings();
|
var routingSettings = new RoutingSettings();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@ using BotSharp.Abstraction.Agents.Enums;
|
||||||
using BotSharp.Abstraction.Agents.Models;
|
using BotSharp.Abstraction.Agents.Models;
|
||||||
using BotSharp.Abstraction.Conversations.Models;
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
using BotSharp.Abstraction.MLTasks;
|
using BotSharp.Abstraction.MLTasks;
|
||||||
|
using BotSharp.Abstraction.Templating;
|
||||||
|
using BotSharp.Core.Templating;
|
||||||
|
using System.IO;
|
||||||
|
using Tensorflow.Keras.Layers.Rnn;
|
||||||
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
|
||||||
namespace BotSharp.Core.Conversations.Services;
|
namespace BotSharp.Core.Conversations.Services;
|
||||||
|
|
||||||
|
|
@ -68,22 +73,48 @@ public partial class ConversationService
|
||||||
{
|
{
|
||||||
var agentService = _services.GetRequiredService<IAgentService>();
|
var agentService = _services.GetRequiredService<IAgentService>();
|
||||||
agent = await agentService.LoadAgent(fn.CurrentAgentId);
|
agent = await agentService.LoadAgent(fn.CurrentAgentId);
|
||||||
|
|
||||||
|
wholeDialogs.Add(fn);
|
||||||
|
|
||||||
|
await GetChatCompletionsAsyncRecursively(chatCompletion,
|
||||||
|
conversationId,
|
||||||
|
agent,
|
||||||
|
wholeDialogs,
|
||||||
|
onMessageReceived,
|
||||||
|
onFunctionExecuting,
|
||||||
|
onFunctionExecuted);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find response template
|
||||||
|
var templateService = _services.GetRequiredService<IResponseTemplateService>();
|
||||||
|
var response = await templateService.RenderFunctionResponse(agent.Id, fn);
|
||||||
|
if (!string.IsNullOrEmpty(response))
|
||||||
|
{
|
||||||
|
await HandleAssistantMessage(new RoleDialogModel(AgentRole.Assistant, response)
|
||||||
|
{
|
||||||
|
CurrentAgentId = agent.Id,
|
||||||
|
Channel = wholeDialogs.Last().Channel
|
||||||
|
}, onMessageReceived);
|
||||||
|
|
||||||
// Add to dialog history
|
return;
|
||||||
// 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
|
// Add to dialog history
|
||||||
wholeDialogs.Add(fn);
|
// The server had an error processing your request. Sorry about that!
|
||||||
|
// _storage.Append(conversationId, preAgentId, fn);
|
||||||
|
|
||||||
await GetChatCompletionsAsyncRecursively(chatCompletion,
|
// After function is executed, pass the result to LLM to get a natural response
|
||||||
conversationId,
|
wholeDialogs.Add(fn);
|
||||||
agent,
|
|
||||||
wholeDialogs,
|
await GetChatCompletionsAsyncRecursively(chatCompletion,
|
||||||
onMessageReceived,
|
conversationId,
|
||||||
onFunctionExecuting,
|
agent,
|
||||||
onFunctionExecuted);
|
wholeDialogs,
|
||||||
|
onMessageReceived,
|
||||||
|
onFunctionExecuting,
|
||||||
|
onFunctionExecuted);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
using BotSharp.Abstraction.Templating;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace BotSharp.Core.Templating;
|
||||||
|
|
||||||
|
public class ResponseTemplateService : IResponseTemplateService
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _services;
|
||||||
|
public ResponseTemplateService(IServiceProvider services)
|
||||||
|
{
|
||||||
|
_services = services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> RenderFunctionResponse(string agentId, RoleDialogModel fn)
|
||||||
|
{
|
||||||
|
// Find response template
|
||||||
|
var agentService = _services.GetRequiredService<IAgentService>();
|
||||||
|
var dir = Path.Combine(agentService.GetAgentDataDir(agentId), "responses");
|
||||||
|
var responses = Directory.GetFiles(dir)
|
||||||
|
.Where(f => f.Split(Path.DirectorySeparatorChar).Last().Split('.')[1] == fn.FunctionName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (responses.Count == 0)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomIndex = new Random().Next(0, responses.Count);
|
||||||
|
var template = File.ReadAllText(responses[randomIndex]);
|
||||||
|
|
||||||
|
var render = _services.GetRequiredService<ITemplateRender>();
|
||||||
|
|
||||||
|
// Convert args and execute data to dictionary
|
||||||
|
var dict = new Dictionary<string, object>();
|
||||||
|
ExtractArgs(JsonSerializer.Deserialize<JsonDocument>(fn.FunctionArgs), dict);
|
||||||
|
ExtractExecuteData(fn.ExecutionData, dict);
|
||||||
|
|
||||||
|
var text = render.Render(template, dict);
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractArgs(JsonDocument args, Dictionary<string, object> dict)
|
||||||
|
{
|
||||||
|
if (args.RootElement is JsonElement root)
|
||||||
|
{
|
||||||
|
foreach (JsonProperty property in root.EnumerateObject())
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(property.Value.ToString()))
|
||||||
|
{
|
||||||
|
dict[property.Name] = property.Value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExtractExecuteData(object data, Dictionary<string, object> dict)
|
||||||
|
{
|
||||||
|
foreach (PropertyInfo property in data.GetType().GetProperties())
|
||||||
|
{
|
||||||
|
var value = property.GetValue(data, null);
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
dict[property.Name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
using BotSharp.Abstraction.Agents.Models;
|
|
||||||
using BotSharp.Abstraction.Routing.Models;
|
using BotSharp.Abstraction.Routing.Models;
|
||||||
using BotSharp.Abstraction.Templating;
|
using BotSharp.Abstraction.Templating;
|
||||||
using Fluid;
|
using Fluid;
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace BotSharp.Core.Templating;
|
namespace BotSharp.Core.Templating;
|
||||||
|
|
||||||
|
|
@ -22,19 +20,18 @@ public class TemplateRender : ITemplateRender
|
||||||
_options.MemberAccessStrategy.Register<RoutingRecord>();
|
_options.MemberAccessStrategy.Register<RoutingRecord>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Render(Agent agent, Dictionary<string, object> dict)
|
public string Render(string template, Dictionary<string, object> dict)
|
||||||
{
|
{
|
||||||
var template = agent.Instruction;
|
|
||||||
if (_parser.TryParse(template, out var t, out var error))
|
if (_parser.TryParse(template, out var t, out var error))
|
||||||
{
|
{
|
||||||
var context = new TemplateContext(dict, _options);
|
var context = new TemplateContext(dict, _options);
|
||||||
agent.Instruction = t.Render(context);
|
template = t.Render(context);
|
||||||
return true;
|
return template;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
return false;
|
return template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@ global using BotSharp.Abstraction.Conversations;
|
||||||
global using BotSharp.Abstraction.Knowledges;
|
global using BotSharp.Abstraction.Knowledges;
|
||||||
global using BotSharp.Abstraction.Users;
|
global using BotSharp.Abstraction.Users;
|
||||||
global using BotSharp.Abstraction.Utilities;
|
global using BotSharp.Abstraction.Utilities;
|
||||||
|
global using BotSharp.Abstraction.Conversations.Models;
|
||||||
|
global using BotSharp.Abstraction.Agents.Settings;
|
||||||
|
global using BotSharp.Abstraction.Conversations.Settings;
|
||||||
global using BotSharp.Core.Repository;
|
global using BotSharp.Core.Repository;
|
||||||
global using BotSharp.Core.Repository.Abstraction;
|
global using BotSharp.Core.Repository.Abstraction;
|
||||||
global using BotSharp.Core.Repository.DbTables;
|
global using BotSharp.Core.Repository.DbTables;
|
||||||
|
|
@ -21,5 +24,3 @@ global using BotSharp.Core.Conversations.Services;
|
||||||
global using BotSharp.Core.Infrastructures;
|
global using BotSharp.Core.Infrastructures;
|
||||||
global using BotSharp.Core.Plugins;
|
global using BotSharp.Core.Plugins;
|
||||||
global using BotSharp.Core.Users.Services;
|
global using BotSharp.Core.Users.Services;
|
||||||
global using BotSharp.Abstraction.Agents.Settings;
|
|
||||||
global using BotSharp.Abstraction.Conversations.Settings;
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using BotSharp.Abstraction.Conversations.Models;
|
using BotSharp.Abstraction.Conversations.Models;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace BotSharp.Plugin.PizzaBot.Functions;
|
namespace BotSharp.Plugin.PizzaBot.Functions;
|
||||||
|
|
||||||
|
|
@ -8,6 +9,10 @@ public class GetPizzaPricesFn : IFunctionCallback
|
||||||
|
|
||||||
public async Task<bool> Execute(RoleDialogModel message)
|
public async Task<bool> Execute(RoleDialogModel message)
|
||||||
{
|
{
|
||||||
|
message.ExecutionData = new
|
||||||
|
{
|
||||||
|
cheese = "3.5"
|
||||||
|
};
|
||||||
message.ExecutionResult = "Pepperoni Pizza: $3.5/slice, Cheese Pizza: $2.5/slice, Margherita Pizza: $3.0/slice";
|
message.ExecutionResult = "Pepperoni Pizza: $3.5/slice, Cheese Pizza: $2.5/slice, Margherita Pizza: $3.0/slice";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue