From 122f18fe1a0305021e126a32b1690e5ccc95d7e0 Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Sat, 18 Jan 2025 04:06:51 +0000 Subject: [PATCH] clean code of sql planner --- .../BotSharp.Plugin.Planner.csproj | 12 +- .../BotSharp.Plugin.Planner/PlannerPlugin.cs | 6 +- .../Functions/SqlGenerationFn.cs | 15 +-- .../Functions/SqlPrimaryStageFn.cs | 105 +++++++++++++++++ .../SqlGeneration/Functions/SqlReviewFn.cs | 6 +- .../Functions/SqlSecondaryStageFn.cs | 106 ++++++++++++++++++ .../Hooks/SqlPlannerAgentHook.cs} | 10 +- .../Models/PrimaryRequirementRequest.cs | 13 --- .../Models/SecondaryBreakdownTask.cs | 13 --- ...rstStagePlan.cs => SqlPrimaryStagePlan.cs} | 14 +-- ...condStagePlan.cs => SqlSecondStagePlan.cs} | 8 +- .../SqlGeneration/SqlGenerationPlanner.cs | 4 +- .../Functions/PrimaryStagePlanFn.cs | 2 +- .../Functions/SecondaryStagePlanFn.cs | 2 +- .../Functions/SummaryPlanFn.cs | 3 +- .../Hooks/TwoStagingPlannerUtilityHook.cs} | 4 +- src/Plugins/BotSharp.Plugin.Planner/Using.cs | 1 - ...mary_stage.json => sql_primary_stage.json} | 2 +- ...ry_stage.json => sql_secondary_stage.json} | 2 +- .../instructions/instruction.liquid | 6 +- ...summarize.liquid => sql.generation.liquid} | 0 ...{two_stage.next.liquid => sql.next.liquid} | 0 ...st.plan.liquid => sql.primary.plan.liquid} | 4 +- ....plan.liquid => sql.secondary.plan.liquid} | 0 .../Functions/SqlValidateFn.cs | 1 + .../Hooks/SqlDriverPlanningHook.cs | 29 ++--- 26 files changed, 265 insertions(+), 103 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs create mode 100644 src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlSecondaryStageFn.cs rename src/Plugins/BotSharp.Plugin.Planner/{Hooks/PlannerAgentHook.cs => SqlGeneration/Hooks/SqlPlannerAgentHook.cs} (66%) delete mode 100644 src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/PrimaryRequirementRequest.cs delete mode 100644 src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondaryBreakdownTask.cs rename src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/{FirstStagePlan.cs => SqlPrimaryStagePlan.cs} (65%) rename src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/{SecondStagePlan.cs => SqlSecondStagePlan.cs} (61%) rename src/Plugins/BotSharp.Plugin.Planner/{ => TwoStaging}/Functions/PrimaryStagePlanFn.cs (98%) rename src/Plugins/BotSharp.Plugin.Planner/{ => TwoStaging}/Functions/SecondaryStagePlanFn.cs (98%) rename src/Plugins/BotSharp.Plugin.Planner/{ => TwoStaging}/Functions/SummaryPlanFn.cs (98%) rename src/Plugins/BotSharp.Plugin.Planner/{Hooks/PlannerUtilityHook.cs => TwoStaging/Hooks/TwoStagingPlannerUtilityHook.cs} (86%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/{plan_primary_stage.json => sql_primary_stage.json} (98%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/{plan_secondary_stage.json => sql_secondary_stage.json} (94%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/{two_stage.summarize.liquid => sql.generation.liquid} (100%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/{two_stage.next.liquid => sql.next.liquid} (100%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/{two_stage.1st.plan.liquid => sql.primary.plan.liquid} (96%) rename src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/{two_stage.2nd.plan.liquid => sql.secondary.plan.liquid} (100%) diff --git a/src/Plugins/BotSharp.Plugin.Planner/BotSharp.Plugin.Planner.csproj b/src/Plugins/BotSharp.Plugin.Planner/BotSharp.Plugin.Planner.csproj index 886964b5..a6246cb0 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/BotSharp.Plugin.Planner.csproj +++ b/src/Plugins/BotSharp.Plugin.Planner/BotSharp.Plugin.Planner.csproj @@ -72,10 +72,10 @@ PreserveNewest - + PreserveNewest - + PreserveNewest @@ -87,16 +87,16 @@ PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest diff --git a/src/Plugins/BotSharp.Plugin.Planner/PlannerPlugin.cs b/src/Plugins/BotSharp.Plugin.Planner/PlannerPlugin.cs index 9ece599f..03b30ceb 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/PlannerPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/PlannerPlugin.cs @@ -1,6 +1,8 @@ using BotSharp.Plugin.Planner.Sequential; using BotSharp.Plugin.Planner.SqlGeneration; +using BotSharp.Plugin.Planner.SqlGeneration.Hooks; using BotSharp.Plugin.Planner.TwoStaging; +using BotSharp.Plugin.Planner.TwoStaging.Hooks; namespace BotSharp.Plugin.Planner; @@ -26,7 +28,7 @@ public class PlannerPlugin : IBotSharpPlugin services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); + services.AddScoped(); } } diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs index e89f533a..4965a67c 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlGenerationFn.cs @@ -1,3 +1,4 @@ +using BotSharp.Plugin.Planner.SqlGeneration; using BotSharp.Plugin.Planner.TwoStaging; using BotSharp.Plugin.Planner.TwoStaging.Models; @@ -54,12 +55,12 @@ public class SqlGenerationFn : IFunctionCallback states.SetState("table_ddls", ddlStatements); // Summarize and generate query - var prompt = await GetSummaryPlanPrompt(msgCopy, taskRequirement, domainKnowledge, dictionaryItems, ddlStatements, excelImportResult); - _logger.LogInformation($"Summary plan prompt:\r\n{prompt}"); + var prompt = await GetSqlGenerationPrompt(msgCopy, taskRequirement, domainKnowledge, dictionaryItems, ddlStatements, excelImportResult); + _logger.LogInformation($"SQL Generation plan prompt:\r\n{prompt}"); var plannerAgent = new Agent { - Id = PlannerAgentId.TwoStagePlanner, + Id = PlannerAgentId.SqlPlanner, Name = Name, Instruction = prompt, LlmConfig = currentAgent.LlmConfig @@ -75,19 +76,19 @@ public class SqlGenerationFn : IFunctionCallback return true; } - private async Task GetSummaryPlanPrompt(RoleDialogModel message, string taskDescription, string domainKnowledge, string dictionaryItems, string ddlStatement, string excelImportResult) + private async Task GetSqlGenerationPrompt(RoleDialogModel message, string taskDescription, string domainKnowledge, string dictionaryItems, string ddlStatement, string excelImportResult) { var agentService = _services.GetRequiredService(); var render = _services.GetRequiredService(); var knowledgeHooks = _services.GetServices(); - var agent = await agentService.GetAgent(PlannerAgentId.TwoStagePlanner); - var template = agent.Templates.FirstOrDefault(x => x.Name == "two_stage.summarize")?.Content ?? string.Empty; + var agent = await agentService.GetAgent(PlannerAgentId.SqlPlanner); + var template = agent.Templates.FirstOrDefault(x => x.Name == "sql.generation")?.Content ?? string.Empty; var additionalRequirements = new List(); await HookEmitter.Emit(_services, async x => { - var requirement = await x.GetSummaryAdditionalRequirements(nameof(TwoStageTaskPlanner), message); + var requirement = await x.GetSummaryAdditionalRequirements(nameof(SqlGenerationPlanner), message); additionalRequirements.Add(requirement); }); diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs new file mode 100644 index 00000000..a8f2e362 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlPrimaryStageFn.cs @@ -0,0 +1,105 @@ +using BotSharp.Plugin.Planner.TwoStaging.Models; + +namespace BotSharp.Plugin.Planner.SqlGeneration.Functions; + +public class SqlPrimaryStageFn : IFunctionCallback +{ + public string Name => "sql_primary_stage"; + public string Indication => "Currently analyzing and breaking down user requirements."; + + private readonly IServiceProvider _services; + private readonly ILogger _logger; + + public SqlPrimaryStageFn( + IServiceProvider services, + ILogger logger) + { + _services = services; + _logger = logger; + } + + public async Task Execute(RoleDialogModel message) + { + var agentService = _services.GetRequiredService(); + var state = _services.GetRequiredService(); + + state.SetState("max_tokens", "4096"); + var task = JsonSerializer.Deserialize(message.FunctionArgs); + var searchQuestions = new List(task.Questions); + searchQuestions.AddRange(task.NormQuestions); + searchQuestions = searchQuestions.Distinct().ToList(); + + // Get knowledge from vectordb + var hooks = _services.GetServices(); + var knowledges = new List(); + foreach (var question in searchQuestions) + { + foreach (var hook in hooks) + { + var k = await hook.GetDomainKnowledges(message, question); + knowledges.AddRange(k); + } + } + knowledges = knowledges.Distinct().ToList(); + var knowledgeState = string.Join("\r\n", knowledges); + state.SetState("domain_knowledges", knowledgeState); + + // Get first stage planning prompt + var currentAgent = await agentService.LoadAgent(message.CurrentAgentId); + var prompt = await GetPrimaryStagePlanPrompt(message, task.Requirements, knowledges); + var plannerAgent = new Agent + { + Id = message.CurrentAgentId, + Name = Name, + Instruction = prompt, + TemplateDict = new Dictionary(), + LlmConfig = currentAgent.LlmConfig + }; + var response = await GetAiResponse(plannerAgent); + message.Content = response.Content; + + var states = _services.GetRequiredService(); + states.SetState("planning_result", response.Content); + + return true; + } + + private async Task GetPrimaryStagePlanPrompt(RoleDialogModel message, string taskDescription, List domainKnowledges) + { + var agentService = _services.GetRequiredService(); + var render = _services.GetRequiredService(); + var knowledgeHooks = _services.GetServices(); + + var agent = await agentService.GetAgent(PlannerAgentId.SqlPlanner); + var template = agent.Templates.FirstOrDefault(x => x.Name == "sql.primary.plan")?.Content ?? string.Empty; + var responseFormat = JsonSerializer.Serialize(new FirstStagePlan { }); + + // Get global knowledges + var globalKnowledges = new List(); + foreach (var hook in knowledgeHooks) + { + var k = await hook.GetGlobalKnowledges(message); + globalKnowledges.AddRange(k); + } + + return render.Render(template, new Dictionary + { + { "task_description", taskDescription }, + { "global_knowledges", globalKnowledges }, + { "domain_knowledges", domainKnowledges }, + { "response_format", responseFormat } + }); + } + + private async Task GetAiResponse(Agent plannerAgent) + { + var conv = _services.GetRequiredService(); + var wholeDialogs = conv.GetDialogHistory(); + + var completion = CompletionProvider.GetChatCompletion(_services, + provider: plannerAgent.LlmConfig.Provider, + model: plannerAgent.LlmConfig.Model); + + return await completion.GetChatCompletions(plannerAgent, wholeDialogs); + } +} diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlReviewFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlReviewFn.cs index 7c14d5f4..6996fb6d 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlReviewFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlReviewFn.cs @@ -1,6 +1,4 @@ using BotSharp.Plugin.Planner.SqlGeneration.Models; -using BotSharp.Plugin.Planner.TwoStaging; -using BotSharp.Plugin.Planner.TwoStaging.Models; namespace BotSharp.Plugin.Planner.SqlGeneration.Functions; @@ -23,14 +21,16 @@ public class SqlReviewFn : IFunctionCallback public async Task Execute(RoleDialogModel message) { var args = JsonSerializer.Deserialize(message.FunctionArgs); + if (!message.Content.StartsWith("```sql")) { message.Content = $"```sql\r\n{args.SqlStatement}\r\n```"; } + if (args != null && !args.IsSqlTemplate && args.ContainsSqlStatements) { await HookEmitter.Emit(_services, async hook => - await hook.OnSourceCodeGenerated(nameof(TwoStageTaskPlanner), message, "sql") + await hook.OnSourceCodeGenerated(nameof(SqlGenerationPlanner), message, "sql") ); } return true; diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlSecondaryStageFn.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlSecondaryStageFn.cs new file mode 100644 index 00000000..4ab6a766 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Functions/SqlSecondaryStageFn.cs @@ -0,0 +1,106 @@ +using BotSharp.Plugin.Planner.TwoStaging.Models; + +namespace BotSharp.Plugin.Planner.SqlGeneration.Functions; + +public class SqlSecondaryStageFn : IFunctionCallback +{ + public string Name => "sql_secondary_stage"; + public string Indication => "Further analyzing and breaking down user sub-needs."; + + private readonly IServiceProvider _services; + private readonly ILogger _logger; + + public SqlSecondaryStageFn( + IServiceProvider services, + ILogger logger) + { + _services = services; + _logger = logger; + } + + public async Task Execute(RoleDialogModel message) + { + var agentService = _services.GetRequiredService(); + var knowledgeService = _services.GetRequiredService(); + var knowledgeSettings = _services.GetRequiredService(); + var states = _services.GetRequiredService(); + + var msgSecondary = RoleDialogModel.From(message); + var collectionName = knowledgeSettings.Default.CollectionName; + var planResult = states.GetState("planning_result"); + + var taskSecondary = JsonSerializer.Deserialize(msgSecondary.FunctionArgs); + + // Search knowledgebase + var hooks = _services.GetServices(); + var knowledges = new List(); + foreach (var hook in hooks) + { + var k = await hook.GetDomainKnowledges(message, taskSecondary.SolutionQuestion); + knowledges.AddRange(k); + } + knowledges = knowledges.Distinct().ToList(); + var knowledgeResults = string.Join("\r\n\r\n=====\r\n", knowledges); + + var knowledgeState = states.GetState("domain_knowledges"); + knowledgeState += string.Join("\r\n", knowledges); + states.SetState("domain_knowledges", knowledgeState); + + // Get second stage planning prompt + var currentAgent = await agentService.LoadAgent(message.CurrentAgentId); + var prompt = await GetSecondStagePlanPrompt(taskSecondary.TaskDescription, planResult, knowledgeResults, message); + _logger.LogInformation(prompt); + + var plannerAgent = new Agent + { + Id = PlannerAgentId.SqlPlanner, + Name = Name, + Instruction = prompt, + TemplateDict = new Dictionary(), + LlmConfig = currentAgent.LlmConfig + }; + + var response = await GetAiResponse(plannerAgent); + message.Content = response.Content; + _logger.LogInformation(response.Content); + + states.SetState("planning_result", response.Content); + return true; + } + + private async Task GetSecondStagePlanPrompt(string taskDescription, string planResult, string knowledgeResults, RoleDialogModel message) + { + var agentService = _services.GetRequiredService(); + var render = _services.GetRequiredService(); + + var agent = await agentService.GetAgent(message.CurrentAgentId); + var template = agent.Templates.FirstOrDefault(x => x.Name == "sql.secondary.plan")?.Content ?? string.Empty; + var responseFormat = JsonSerializer.Serialize(new SecondStagePlan + { + Parameters = [JsonDocument.Parse("{}")], + Results = [string.Empty] + }); + + return render.Render(template, new Dictionary + { + { "task_description", taskDescription }, + { "primary_plan", planResult }, + { "additional_knowledge", knowledgeResults }, + { "response_format", responseFormat } + }); + } + + private async Task GetAiResponse(Agent plannerAgent) + { + 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); + + return await completion.GetChatCompletions(plannerAgent, wholeDialogs); + } +} diff --git a/src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerAgentHook.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Hooks/SqlPlannerAgentHook.cs similarity index 66% rename from src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerAgentHook.cs rename to src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Hooks/SqlPlannerAgentHook.cs index 8c6f2635..64645eac 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerAgentHook.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Hooks/SqlPlannerAgentHook.cs @@ -1,10 +1,10 @@ -namespace BotSharp.Plugin.Planner.Hooks; +namespace BotSharp.Plugin.Planner.SqlGeneration.Hooks; -public class PlannerAgentHook : AgentHookBase +public class SqlPlannerAgentHook : AgentHookBase { - public override string SelfId => PlannerAgentId.TwoStagePlanner; + public override string SelfId => PlannerAgentId.SqlPlanner; - public PlannerAgentHook(IServiceProvider services, AgentSettings settings) + public SqlPlannerAgentHook(IServiceProvider services, AgentSettings settings) : base(services, settings) { } @@ -19,7 +19,7 @@ public class PlannerAgentHook : AgentHookBase { var k = hook.GetGlobalKnowledges(new RoleDialogModel(AgentRole.User, template) { - CurrentAgentId = PlannerAgentId.TwoStagePlanner + CurrentAgentId = PlannerAgentId.SqlPlanner }).Result; Knowledges.AddRange(k); } diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/PrimaryRequirementRequest.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/PrimaryRequirementRequest.cs deleted file mode 100644 index 6a15faba..00000000 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/PrimaryRequirementRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace BotSharp.Plugin.Planner.SqlGeneration.Models; - -public class PrimaryRequirementRequest -{ - [JsonPropertyName("requirement_detail")] - public string Requirements { get; set; } = null!; - - [JsonPropertyName("questions")] - public string[] Questions { get; set; } = []; - - [JsonPropertyName("norm_questions")] - public string[] NormQuestions { get; set; } = []; -} diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondaryBreakdownTask.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondaryBreakdownTask.cs deleted file mode 100644 index 671c6353..00000000 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondaryBreakdownTask.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace BotSharp.Plugin.Planner.SqlGeneration.Models; - -public class SecondaryBreakdownTask -{ - [JsonPropertyName("task_description")] - public string TaskDescription { get; set; } = null!; - - [JsonPropertyName("solution_search_question")] - public string SolutionQuestion { get; set; } = null!; - - [JsonPropertyName("need_lookup_dictionary")] - public bool NeedLookupDictionary { get; set; } -} diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/FirstStagePlan.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlPrimaryStagePlan.cs similarity index 65% rename from src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/FirstStagePlan.cs rename to src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlPrimaryStagePlan.cs index 17ca9f0e..231f312f 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/FirstStagePlan.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlPrimaryStagePlan.cs @@ -1,13 +1,10 @@ namespace BotSharp.Plugin.Planner.SqlGeneration.Models; -public class FirstStagePlan +public class SqlPrimaryStagePlan { [JsonPropertyName("task_detail")] public string Task { get; set; } = ""; - //[JsonPropertyName("reason")] - //public string Reason { get; set; } = ""; - [JsonPropertyName("step")] public int Step { get; set; } = -1; @@ -23,15 +20,6 @@ public class FirstStagePlan [JsonPropertyName("has_found_relevant_knowledge")] public bool HasFoundRelevantKnowledge { get; set; } = false; - //[JsonPropertyName("related_urls")] - //public string[] Urls { get; set; } = []; - - //[JsonPropertyName("input_args")] - //public JsonDocument[] Parameters { get; set; } = []; - - //[JsonPropertyName("output_results")] - //public string[] Results { get; set; } = []; - public override string ToString() { return $"STEP {Step}: {Task}"; diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondStagePlan.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlSecondStagePlan.cs similarity index 61% rename from src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondStagePlan.cs rename to src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlSecondStagePlan.cs index 49f78f23..93e7bf57 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SecondStagePlan.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Models/SqlSecondStagePlan.cs @@ -1,6 +1,6 @@ namespace BotSharp.Plugin.Planner.SqlGeneration.Models; -public class SecondStagePlan +public class SqlSecondStagePlan { [JsonPropertyName("related_tables")] public string[] Tables { get; set; } = []; @@ -10,10 +10,4 @@ public class SecondStagePlan [JsonPropertyName("description")] public string Description { get; set; } = ""; - - [JsonPropertyName("input_args")] - public JsonDocument[] Parameters { get; set; } = []; - - [JsonPropertyName("output_results")] - public string[] Results { get; set; } = []; } diff --git a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs index 52571578..62340e9c 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/SqlGenerationPlanner.cs @@ -94,8 +94,8 @@ public class SqlGenerationPlanner : ITaskPlanner private async Task GetNextStepPrompt(Agent router) { var agentService = _services.GetRequiredService(); - var planner = await agentService.LoadAgent(PlannerAgentId.TwoStagePlanner); - var template = planner.Templates.First(x => x.Name == "two_stage.next").Content; + var planner = await agentService.LoadAgent(PlannerAgentId.SqlPlanner); + var template = planner.Templates.First(x => x.Name == "sql.next").Content; var states = _services.GetRequiredService(); var render = _services.GetRequiredService(); return render.Render(template, new Dictionary diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs similarity index 98% rename from src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs rename to src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs index fa1b7166..561b9977 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/PrimaryStagePlanFn.cs @@ -1,6 +1,6 @@ using BotSharp.Plugin.Planner.TwoStaging.Models; -namespace BotSharp.Plugin.Planner.Functions; +namespace BotSharp.Plugin.Planner.TwoStaging.Functions; public class PrimaryStagePlanFn : IFunctionCallback { diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SecondaryStagePlanFn.cs similarity index 98% rename from src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs rename to src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SecondaryStagePlanFn.cs index 5044139c..208a15d9 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SecondaryStagePlanFn.cs @@ -1,6 +1,6 @@ using BotSharp.Plugin.Planner.TwoStaging.Models; -namespace BotSharp.Plugin.Planner.Functions; +namespace BotSharp.Plugin.Planner.TwoStaging.Functions; public class SecondaryStagePlanFn : IFunctionCallback { diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs similarity index 98% rename from src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs rename to src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs index b89bcc35..465f1df2 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/SummaryPlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Functions/SummaryPlanFn.cs @@ -1,7 +1,6 @@ -using BotSharp.Plugin.Planner.TwoStaging; using BotSharp.Plugin.Planner.TwoStaging.Models; -namespace BotSharp.Plugin.Planner.Functions; +namespace BotSharp.Plugin.Planner.TwoStaging.Functions; public class SummaryPlanFn : IFunctionCallback { diff --git a/src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerUtilityHook.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Hooks/TwoStagingPlannerUtilityHook.cs similarity index 86% rename from src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerUtilityHook.cs rename to src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Hooks/TwoStagingPlannerUtilityHook.cs index b10d02ac..80dfad57 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Hooks/PlannerUtilityHook.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Hooks/TwoStagingPlannerUtilityHook.cs @@ -1,6 +1,6 @@ -namespace BotSharp.Plugin.Planner.Hooks; +namespace BotSharp.Plugin.Planner.TwoStaging.Hooks; -public class PlannerUtilityHook : IAgentUtilityHook +public class TwoStagingPlannerUtilityHook : IAgentUtilityHook { private const string PRIMARY_STAGE_FN = "plan_primary_stage"; private const string SECONDARY_STAGE_FN = "plan_secondary_stage"; diff --git a/src/Plugins/BotSharp.Plugin.Planner/Using.cs b/src/Plugins/BotSharp.Plugin.Planner/Using.cs index 50db1596..9f295f94 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Using.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/Using.cs @@ -32,5 +32,4 @@ global using BotSharp.Abstraction.Routing.Models; global using BotSharp.Core.Infrastructures; global using BotSharp.Core.Routing.Reasoning; -global using BotSharp.Plugin.Planner.Hooks; global using BotSharp.Plugin.Planner.Enums; diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_primary_stage.json b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_primary_stage.json similarity index 98% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_primary_stage.json rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_primary_stage.json index 5fefe691..31b5bfdc 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_primary_stage.json +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_primary_stage.json @@ -1,5 +1,5 @@ { - "name": "plan_primary_stage", + "name": "sql_primary_stage", "description": "Plan the high level steps to finish the task", "parameters": { "type": "object", diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_secondary_stage.json b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_secondary_stage.json similarity index 94% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_secondary_stage.json rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_secondary_stage.json index ca6b3d0b..0f7d5171 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/plan_secondary_stage.json +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/functions/sql_secondary_stage.json @@ -1,5 +1,5 @@ { - "name": "plan_secondary_stage", + "name": "sql_secondary_stage", "description": "Based on the primary stage planning, make more detail steps of the second stage if the primary stage needs more information.", "parameters": { "type": "object", diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/instructions/instruction.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/instructions/instruction.liquid index 52e498e5..617759fc 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/instructions/instruction.liquid +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/instructions/instruction.liquid @@ -3,12 +3,12 @@ You are going convert the user requirement into sql statements. The user is dealing with a complex problem, and you need to break this complex problem into several small tasks to more easily solve the user's needs. Follow these steps strictly and in order. -1. If user raised a new task, call plan_primary_stage to generate the primary plan. +1. If user raised a new task, call sql_primary_stage to generate the primary plan. If the sql response can be generate directly based on the context, directly go to step 6 to call function sql_review. 2. If need_lookup_dictionary is True, call verify_dictionary_term to verify or get the enum/term/dictionary value. Pull id and name. - * If you no items retured, you can pull 100 records from the table and look for the match. + * If there is no any item found, you can pull up to 100 records from the table and look for the match. * If need_lookup_dictionary is False, skip calling verify_dictionary_term. -3. If need_breakdown_task is true, call plan_secondary_stage for the specific primary stage. +3. If need_breakdown_task is true, call sql_secondary_stage for the specific primary stage. 4. Repeat step 3 until you processed all the primary steps. 5. Call sql_generation function to generate SQL statements. 6. Call sql_review function to review SQL statements. This is the step you must go through before reply to the user. diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.summarize.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.generation.liquid similarity index 100% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.summarize.liquid rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.generation.liquid diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.next.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.next.liquid similarity index 100% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.next.liquid rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.next.liquid diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.1st.plan.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.primary.plan.liquid similarity index 96% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.1st.plan.liquid rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.primary.plan.liquid index 306f4214..7013f0bf 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.1st.plan.liquid +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.primary.plan.liquid @@ -36,4 +36,6 @@ Domain Knowledge: ===== Task description: -{{ task_description }} \ No newline at end of file +{{ task_description }} + +Output the sub-tasks in JSON format: \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.2nd.plan.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.secondary.plan.liquid similarity index 100% rename from src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/two_stage.2nd.plan.liquid rename to src/Plugins/BotSharp.Plugin.Planner/data/agents/da7aad2c-8112-48a2-ab7b-1f87da524741/templates/sql.secondary.plan.liquid diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs index b712d347..a4e6d4b8 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Functions/SqlValidateFn.cs @@ -27,6 +27,7 @@ public class SqlValidateFn : IFunctionCallback } sql = Regex.Match(sql, pattern).Groups[1].Value; + message.Content = sql; var dbHook = _services.GetRequiredService(); var dbType = dbHook.GetDatabaseType(message); diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs index 231d793a..168929ea 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Hooks/SqlDriverPlanningHook.cs @@ -43,26 +43,17 @@ public class SqlDriverPlanningHook : IPlanningHook return; } - var conv = _services.GetRequiredService(); - var wholeDialogs = conv.GetDialogHistory(); - wholeDialogs.Add(RoleDialogModel.From(msg)); - wholeDialogs.Add(RoleDialogModel.From(msg, AgentRole.User, $"call execute_sql to run query, set formatting_result as {settings.FormattingResult}")); - - var agent = await _services.GetRequiredService().LoadAgent(BuiltInAgentId.SqlDriver); - var completion = CompletionProvider.GetChatCompletion(_services, - provider: agent.LlmConfig.Provider, - model: agent.LlmConfig.Model); - - var response = await completion.GetChatCompletions(agent, wholeDialogs); - // Invoke "execute_sql" - await routing.InvokeFunction(response.FunctionName, response); - - msg.CurrentAgentId = agent.Id; - msg.FunctionName = response.FunctionName; - msg.FunctionArgs = response.FunctionArgs; - msg.Content = response.Content; - msg.StopCompletion = response.StopCompletion; + var executionMsg = new RoleDialogModel(AgentRole.Function, "execute sql and format the result") + { + FunctionArgs = JsonSerializer.Serialize(new ExecuteQueryArgs + { + SqlStatements = [msg.Content], + FormattingResult = settings.FormattingResult + }) + }; + await routing.InvokeFunction("execute_sql", executionMsg); + msg.Content = $"The SQL query has been reviewed and executed, the formatted result is: \r\n{executionMsg.Content}"; } public async Task OnPlanningCompleted(string planner, RoleDialogModel msg)