BotSharp/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/VerifyDictionaryTerm.cs

134 lines
4.6 KiB
C#
Raw Normal View History

2024-02-22 19:37:14 +00:00
using BotSharp.Abstraction.Agents.Enums;
2024-09-30 20:14:37 +00:00
using BotSharp.Abstraction.Routing;
2024-02-22 19:37:14 +00:00
using BotSharp.Core.Infrastructures;
using BotSharp.Plugin.SqlDriver.Models;
using MySqlConnector;
using static Dapper.SqlMapper;
namespace BotSharp.Plugin.SqlDriver.Functions;
2024-10-17 18:16:31 +00:00
public class VerifyDictionaryTerm : IFunctionCallback
2024-02-22 19:37:14 +00:00
{
public string Name => "verify_dictionary_term";
2024-10-17 18:16:31 +00:00
public string Indication => "Verifying dictionary term";
2024-02-22 19:37:14 +00:00
private readonly IServiceProvider _services;
2024-10-17 18:16:31 +00:00
public VerifyDictionaryTerm(IServiceProvider services)
2024-02-22 19:37:14 +00:00
{
_services = services;
}
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<LookupDictionary>(message.FunctionArgs);
2024-09-30 20:14:37 +00:00
// get table DDL
var fn = _services.GetRequiredService<IRoutingService>();
var msgCopy = RoleDialogModel.From(message);
await fn.InvokeFunction("sql_table_definition", msgCopy);
// refine SQL
var agentService = _services.GetRequiredService<IAgentService>();
var currentAgent = await agentService.LoadAgent(message.CurrentAgentId);
var dictionarySqlPrompt = await GetDictionarySQLPrompt(args.SqlStatement, msgCopy.Content);
2024-09-30 23:25:32 +00:00
var agent = new Agent
2024-09-30 20:14:37 +00:00
{
2024-09-30 23:25:32 +00:00
Id = message.CurrentAgentId ?? string.Empty,
2024-09-30 20:14:37 +00:00
Name = "sqlDriver_DictionarySearch",
Instruction = dictionarySqlPrompt,
TemplateDict = new Dictionary<string, object>(),
LlmConfig = currentAgent.LlmConfig
};
2024-09-30 23:25:32 +00:00
var response = await GetAiResponse(agent);
2024-10-02 18:00:23 +00:00
args = response.Content.JsonContent<LookupDictionary>();
2024-09-30 20:14:37 +00:00
2024-09-24 15:45:57 +00:00
// check if need to instantely
2024-10-02 18:00:23 +00:00
IEnumerable<dynamic>? result = null;
if (!string.IsNullOrWhiteSpace(args.SqlStatement))
{
var settings = _services.GetRequiredService<SqlDriverSetting>();
using var connection = new MySqlConnection(settings.MySqlExecutionConnectionString);
result = connection.Query(args.SqlStatement);
}
2024-02-22 19:37:14 +00:00
2024-10-02 18:00:23 +00:00
if (result.IsNullOrEmpty())
2024-02-22 19:37:14 +00:00
{
2024-09-24 15:45:57 +00:00
message.Content = "Record not found";
}
else
2024-02-22 19:37:14 +00:00
{
2024-09-24 15:45:57 +00:00
message.Content = JsonSerializer.Serialize(result);
}
2024-09-30 23:25:32 +00:00
2024-09-24 15:45:57 +00:00
var states = _services.GetRequiredService<IConversationStateService>();
2024-10-01 06:18:11 +00:00
var dictionaryItems = states.GetState("dictionary_items", "");
2024-09-30 23:25:32 +00:00
var newItem = BuildDictionaryItem(args.Table, args.Reason, message.Content);
2024-10-01 06:18:11 +00:00
dictionaryItems += !string.IsNullOrWhiteSpace(newItem) ? $"\r\n{newItem}\r\n" : string.Empty;
states.SetState("dictionary_items", dictionaryItems);
2024-02-22 19:37:14 +00:00
return true;
}
2024-09-30 23:25:32 +00:00
2024-09-30 20:14:37 +00:00
private async Task<string> GetDictionarySQLPrompt(string originalSql, string tableStructure)
{
var agentService = _services.GetRequiredService<IAgentService>();
var render = _services.GetRequiredService<ITemplateRender>();
var knowledgeHooks = _services.GetServices<IKnowledgeHook>();
2024-11-06 22:03:16 +00:00
var agent = await agentService.GetAgent(BuiltInAgentId.SqlDriver);
2024-09-30 20:14:37 +00:00
var template = agent.Templates.FirstOrDefault(x => x.Name == "database.dictionary.sql")?.Content ?? string.Empty;
var responseFormat = JsonSerializer.Serialize(new LookupDictionary{ });
return render.Render(template, new Dictionary<string, object>
{
{ "original_sql", originalSql },
{ "table_structure", tableStructure },
{ "response_format", responseFormat }
});
}
2024-09-30 23:25:32 +00:00
private async Task<RoleDialogModel> GetAiResponse(Agent agent)
2024-09-30 20:14:37 +00:00
{
var text = "Check and correct the SQL statement.";
var message = new RoleDialogModel(AgentRole.User, text);
var completion = CompletionProvider.GetChatCompletion(_services,
2024-09-30 23:25:32 +00:00
provider: agent.LlmConfig.Provider,
model: agent.LlmConfig.Model);
return await completion.GetChatCompletions(agent, new List<RoleDialogModel> { message });
}
private string BuildDictionaryItem(string? table, string? reason, string? result)
{
2024-10-01 06:18:11 +00:00
var res = string.Empty;
2024-09-30 23:25:32 +00:00
if (!string.IsNullOrWhiteSpace(table))
{
2024-10-01 06:18:11 +00:00
res += $"Table: {table}";
2024-09-30 23:25:32 +00:00
}
if (!string.IsNullOrWhiteSpace(reason))
{
2024-10-01 06:18:11 +00:00
if (!string.IsNullOrWhiteSpace(res))
{
res += "\r\n";
}
res += $"Reason: {reason}";
2024-09-30 23:25:32 +00:00
}
if (!string.IsNullOrWhiteSpace(result))
{
2024-10-01 06:18:11 +00:00
if (!string.IsNullOrWhiteSpace(res))
{
res += "\r\n";
}
res += $"Result: {result}";
2024-09-30 23:25:32 +00:00
}
2024-10-01 06:18:11 +00:00
return res;
2024-09-30 20:14:37 +00:00
}
2024-02-22 19:37:14 +00:00
}