From b76f9bb979e1b1d1ecb38eb2fc4b58e326c691d0 Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Mon, 23 Sep 2024 14:31:47 -0500 Subject: [PATCH] add question to GetRelevantKnowledges. --- .../Knowledges/IKnowledgeHook.cs | 2 +- .../Template/GenericTemplateMessage.cs | 3 ++ .../Planning/IPlanningHook.cs | 1 + .../ConversationService.SendMessage.cs | 6 +++ .../Filters/UserSingleLoginFilter.cs | 6 ++- .../Functions/PrimaryStagePlanFn.cs | 10 ++++- .../Functions/SecondaryStagePlanFn.cs | 1 - .../TwoStaging/Models/SecondStagePlan.cs | 3 -- .../TwoStaging/TwoStageTaskPlanner.cs | 38 ------------------- .../instructions/instruction.liquid | 5 ++- .../templates/two_stage.next.liquid | 1 - 11 files changed, 27 insertions(+), 49 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeHook.cs b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeHook.cs index 3b77af77..7143d789 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Knowledges/IKnowledgeHook.cs @@ -5,7 +5,7 @@ public interface IKnowledgeHook Task> CollectChunkedKnowledge() => Task.FromResult(new List()); - Task> GetRelevantKnowledges() + Task> GetRelevantKnowledges(string text) => Task.FromResult(new List()); Task> GetGlobalKnowledges() diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/GenericTemplateMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/GenericTemplateMessage.cs index f165dbc1..daf2e636 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/GenericTemplateMessage.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/GenericTemplateMessage.cs @@ -5,6 +5,9 @@ public class GenericTemplateMessage : IRichMessage, ITemplateMessage [JsonPropertyName("rich_type")] public string RichType => RichTypeEnum.GenericTemplate; + /// + /// Use model refined content if leaving blank + /// [JsonPropertyName("text")] [Translate] public string Text { get; set; } = string.Empty; diff --git a/src/Infrastructure/BotSharp.Abstraction/Planning/IPlanningHook.cs b/src/Infrastructure/BotSharp.Abstraction/Planning/IPlanningHook.cs index 3f258c98..e609ab11 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Planning/IPlanningHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Planning/IPlanningHook.cs @@ -4,6 +4,7 @@ public interface IPlanningHook { Task GetSummaryAdditionalRequirements(string planner) => Task.FromResult(string.Empty); + Task OnPlanningCompleted(string planner, RoleDialogModel msg) => Task.CompletedTask; } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs index b0410750..13e8edf1 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.SendMessage.cs @@ -123,6 +123,12 @@ public partial class ConversationService Message = new TextMessage(response.SecondaryContent ?? response.Content) }; + // Use model refined response + if (string.IsNullOrEmpty(response.RichContent.Message.Text)) + { + response.RichContent.Message.Text = response.Content; + } + // Patch return function name if (response.PostbackFunctionName != null) { diff --git a/src/Infrastructure/BotSharp.OpenAPI/Filters/UserSingleLoginFilter.cs b/src/Infrastructure/BotSharp.OpenAPI/Filters/UserSingleLoginFilter.cs index d7c35c8e..6e0a6b2f 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Filters/UserSingleLoginFilter.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Filters/UserSingleLoginFilter.cs @@ -31,8 +31,12 @@ namespace BotSharp.OpenAPI.Filters return; } - if (token.ValidTo.ToLongTimeString() != GetUserExpires().ToLongTimeString()) + var validTo = token.ValidTo.ToLongTimeString(); + var currentExpires = GetUserExpires().ToLongTimeString(); + + if (validTo != currentExpires) { + Serilog.Log.Warning($"Token expired. Token expires at {validTo}, current expires at {currentExpires}"); context.Result = new UnauthorizedResult(); } } diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs index d2ef2e5c..f1a34513 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/Functions/PrimaryStagePlanFn.cs @@ -27,6 +27,7 @@ public class PrimaryStagePlanFn : IFunctionCallback var collectionName = knowledgeSettings.Default.CollectionName ?? KnowledgeCollectionName.BotSharp; // Get knowledge from vectordb + var hooks = _services.GetServices(); var knowledges = new List(); foreach (var question in task.Questions) { @@ -34,8 +35,13 @@ public class PrimaryStagePlanFn : IFunctionCallback { Confidence = 0.2f }); - knowledges.Add(string.Join("\r\n\r\n=====\r\n", list.Select(x => x.ToQuestionAnswer()))); + + foreach (var hook in hooks) + { + var k = await hook.GetRelevantKnowledges(question); + knowledges.AddRange(k); + } } // Get first stage planning prompt @@ -92,7 +98,7 @@ public class PrimaryStagePlanFn : IFunctionCallback var wholeDialogs = conv.GetDialogHistory(); // Append text - wholeDialogs.Last().Content += "\n\nYou must analyze the table description to infer the table relations."; + wholeDialogs.Last().Content += "\n\nYou must analyze the table description to infer the table relations. Only output the JSON result."; var completion = CompletionProvider.GetChatCompletion(_services, provider: plannerAgent.LlmConfig.Provider, diff --git a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs b/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs index 29a74364..cfd150d9 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/Functions/SecondaryStagePlanFn.cs @@ -75,7 +75,6 @@ public class SecondaryStagePlanFn : IFunctionCallback var template = agent.Templates.FirstOrDefault(x => x.Name == "two_stage.2nd.plan")?.Content ?? string.Empty; var responseFormat = JsonSerializer.Serialize(new SecondStagePlan { - Tool = "tool name if task solution provided", Parameters = [ JsonDocument.Parse("{}") ], Results = [ string.Empty ] }); diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SecondStagePlan.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SecondStagePlan.cs index d4f5dfcf..9076a6b4 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SecondStagePlan.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/Models/SecondStagePlan.cs @@ -8,9 +8,6 @@ public class SecondStagePlan [JsonPropertyName("description")] public string Description { get; set; } = ""; - [JsonPropertyName("tool_name")] - public string Tool { get; set; } = ""; - [JsonPropertyName("input_args")] public JsonDocument[] Parameters { get; set; } = []; diff --git a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs index 06050d86..2ecd9ac0 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs +++ b/src/Plugins/BotSharp.Plugin.Planner/TwoStaging/TwoStageTaskPlanner.cs @@ -96,31 +96,6 @@ public partial class TwoStageTaskPlanner : IRoutingPlaner return true; } - private async Task GetFirstStagePlanPrompt(Agent router) - { - var template = router.Templates.First(x => x.Name == "two_stage.1st.plan").Content; - var responseFormat = JsonSerializer.Serialize(new FirstStagePlan - { - Parameters = new JsonDocument[] { JsonDocument.Parse("{}") }, - Results = new string[] { "" } - }); - - var relevantKnowledges = new List(); - var hooks = _services.GetServices(); - foreach (var hook in hooks) - { - var k = await hook.GetRelevantKnowledges(); - relevantKnowledges.AddRange(k); - } - - var render = _services.GetRequiredService(); - return render.Render(template, new Dictionary - { - { "response_format", responseFormat }, - { "relevant_knowledges", relevantKnowledges.ToArray() } - }); - } - private async Task GetNextStepPrompt(Agent router) { var agentService = _services.GetRequiredService(); @@ -134,17 +109,4 @@ public partial class TwoStageTaskPlanner : IRoutingPlaner { StateConst.EXPECTED_GOAL_AGENT, states.GetState(StateConst.EXPECTED_GOAL_AGENT) } }); } - - private string GetSecondStageTaskPrompt(Agent router, SecondStagePlan plan) - { - var template = router.Templates.First(x => x.Name == "planner_prompt.two_stage.2nd.task").Content; - var render = _services.GetRequiredService(); - return render.Render(template, new Dictionary - { - { "task_description", plan.Description }, - { "related_tables", plan.Tables }, - { "input_arguments", JsonSerializer.Serialize(plan.Parameters) }, - { "output_results", JsonSerializer.Serialize(plan.Results) }, - }); - } } diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid index e542c2ee..8f8b29a5 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/instructions/instruction.liquid @@ -1,7 +1,8 @@ Use the TwoStagePlanner approach to plan the overall implementation steps, follow the below steps strictly. -1. call plan_primary_stage to generate the primary plan. +1. Call plan_primary_stage to generate the primary plan. 2. If need_additional_information is true, call plan_secondary_stage for the specific primary stage. -3. You must call plan_summary for you final planned output. +3. You must call plan_summary to generate final planned steps. +4. If you can't generate the final accurate planning steps due to missing some specific informations, please ask user for more information. *** IMPORTANT *** Don't run the planning process repeatedly if you have already got the result of user's request. diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.next.liquid b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.next.liquid index 48ae2b39..f7388be6 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.next.liquid +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/templates/two_stage.next.liquid @@ -10,4 +10,3 @@ Expected user goal agent is {{ expected_user_goal_agent }}. {%- else -%} User goal agent is inferred based on user initial request. {%- endif %} -Always route to planner first. \ No newline at end of file