diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index da864c607..4483bb2c2 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -1,4 +1,4 @@ - + $(TargetFramework) @@ -191,7 +191,6 @@ - diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs index 67c3f941e..cc3b568c6 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluatingService.cs @@ -65,14 +65,14 @@ public async Task Execute(string task, EvaluationRequest request) if (roundCount > 10) { - Console.WriteLine($"Conversation ended due to execced max round count {roundCount}", Color.Red); + Console.WriteLine($"Conversation ended due to execced max round count {roundCount}"); break; } if (response.FunctionName == "conversation_end" || response.FunctionName == "human_intervention_needed") { - Console.WriteLine($"Conversation ended by function {response.FunctionName}", Color.Green); + Console.WriteLine($"Conversation ended by function {response.FunctionName}"); break; } } diff --git a/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs index 1b883657a..2601940ef 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs @@ -67,7 +67,7 @@ public void Load(Action loaded, string? plugin = null) if (!_plugins.Any(x => x.Assembly == plugin)) { - Console.WriteLine($"Load dependent plugin {plugin} failed by {module.Name}.", Color.Red); + Console.WriteLine($"Load dependent plugin {plugin} failed by {module.Name}."); } } } @@ -79,7 +79,7 @@ public void Load(Action loaded, string? plugin = null) } else { - Console.WriteLine($"Can't find assemble {assemblyPath}.", Color.Red); + Console.WriteLine($"Can't find assemble {assemblyPath}."); } }); } @@ -101,7 +101,7 @@ private void InitModule(string assembly, IBotSharpPlugin module) AgentIds = module.AgentIds }); Console.Write($"Loaded plugin "); - Console.Write(name, Color.Green); + Console.Write(name); Console.WriteLine($" from {assembly}."); if (!string.IsNullOrEmpty(module.Description)) { @@ -258,7 +258,7 @@ public void Configure(IApplicationBuilder app) { if (_modules.Count == 0) { - Console.WriteLine($"No plugin loaded. Please check whether the Load() method is called.", Color.Yellow); + Console.WriteLine($"No plugin loaded. Please check whether the Load() method is called."); } _modules.ForEach(module => diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs index 60f3f3311..3b1f05668 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.HasMissingRequiredField.cs @@ -88,7 +88,7 @@ public partial class RoutingService message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", record.Name); agentId = routingRule.RedirectTo; #if DEBUG - Console.WriteLine($"*** Routing redirect to {record.Name.ToUpper()} ***", Color.Yellow); + Console.WriteLine($"*** Routing redirect to {record.Name.ToUpper()} ***"); #else logger.LogInformation($"*** Routing redirect to {record.Name.ToUpper()} ***"); #endif diff --git a/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj b/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj index f73fae8ff..75f0246a7 100644 --- a/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj +++ b/src/Plugins/BotSharp.Plugin.PaddleSharp/BotSharp.Plugin.PaddleSharp.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Plugins/BotSharp.Plugin.PaddleSharp/Providers/Pdf2TextConverter.cs b/src/Plugins/BotSharp.Plugin.PaddleSharp/Providers/Pdf2TextConverter.cs index 58f2015a5..a66cb8f94 100644 --- a/src/Plugins/BotSharp.Plugin.PaddleSharp/Providers/Pdf2TextConverter.cs +++ b/src/Plugins/BotSharp.Plugin.PaddleSharp/Providers/Pdf2TextConverter.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; -using System.Text; using System.IO; using ImageMagick; using OpenCvSharp; -using Microsoft.AspNetCore.Http; using Sdcb.PaddleInference; using Sdcb.PaddleOCR.Models; -using Sdcb.PaddleOCR.Models.LocalV3; using Sdcb.PaddleOCR; using System.Threading.Tasks; using BotSharp.Abstraction.Knowledges; diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj b/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj index 344458d4d..8d861d68c 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/BotSharp.Plugin.SqlDriver.csproj @@ -11,6 +11,8 @@ + + @@ -42,6 +44,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Enum/Utility.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Enum/Utility.cs new file mode 100644 index 000000000..380d9f519 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Enum/Utility.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Plugin.SqlDriver.Enum; + +public class Utility +{ + public const string SqlExecutor = "sql-executor"; +} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs index 1d2226db7..d6e2af4aa 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs @@ -1,12 +1,3 @@ -using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.Functions; -using BotSharp.Plugin.SqlDriver.Models; -using BotSharp.Plugin.SqlHero.Settings; -using Dapper; -using MySqlConnector; -using System.Text.Json; -using System.Threading.Tasks; - namespace BotSharp.Plugin.SqlDriver.Functions; public class ExecuteQueryFn : IFunctionCallback diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorHook.cs new file mode 100644 index 000000000..34da9ab58 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorHook.cs @@ -0,0 +1,84 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Settings; +using BotSharp.Abstraction.Functions.Models; +using BotSharp.Abstraction.Repositories; + +namespace BotSharp.Plugin.SqlDriver.Hooks; + +public class SqlExecutorHook : AgentHookBase, IAgentHook +{ + private const string SQL_EXECUTOR_TEMPLATE = "sql_executor.fn"; + private IEnumerable _targetSqlExecutorFunctions = new List + { + "sql_select" + }; + + public override string SelfId => string.Empty; + + public SqlExecutorHook(IServiceProvider services, AgentSettings settings) : base(services, settings) + { + } + + public override void OnAgentLoaded(Agent agent) + { + var conv = _services.GetRequiredService(); + var isConvMode = conv.IsConversationMode(); + var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.SqlExecutor); + + if (isConvMode && isEnabled) + { + var (prompt, fns) = GetPromptAndFunctions(); + if (!fns.IsNullOrEmpty()) + { + if (!string.IsNullOrWhiteSpace(prompt)) + { + agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n"; + } + + if (agent.Functions == null) + { + agent.Functions = fns; + } + else + { + agent.Functions.AddRange(fns); + } + } + } + + base.OnAgentLoaded(agent); + } + + private (string, List?) GetPromptAndFunctions() + { + var db = _services.GetRequiredService(); + var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant); + var fns = agent?.Functions?.Where(x => _targetSqlExecutorFunctions.Contains(x.Name))?.ToList(); + + var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(SQL_EXECUTOR_TEMPLATE))?.Content ?? string.Empty; + var dbType = GetDatabaseType(); + var render = _services.GetRequiredService(); + prompt = render.Render(prompt, new Dictionary + { + { "db_type", dbType } + }); + + return (prompt, fns); + } + + private string GetDatabaseType() + { + var settings = _services.GetRequiredService(); + var dbType = "MySQL"; + + if (!string.IsNullOrWhiteSpace(settings?.SqlServerConnectionString)) + { + dbType = "SQL Server"; + } + else if (!string.IsNullOrWhiteSpace(settings?.SqlLiteConnectionString)) + { + dbType = "SQL Lite"; + } + return dbType; + } +} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorUtilityHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorUtilityHook.cs new file mode 100644 index 000000000..47e0fedc9 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlExecutorUtilityHook.cs @@ -0,0 +1,9 @@ +namespace BotSharp.Plugin.SqlDriver.Hooks; + +public class SqlExecutorUtilityHook : IAgentUtilityHook +{ + public void AddUtilities(List utilities) + { + utilities.Add(Utility.SqlExecutor); + } +} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Services/SqlDriverService.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Services/SqlDriverService.cs index 0c36a1386..868f42a32 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Services/SqlDriverService.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Services/SqlDriverService.cs @@ -25,21 +25,21 @@ public void Enqueue(SqlStatement statement) Console.WriteLine($"{sql.Reason}"); - Console.WriteLine(sql.Statement, Color.Yellow); + Console.WriteLine(sql.Statement); foreach (var p in sql.Parameters) { - Console.WriteLine($"@{p.Name} = '{p.Value}'", Color.Green); + Console.WriteLine($"@{p.Name} = '{p.Value}'"); } if (sql.Return != null) { Console.Write($"Return: "); if (!string.IsNullOrEmpty(sql.Return.Value)) { - Console.WriteLine($" {sql.Return.Value}", Color.Red); + Console.WriteLine($" {sql.Return.Value}"); } else { - Console.WriteLine($"{sql.Return.Name} as @{sql.Return.Alias}", Color.Green); + Console.WriteLine($"{sql.Return.Name} as @{sql.Return.Alias}"); } } } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs index 8ccd22156..ed7a7fe1a 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs @@ -3,4 +3,6 @@ namespace BotSharp.Plugin.SqlHero.Settings; public class SqlDriverSetting { public string MySqlConnectionString { get; set; } + public string SqlServerConnectionString { get; set; } + public string SqlLiteConnectionString { get; set; } } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs index 3a7077a7b..aaad1a0fa 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs @@ -17,5 +17,7 @@ public void RegisterDI(IServiceCollection services, IConfiguration config) services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); } } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Using.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Using.cs index 75d7f8ed9..905c4f05d 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Using.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Using.cs @@ -19,5 +19,6 @@ global using BotSharp.Abstraction.Settings; global using BotSharp.Plugin.SqlDriver.Hooks; global using BotSharp.Plugin.SqlDriver.Services; +global using BotSharp.Plugin.SqlDriver.Enum; global using BotSharp.Plugin.SqlHero.Settings; global using System.Drawing; diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_select.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_select.json new file mode 100644 index 000000000..956af5efe --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/sql_select.json @@ -0,0 +1,56 @@ +{ + "name": "sql_select", + "description": "Get the specific value from table", + "parameters": { + "type": "object", + "properties": { + "sql_statement": { + "type": "string", + "description": "SQL statement with SELECT" + }, + "reason": { + "type": "string", + "description": "reason" + }, + "table": { + "type": "string", + "description": "related table" + }, + "parameters": { + "type": "array", + "description": "data criteria for the query", + "items": { + "type": "object", + "description": "the name and value for the parameter", + "properties": { + "name": { + "type": "string", + "description": "field name" + }, + "value": { + "type": "string", + "description": "real value inferred by the context" + } + }, + "required": [ "name", "value" ] + } + }, + "return_field": { + "type": "object", + "description": "the name and alias for the return field", + "properties": { + "name": { + "type": "string", + "description": "field in the table" + }, + "alias": { + "type": "string", + "description": "meaningful field alias" + } + }, + "required": [ "name", "value" ] + } + }, + "required": [ "sql_statement", "reason", "table", "parameters", "return_field" ] + } +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/sql_executor.fn.liquid b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/sql_executor.fn.liquid new file mode 100644 index 000000000..e8ac2a14e --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/templates/sql_executor.fn.liquid @@ -0,0 +1,5 @@ +You are connecting to {{ db_type }} database. Please generate SQL statements following {{ db_type }} rules. + +Please call function sql_select if user wants to get or retrieve data from data tables. +If there are any parameters, please add them in the WHERE clause, each of which starts with "@". +For example, SELECT * FROM table WHERE Id=@Id AND Name=@Name diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index efc8dbc86..275704ead 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -159,6 +159,12 @@ "Origin": "" }, + "SqlDriver": { + "MySqlConnectionString": "", + "SqlServerConnectionString": "", + "SqlLiteConnectionString": "" + }, + "Statistics": { "DataDir": "stats" },