diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs index f0972ccf..be780f51 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs @@ -95,6 +95,8 @@ public class SecondaryStagePlanFn : IFunctionCallback var conv = _services.GetRequiredService(); var wholeDialogs = conv.GetDialogHistory(); + wholeDialogs.Last().Content += "\r\nOutput in JSON format."; + var completion = CompletionProvider.GetChatCompletion(_services, provider: plannerAgent.LlmConfig.Provider, model: plannerAgent.LlmConfig.Model); diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs index 7b5134a0..2f5a1708 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs @@ -72,8 +72,12 @@ public class SummaryPlanFn : IFunctionCallback message.Content = summary.Content; // Validate the sql result - await fn.InvokeFunction("validate_sql", message); - + var args = JsonSerializer.Deserialize(message.FunctionArgs); + if (args.IsSqlTemplate == false) + { + await fn.InvokeFunction("validate_sql", message); + } + await HookEmitter.Emit(_services, async hook => await hook.OnPlanningCompleted(nameof(TwoStageTaskPlanner), message) ); diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SummaryPlan.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SummaryPlan.cs new file mode 100644 index 00000000..459237a8 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SummaryPlan.cs @@ -0,0 +1,7 @@ +namespace BotSharp.Plugin.Planner.TwoStaging.Models; + +public class SummaryPlan +{ + [JsonPropertyName("is_sql_template")] + public bool IsSqlTemplate { get; set; } = false; +} diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/functions/plan_summary.json b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/functions/plan_summary.json index 7e459503..c13bfb25 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/functions/plan_summary.json +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/functions/plan_summary.json @@ -4,6 +4,10 @@ "parameters": { "type": "object", "properties": { + "is_sql_template": { + "type": "boolean", + "description": "If user request is to generate sql template instead of actual sql statement." + }, "related_tables": { "type": "array", "description": "table name in planning steps", @@ -13,6 +17,6 @@ } } }, - "required": [ "related_tables" ] + "required": [ "related_tables", "is_sql_template" ] } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.summarize.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.summarize.liquid index a585cd23..c53abdab 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.summarize.liquid +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.summarize.liquid @@ -1,4 +1,4 @@ -You are a planning summarizer. You will generate the final output in JSON format based on the task description, knowledge and related table structure and relationship. +You are a planning summarizer. You will generate the final output in JSON format with short explanation based on the task description, knowledge and related table structure and relationship. Requirements: {{ summary_requirements }} diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs index af337bab..99060105 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/ExecuteQueryFn.cs @@ -30,7 +30,7 @@ public class ExecuteQueryFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs); - var refinedArgs = await RefineSqlStatement(message, args); + //var refinedArgs = await RefineSqlStatement(message, args); var dbHook = _services.GetRequiredService(); var dbType = dbHook.GetDatabaseType(message); @@ -38,13 +38,13 @@ public class ExecuteQueryFn : IFunctionCallback { var results = dbType.ToLower() switch { - "mysql" => RunQueryInMySql(refinedArgs.SqlStatements), - "sqlserver" => RunQueryInSqlServer(refinedArgs.SqlStatements), - "redshift" => RunQueryInRedshift(refinedArgs.SqlStatements), + "mysql" => RunQueryInMySql(args.SqlStatements), + "sqlserver" => RunQueryInSqlServer(args.SqlStatements), + "redshift" => RunQueryInRedshift(args.SqlStatements), _ => throw new NotImplementedException($"Database type {dbType} is not supported.") }; - if (refinedArgs.SqlStatements.Length == 1 && refinedArgs.SqlStatements[0].StartsWith("DROP TABLE")) + if (args.SqlStatements.Length == 1 && args.SqlStatements[0].StartsWith("DROP TABLE")) { message.Content = "Drop table successfully"; return true; diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs index a1c4dca9..5f33a74a 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs @@ -41,7 +41,7 @@ public class SqlValidateFn : IFunctionCallback var dbType = dbHook.GetDatabaseType(message); var validateSql = dbType.ToLower() switch { - "mysql" => $"explain\r\n{sql}", + "mysql" => $"explain\r\n{sql.Replace("SET ", "-- SET ", StringComparison.InvariantCultureIgnoreCase).Replace(";", "; explain ").TrimEnd("explain ".ToCharArray())}", "sqlserver" => $"SET PARSEONLY ON;\r\n{sql}\r\nSET PARSEONLY OFF;", "redshift" => $"explain\r\n{sql}", _ => throw new NotImplementedException($"Database type {dbType} is not supported.") @@ -49,7 +49,7 @@ public class SqlValidateFn : IFunctionCallback var msgCopy = RoleDialogModel.From(message); msgCopy.FunctionArgs = JsonSerializer.Serialize(new ExecuteQueryArgs { - SqlStatements = new string[] { validateSql } + SqlStatements = [validateSql] }); var fn = _services.GetRequiredService(); @@ -74,7 +74,7 @@ public class SqlValidateFn : IFunctionCallback Message = "Correct SQL Statement", Data = new Dictionary { - { "original_sql", sql }, + { "original_sql", message.Content }, { "error_message", ex.Message }, { "table_structure", ddl } } diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/verify_dictionary_term.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/verify_dictionary_term.json index 871210a2..64502c62 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/verify_dictionary_term.json +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/6745151e-6d46-4a02-8de4-1c4f21c7da95/functions/verify_dictionary_term.json @@ -1,6 +1,6 @@ { "name": "verify_dictionary_term", - "description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true and is_insert is false. You can only query one table at a time.", + "description": "Get id from dictionary table by keyword. Call this function only if need_lookup_dictionary is true, is_table_from_knowledge is true and is_insert is false. You can only query one table at a time. The table name must come from the global/domain knowledge.", "parameters": { "type": "object", "properties": { @@ -16,9 +16,13 @@ "type": "boolean", "description": "if SQL statement is inserting." }, + "is_table_from_knowledge": { + "type": "boolean", + "description": "if table is from the global/domain knowledge." + }, "tables": { "type": "array", - "description": "all related dictionary tables must be from related knowledge in the context", + "description": "all related dictionary tables must be from global/domain knowledge in the context", "items": { "type": "string", "description": "table name from related knowledge in the context" diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/database.summarize.mysql.liquid b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/database.summarize.mysql.liquid index 515deffd..1098bdd1 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/database.summarize.mysql.liquid +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/database.summarize.mysql.liquid @@ -4,7 +4,7 @@ If not, generate the query step by step based on the planning. The query must exactly based on the provided table structure. And carefully review the foreign keys to make sure you include all the accurate information. -Note: Output should be only the sql query with sql comments that can be directly run in mysql database with version 8.0. +Note: Output should be only the sql query with short sql comments and explanation that can be directly run in mysql database with version 8.0. Don't use the sql statement that specify target table for update in FROM clause. For example, you CAN'T write query as below: diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/sql_statement_correctness.liquid b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/sql_statement_correctness.liquid index 2e6f28e1..f180e19f 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/sql_statement_correctness.liquid +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/templates/sql_statement_correctness.liquid @@ -1,5 +1,5 @@ You are a sql statement corrector. You will need to refer to the table structure and rewrite the original sql statement so it's using the correct information, e.g. column name. -Output the sql statement only without comments, in JSON format: {{ response_format }} +Correct the sql statement and keep only the original explanation and comments without any information related to error message{% if response_format %} in JSON format: {{ response_format }} {% endif %}. Make sure all the column names are defined in the Table Structure. =====