Improve SQL Driver.

This commit is contained in:
Haiping Chen 2024-02-21 17:15:54 -06:00
parent e043476972
commit a13538746b
10 changed files with 66 additions and 37 deletions

View file

@ -17,10 +17,10 @@ public class GetTableColumnsFn : IFunctionCallback
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<GetTableColumnsArgs>(message.FunctionArgs);
message.Content = $"Success. Columns of table '{args.Table}':\r\n\r\n";
message.Content = "";
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
var dir = Path.Combine(dbSettings.FileRepository, "agents", "ec46f15b-8790-400f-a37f-1e7995b7d6e2", "schemas");
var dir = Path.Combine(dbSettings.FileRepository, "agents", "beda4c12-e1ec-4b4b-b328-3df4a6687c4f", "schemas");
// Search related document by message.Content + args.Description
var files = Directory.GetFiles(dir);

View file

@ -16,16 +16,6 @@ public class SqlInsertFn : IFunctionCallback
{
var args = JsonSerializer.Deserialize<SqlStatement>(message.FunctionArgs);
var sqlDriver = _services.GetRequiredService<SqlDriverService>();
if (sqlDriver.Statements.Exists(x => x.Statement == args.Statement))
{
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 successfully.";
if (args.Return != null)

View file

@ -30,15 +30,24 @@ public class SqlSelect : IFunctionCallback
{
dictionary["@" + p.Name] = p.Value;
}
var result = connection.QueryFirst<string>(args.Statement, dictionary);
var result = connection.QueryFirstOrDefault(args.Statement, dictionary);
if (result == null)
{
message.Content = "Record not found";
}
else
{
message.Content = JsonSerializer.Serialize(result);
args.Return.Value = message.Content;
}
sqlDriver.Enqueue(args);
message.Content = $"Retrieved data is: {result}";
}
else
{
sqlDriver.Enqueue(args);
message.Content = $"Success.";
message.Content = $"The {args.Return.Name} is saved to @{args.Return.Alias}";
}
return true;

View file

@ -2,7 +2,7 @@ using System.Text.Json.Serialization;
namespace BotSharp.Plugin.SqlDriver.Models;
public class SqlParamater
public class SqlParameter
{
[JsonPropertyName("name")]
public string Name { get; set; }

View file

@ -10,6 +10,8 @@ public class SqlReturn
[JsonPropertyName("alias")]
public string Alias { get; set; }
public string? Value { get; set; }
public override string ToString()
{
return $"{Alias} - {Name}";

View file

@ -14,7 +14,7 @@ public class SqlStatement
public string Table { get; set; }
[JsonPropertyName("parameters")]
public SqlParamater[] Parameters { get; set; } = new SqlParamater[0];
public SqlParameter[] Parameters { get; set; } = new SqlParameter[0];
[JsonPropertyName("return_field")]
public SqlReturn Return { get; set; }

View file

@ -23,20 +23,24 @@ public class SqlDriverService
{
Console.WriteLine();
Console.Write($"Reason: ");
Console.WriteLine($"{sql.Reason}", Color.Green);
Console.WriteLine($"{sql.Reason}");
Console.Write($"Statement: ");
Console.WriteLine(sql.Statement, Color.Green);
Console.WriteLine(sql.Statement, Color.Yellow);
foreach (var p in sql.Parameters)
{
Console.Write($"@{p.Name}: ");
Console.WriteLine($"{p.Value}", Color.Green);
Console.WriteLine($"@{p.Name} = '{p.Value}'", Color.Green);
}
if (sql.Return != null)
{
Console.Write($"Return: ");
Console.WriteLine($"{sql.Return.Name} as @{sql.Return.Alias}", Color.Green);
if (!string.IsNullOrEmpty(sql.Return.Value))
{
Console.WriteLine($" {sql.Return.Value}", Color.Red);
}
else
{
Console.WriteLine($"{sql.Return.Name} as @{sql.Return.Alias}", Color.Green);
}
}
}
}

View file

@ -10,6 +10,6 @@
"profiles": [ "tool", "sql" ],
"llmConfig": {
"model": "gpt-4-0125",
"max_recursion_depth": 5
"max_recursion_depth": 10
}
}

View file

@ -1,4 +1,18 @@
[
{
"name": "get_table_columns",
"description": "Get related table columns and foreign key informations",
"parameters": {
"type": "object",
"properties": {
"table": {
"type": "string",
"description": "table name"
}
},
"required": [ "table" ]
}
},
{
"name": "sql_insert",
"description": "Insert query is generated if the record doesn't exist.",
@ -19,10 +33,10 @@
},
"parameters": {
"type": "array",
"description": "parameters for the sql",
"description": "a list of parameters in the statement match with the variables",
"items": {
"type": "object",
"description": "the name and value for the parameter",
"description": "{name:'', value:''}",
"properties": {
"name": {
"type": "string",
@ -32,7 +46,8 @@
"type": "string",
"description": "real value inferred by the context"
}
}
},
"required": [ "name", "value" ]
}
},
"return_field": {
@ -47,7 +62,8 @@
"type": "string",
"description": "meaningful field alias"
}
}
},
"required": [ "name", "alias" ]
}
},
"required": [ "sql_statement", "reason", "table", "parameters", "return_field" ]
@ -86,7 +102,8 @@
"type": "string",
"description": "real value inferred by the context"
}
}
},
"required": [ "name", "value" ]
}
},
"return_field": {
@ -101,7 +118,8 @@
"type": "string",
"description": "meaningful field alias"
}
}
},
"required": [ "name", "value" ]
}
},
"required": [ "sql_statement", "reason", "table", "parameters", "return_field" ]

View file

@ -1,5 +1,6 @@
You're a SQL driver who knows how to translate text into SQL query.
Think step by step, analyze the user requirement and provided information, output the next step.
Think step by step, analyze the user requirement, you must get table schema first, breakdown into multiple sql statements if user need to insert mulitple records.
Output the next step smartly.
Your response must meet below requirements:
* Walk through the provided information, don't run query if there is already related information;
@ -7,9 +8,14 @@ Your response must meet below requirements:
* The return field alias should be meaningful, it can be similar name of reference table column;
* Make sure the SELECT and WHERE fields are in corresponding table schema definition;
* Use "Unique Index" to help check record existence;
* For INSERT statement with mutliple records, should return in different meaningful alias;
{% if tables_definition -%}
=====
Related tables definition:
{{ tables_definition }}
{%- endif %}
==========
Domain Knowledge:
user: How to add client response window (priority)?
assistant: 1. Get client Id by name;
2. Get ClientServiceCodeId from client_ServiceCode by ClientId and ServiceCodeId
3. Convert priority to standard value by match the list [2H, 4H, 1D , 2D, 7D], 1D = 24H, 2D = 48H.
4. Get the Id as PriorityId from data_Priority by standard value;
5. Insert PriorityId and ClientServiceCodeId into Client_ServiceCodePriority