add execute template utility

This commit is contained in:
Jicheng Lu 2025-03-17 14:13:31 -05:00
parent 5d4dcc3e13
commit bcadc7e940
8 changed files with 122 additions and 4 deletions

View file

@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Instructs.Models;
public class ExecuteTemplateArgs
{
[JsonPropertyName("template_name")]
public string? TemplateName { get; set; }
}

View file

@ -90,6 +90,7 @@
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\templates\instruction.metrics.liquid" />
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\templates\instruction.reviewer.liquid" />
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\templates\instruction.simulator.liquid" />
<None Remove="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\templates\instruction.simulator.liquid" />
<None Remove="data\plugins\config.json" />
</ItemGroup>
@ -187,6 +188,12 @@
<Content Include="data\agents\dfd9b46d-d00c-40af-8a75-3fbdc2b89869\templates\instruction.metrics.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\util-instruct-execute_template.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\util-instruct-execute_template.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\plugins\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View file

@ -0,0 +1,69 @@
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Instructs.Models;
namespace BotSharp.Core.Instructs.Functions;
public class ExecuteTemplateFn : IFunctionCallback
{
public string Name => "util-instruct-execute_template";
private readonly IServiceProvider _services;
private readonly ILogger<ExecuteTemplateFn> _logger;
public ExecuteTemplateFn(
IServiceProvider services,
ILogger<ExecuteTemplateFn> logger)
{
_services = services;
_logger = logger;
}
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<ExecuteTemplateArgs>(message.FunctionArgs);
if (string.IsNullOrEmpty(args.TemplateName))
{
message.Content = $"Empty template name.";
return false;
}
var agentService = _services.GetRequiredService<IAgentService>();
var agent = await agentService.GetAgent(message.CurrentAgentId);
var template = agent.Templates.FirstOrDefault(x => x.Name.IsEqualTo(args.TemplateName));
if (template == null)
{
message.Content = $"Cannot find template ({args.TemplateName}) in agent {agent.Name}";
return false;
}
var prompt = agentService.RenderedTemplate(agent, args.TemplateName);
var response = await GetAiResponse(agent, prompt);
message.Content = response;
return true;
}
private async Task<string> GetAiResponse(Agent agent, string text)
{
try
{
var completion = CompletionProvider.GetChatCompletion(_services, provider: agent.LlmConfig?.Provider, model: agent.LlmConfig?.Model);
var response = await completion.GetChatCompletions(new Agent()
{
Id = agent.Id
},
new List<RoleDialogModel>
{
new(AgentRole.User, text)
});
return response.Content;
}
catch (Exception ex)
{
var error = $"Error when getting agent {agent.Name} instruction response.";
_logger.LogWarning($"{error} {ex.Message}\r\n{ex.InnerException}");
return error;
}
}
}

View file

@ -0,0 +1,17 @@
namespace BotSharp.Core.Instructs.Hooks;
public class InstructUtilityHook : IAgentUtilityHook
{
private static string PREFIX = "util-instruct-";
private static string EXECUTE_TEMPLATE = $"{PREFIX}execute_template";
public void AddUtilities(List<AgentUtility> utilities)
{
utilities.Add(new AgentUtility
{
Name = "instruct.template",
Functions = [new($"{EXECUTE_TEMPLATE}")],
Templates = [new($"{EXECUTE_TEMPLATE}.fn")]
});
}
}

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Instructs.Settings;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Settings;
using BotSharp.Core.Instructs.Hooks;
using Microsoft.Extensions.Configuration;
namespace BotSharp.Core.Instructs;
@ -18,6 +19,8 @@ public class InsturctionPlugin : IBotSharpPlugin
var settingService = provider.GetRequiredService<ISettingService>();
return settingService.Bind<InstructionSettings>("Instruction");
});
services.AddScoped<IAgentUtilityHook, InstructUtilityHook>();
}
public bool AttachMenu(List<PluginMenuDef> menu)

View file

@ -8,13 +8,11 @@ public class RoutingUtilityHook : IAgentUtilityHook
public void AddUtilities(List<AgentUtility> utilities)
{
var utility = new AgentUtility
utilities.Add(new AgentUtility
{
Name = "routing.tools",
Functions = [new($"{REDIRECT_TO_AGENT}"), new($"{FALLBACK_TO_ROUTER}")],
Templates = [new($"{REDIRECT_TO_AGENT}.fn"), new($"{FALLBACK_TO_ROUTER}.fn")]
};
utilities.Add(utility);
});
}
}

View file

@ -0,0 +1,14 @@
{
"name": "util-instruct-execute_template",
"description": "Select a specific template that can handle the user's request.",
"parameters": {
"type": "object",
"properties": {
"template_name": {
"type": "string",
"description": "The template name that is selected for handling the request."
}
},
"required": [ "template_name" ]
}
}

View file

@ -0,0 +1,3 @@
please call function util-routing-execute_template if user wants to use a template to fulfill a specific task.
Please ensure the template is executed only once.
Please output the template response directly without changing anthything.