clean code of sql planner
This commit is contained in:
parent
fe381066a5
commit
122f18fe1a
|
|
@ -72,10 +72,10 @@
|
|||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\agent.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\functions\plan_primary_stage.json">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\functions\sql_primary_stage.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\functions\plan_secondary_stage.json">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\functions\sql_secondary_stage.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\functions\sql_review.json">
|
||||
|
|
@ -87,16 +87,16 @@
|
|||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\instructions\instruction.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\two_stage.1st.plan.liquid">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\sql.primary.plan.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\two_stage.2nd.plan.liquid">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\sql.secondary.plan.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\two_stage.next.liquid">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\sql.next.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\two_stage.summarize.liquid">
|
||||
<Content Include="data\agents\da7aad2c-8112-48a2-ab7b-1f87da524741\templates\sql.generation.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -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<ITaskPlanner, SequentialPlanner>();
|
||||
services.AddScoped<ITaskPlanner, TwoStageTaskPlanner>();
|
||||
services.AddScoped<ITaskPlanner, SqlGenerationPlanner>();
|
||||
services.AddScoped<IAgentHook, PlannerAgentHook>();
|
||||
services.AddScoped<IAgentUtilityHook, PlannerUtilityHook>();
|
||||
services.AddScoped<IAgentHook, SqlPlannerAgentHook>();
|
||||
services.AddScoped<IAgentUtilityHook, TwoStagingPlannerUtilityHook>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<string> GetSummaryPlanPrompt(RoleDialogModel message, string taskDescription, string domainKnowledge, string dictionaryItems, string ddlStatement, string excelImportResult)
|
||||
private async Task<string> GetSqlGenerationPrompt(RoleDialogModel message, string taskDescription, string domainKnowledge, string dictionaryItems, string ddlStatement, string excelImportResult)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
var knowledgeHooks = _services.GetServices<IKnowledgeHook>();
|
||||
|
||||
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<string>();
|
||||
await HookEmitter.Emit<IPlanningHook>(_services, async x =>
|
||||
{
|
||||
var requirement = await x.GetSummaryAdditionalRequirements(nameof(TwoStageTaskPlanner), message);
|
||||
var requirement = await x.GetSummaryAdditionalRequirements(nameof(SqlGenerationPlanner), message);
|
||||
additionalRequirements.Add(requirement);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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<SqlPrimaryStageFn> _logger;
|
||||
|
||||
public SqlPrimaryStageFn(
|
||||
IServiceProvider services,
|
||||
ILogger<SqlPrimaryStageFn> logger)
|
||||
{
|
||||
_services = services;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
|
||||
state.SetState("max_tokens", "4096");
|
||||
var task = JsonSerializer.Deserialize<PrimaryRequirementRequest>(message.FunctionArgs);
|
||||
var searchQuestions = new List<string>(task.Questions);
|
||||
searchQuestions.AddRange(task.NormQuestions);
|
||||
searchQuestions = searchQuestions.Distinct().ToList();
|
||||
|
||||
// Get knowledge from vectordb
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
var knowledges = new List<string>();
|
||||
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<string, object>(),
|
||||
LlmConfig = currentAgent.LlmConfig
|
||||
};
|
||||
var response = await GetAiResponse(plannerAgent);
|
||||
message.Content = response.Content;
|
||||
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
states.SetState("planning_result", response.Content);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<string> GetPrimaryStagePlanPrompt(RoleDialogModel message, string taskDescription, List<string> domainKnowledges)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
var knowledgeHooks = _services.GetServices<IKnowledgeHook>();
|
||||
|
||||
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<string>();
|
||||
foreach (var hook in knowledgeHooks)
|
||||
{
|
||||
var k = await hook.GetGlobalKnowledges(message);
|
||||
globalKnowledges.AddRange(k);
|
||||
}
|
||||
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
{
|
||||
{ "task_description", taskDescription },
|
||||
{ "global_knowledges", globalKnowledges },
|
||||
{ "domain_knowledges", domainKnowledges },
|
||||
{ "response_format", responseFormat }
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<RoleDialogModel> GetAiResponse(Agent plannerAgent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var wholeDialogs = conv.GetDialogHistory();
|
||||
|
||||
var completion = CompletionProvider.GetChatCompletion(_services,
|
||||
provider: plannerAgent.LlmConfig.Provider,
|
||||
model: plannerAgent.LlmConfig.Model);
|
||||
|
||||
return await completion.GetChatCompletions(plannerAgent, wholeDialogs);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var args = JsonSerializer.Deserialize<SqlReviewArgs>(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<IPlanningHook>(_services, async hook =>
|
||||
await hook.OnSourceCodeGenerated(nameof(TwoStageTaskPlanner), message, "sql")
|
||||
await hook.OnSourceCodeGenerated(nameof(SqlGenerationPlanner), message, "sql")
|
||||
);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -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<SqlSecondaryStageFn> _logger;
|
||||
|
||||
public SqlSecondaryStageFn(
|
||||
IServiceProvider services,
|
||||
ILogger<SqlSecondaryStageFn> logger)
|
||||
{
|
||||
_services = services;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var knowledgeService = _services.GetRequiredService<IKnowledgeService>();
|
||||
var knowledgeSettings = _services.GetRequiredService<KnowledgeBaseSettings>();
|
||||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
|
||||
var msgSecondary = RoleDialogModel.From(message);
|
||||
var collectionName = knowledgeSettings.Default.CollectionName;
|
||||
var planResult = states.GetState("planning_result");
|
||||
|
||||
var taskSecondary = JsonSerializer.Deserialize<SecondaryBreakdownTask>(msgSecondary.FunctionArgs);
|
||||
|
||||
// Search knowledgebase
|
||||
var hooks = _services.GetServices<IKnowledgeHook>();
|
||||
var knowledges = new List<string>();
|
||||
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<string, object>(),
|
||||
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<string> GetSecondStagePlanPrompt(string taskDescription, string planResult, string knowledgeResults, RoleDialogModel message)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
|
||||
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<string, object>
|
||||
{
|
||||
{ "task_description", taskDescription },
|
||||
{ "primary_plan", planResult },
|
||||
{ "additional_knowledge", knowledgeResults },
|
||||
{ "response_format", responseFormat }
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<RoleDialogModel> GetAiResponse(Agent plannerAgent)
|
||||
{
|
||||
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);
|
||||
|
||||
return await completion.GetChatCompletions(plannerAgent, wholeDialogs);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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; } = [];
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -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}";
|
||||
|
|
@ -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; } = [];
|
||||
}
|
||||
|
|
@ -94,8 +94,8 @@ public class SqlGenerationPlanner : ITaskPlanner
|
|||
private async Task<string> GetNextStepPrompt(Agent router)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
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<IConversationStateService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
return render.Render(template, new Dictionary<string, object>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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";
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
@ -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",
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -36,4 +36,6 @@ Domain Knowledge:
|
|||
=====
|
||||
|
||||
Task description:
|
||||
{{ task_description }}
|
||||
{{ task_description }}
|
||||
|
||||
Output the sub-tasks in JSON format:
|
||||
|
|
@ -27,6 +27,7 @@ public class SqlValidateFn : IFunctionCallback
|
|||
}
|
||||
|
||||
sql = Regex.Match(sql, pattern).Groups[1].Value;
|
||||
message.Content = sql;
|
||||
|
||||
var dbHook = _services.GetRequiredService<ISqlDriverHook>();
|
||||
var dbType = dbHook.GetDatabaseType(message);
|
||||
|
|
|
|||
|
|
@ -43,26 +43,17 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
return;
|
||||
}
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
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<IAgentService>().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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue