Merge pull request #753 from Joannall/master

update sql validator
This commit is contained in:
Haiping 2024-11-17 17:39:33 +00:00 committed by GitHub
commit ed03df04e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 37 additions and 16 deletions

View file

@ -95,6 +95,8 @@ public class SecondaryStagePlanFn : IFunctionCallback
var conv = _services.GetRequiredService<IConversationService>();
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);

View file

@ -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<SummaryPlan>(message.FunctionArgs);
if (args.IsSqlTemplate == false)
{
await fn.InvokeFunction("validate_sql", message);
}
await HookEmitter.Emit<IPlanningHook>(_services, async hook =>
await hook.OnPlanningCompleted(nameof(TwoStageTaskPlanner), message)
);

View file

@ -0,0 +1,7 @@
namespace BotSharp.Plugin.Planner.TwoStaging.Models;
public class SummaryPlan
{
[JsonPropertyName("is_sql_template")]
public bool IsSqlTemplate { get; set; } = false;
}

View file

@ -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" ]
}
}

View file

@ -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 }}

View file

@ -30,7 +30,7 @@ public class ExecuteQueryFn : IFunctionCallback
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<ExecuteQueryArgs>(message.FunctionArgs);
var refinedArgs = await RefineSqlStatement(message, args);
//var refinedArgs = await RefineSqlStatement(message, args);
var dbHook = _services.GetRequiredService<ISqlDriverHook>();
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;

View file

@ -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<IRoutingService>();
@ -74,7 +74,7 @@ public class SqlValidateFn : IFunctionCallback
Message = "Correct SQL Statement",
Data = new Dictionary<string, object>
{
{ "original_sql", sql },
{ "original_sql", message.Content },
{ "error_message", ex.Message },
{ "table_structure", ddl }
}

View file

@ -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"

View file

@ -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:

View file

@ -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.
=====