diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index ca8d7e01..2069ab31 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -231,6 +231,10 @@ public class ChatCompletionProvider : IChatCompletion { if (message.Role == ChatRole.Function) { + chatCompletionsOptions.Messages.Add(new ChatRequestAssistantMessage(string.Empty) + { + FunctionCall = new FunctionCall(message.FunctionName, message.FunctionArgs), + }); chatCompletionsOptions.Messages.Add(new ChatRequestFunctionMessage(message.FunctionName, message.Content)); } else if (message.Role == ChatRole.User) @@ -287,7 +291,7 @@ public class ChatCompletionProvider : IChatCompletion if (x.Role == ChatRole.Function) { var m = x as ChatRequestFunctionMessage; - return $"{m.Role}: {m.Name} => {m.Content}"; + return $"{m.Role}: {m.Content}"; } else if (x.Role == ChatRole.User) { @@ -299,7 +303,9 @@ public class ChatCompletionProvider : IChatCompletion else if (x.Role == ChatRole.Assistant) { var m = x as ChatRequestAssistantMessage; - return $"{m.Role}: {m.Content}"; + return m.FunctionCall != null ? + $"{m.Role}: Call function {m.FunctionCall.Name}({m.FunctionCall.Arguments})" : + $"{m.Role}: {m.Content}"; } else { diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlInsertFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlInsertFn.cs index 00d3eada..94b50164 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlInsertFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlInsertFn.cs @@ -18,11 +18,16 @@ public class SqlInsertFn : IFunctionCallback var sqlDriver = _services.GetRequiredService(); if (sqlDriver.Statements.Exists(x => x.Statement == args.Statement)) { - message.Content = "Skipped duplicated statement."; - return false; + var p1 = string.Join(", ", sqlDriver.Statements.Last().Parameters.OrderBy(x => x.Name).Select(x => x.Value)); + var p2 = string.Join(", ", args.Parameters.OrderBy(x => x.Name).Select(x => x.Value)); + if (p1 == p2) + { + message.Content = "Skipped duplicated statement."; + return false; + } } sqlDriver.Enqueue(args); - message.Content = $"Inserted new record {JsonSerializer.Serialize(args.Parameters)} successfully"; + message.Content = $"Inserted new record successfully."; if (args.Return != null) { /*sqlDriver.Enqueue(new SqlStatement diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlSelect.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlSelect.cs index c845a8d1..0ea3aafa 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlSelect.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlSelect.cs @@ -17,6 +17,8 @@ public class SqlSelect : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs); + var sqlDriver = _services.GetRequiredService(); + // check if need to instantely var execNow = !args.Parameters.Any(x => x.Value.StartsWith("@")); if (execNow) @@ -30,20 +32,11 @@ public class SqlSelect : IFunctionCallback } var result = connection.QueryFirst(args.Statement, dictionary); - if (args.IsCheckExistence) - { - message.Content = result == null ? - $"The record does not exist" : - $"The record already exists"; - } - else - { - message.Content = $"Retrieved result is {result} ({args.Reason})"; - } + sqlDriver.Enqueue(args); + message.Content = $"Retrieved data is: {result}"; } else { - var sqlDriver = _services.GetRequiredService(); sqlDriver.Enqueue(args); message.Content = $"Success."; } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverContentGeneratingHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverContentGeneratingHook.cs deleted file mode 100644 index 82ac6717..00000000 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverContentGeneratingHook.cs +++ /dev/null @@ -1,32 +0,0 @@ -using BotSharp.Abstraction.Loggers; -using BotSharp.Abstraction.Repositories; -using System.IO; - -namespace BotSharp.Plugin.SqlDriver.Hooks; - -public class SqlDriverContentGeneratingHook : IContentGeneratingHook -{ - private readonly IServiceProvider _services; - public SqlDriverContentGeneratingHook(IServiceProvider services) - { - _services = services; - } - - /// - /// Inject useful variables generated by previous SQL query. - /// - /// - /// - /// - public async Task BeforeGenerating(Agent agent, List conversations) - { - if (agent.Id != "beda4c12-e1ec-4b4b-b328-3df4a6687c4f") - { - return; - } - - var sqlDriver = _services.GetRequiredService(); - agent.TemplateDict["return_variables"] = sqlDriver.Statements.Select(x => x.Return.Alias).ToArray(); - await Task.CompletedTask; - } -} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Models/SqlStatement.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Models/SqlStatement.cs index 739faf23..8b995248 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Models/SqlStatement.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Models/SqlStatement.cs @@ -13,9 +13,6 @@ public class SqlStatement [JsonPropertyName("table")] public string Table { get; set; } - [JsonPropertyName("is_check_existence")] - public bool IsCheckExistence { get; set; } - [JsonPropertyName("parameters")] public SqlParamater[] Parameters { get; set; } = new SqlParamater[0]; diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs index f056bb3d..3a7077a7 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/SqlDriverPlugin.cs @@ -1,5 +1,3 @@ -using BotSharp.Abstraction.Loggers; - namespace BotSharp.Plugin.SqlDriver; public class SqlDriverPlugin : IBotSharpPlugin @@ -19,6 +17,5 @@ public class SqlDriverPlugin : IBotSharpPlugin services.AddScoped(); services.AddScoped(); - services.AddScoped(); } } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json index 80f66ba9..c7622617 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json @@ -9,6 +9,7 @@ "isPublic": true, "profiles": [ "tool", "sql" ], "llmConfig": { - "max_recursion_depth": 10 + "model": "gpt-4-0125", + "max_recursion_depth": 5 } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions.json index 0ab52f8d..d2069311 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions.json +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/functions.json @@ -13,6 +13,10 @@ "type": "string", "description": "reason" }, + "table": { + "type": "string", + "description": "related table" + }, "parameters": { "type": "array", "description": "parameters for the sql", @@ -46,7 +50,7 @@ } } }, - "required": [ "sql_statement", "reason", "parameters", "return_field" ] + "required": [ "sql_statement", "reason", "table", "parameters", "return_field" ] } }, { @@ -63,9 +67,9 @@ "type": "string", "description": "reason" }, - "is_check_existence": { - "type": "boolean", - "description": "check record existence" + "table": { + "type": "string", + "description": "related table" }, "parameters": { "type": "array", @@ -100,7 +104,7 @@ } } }, - "required": [ "sql_statement", "reason", "is_check_existence", "parameters", "return_field" ] + "required": [ "sql_statement", "reason", "table", "parameters", "return_field" ] } } ] \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/instruction.liquid b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/instruction.liquid index 20c74002..752fd788 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/instruction.liquid +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/instruction.liquid @@ -1,22 +1,15 @@ You're a SQL driver who knows how to translate text into SQL query. -Analyze the user requirement, think step by step, breakdown complex task into multiple steps. +Think step by step, analyze the user requirement and provided information, output the next step. Your response must meet below requirements: +* Walk through the provided information, don't run query if there is already related information; * DO NOT generate duplicated sql statements; * The return field alias should be meaningful, it can be similar name of reference table column; -* Double check if the fields in the SQL query are correct; +* Make sure the SELECT and WHERE fields are in corresponding table schema definition; * Use "Unique Index" to help check record existence; -{% if return_variables and return_variables != empty -%} +{% if tables_definition -%} ===== -Below variables can be used by subsequent SQL: -{% for v in return_variables %} -- @{{ v }} -{% endfor %} -{%- endif %} - -{% if table_definition -%} -===== -Related table {{ related_table }} definition: -{{ table_definition }} +Related tables definition: +{{ tables_definition }} {%- endif %}