From e939707595545611728cf2eb578b548b2d076ce2 Mon Sep 17 00:00:00 2001 From: hchen Date: Wed, 13 Sep 2023 05:08:34 -0500 Subject: [PATCH] Fix bug when there are multiple missing fileds. --- .../Agents/IAgentRouting.cs | 1 + .../Models/IncomingMessageModel.cs | 3 + ...vice.GetChatCompletionsAsyncRecursively.cs | 5 +- .../BotSharp.Core/Routing/RouteToAgentFn.cs | 59 +++++++++++++------ .../BotSharp.Core/Routing/Router.cs | 6 +- .../ViewModels/OpenAiMessageInput.cs | 3 - 6 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs index 269a6983..1e94e5dd 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentRouting.cs @@ -7,5 +7,6 @@ public interface IAgentRouting string AgentId { get; } Task LoadRouter(); RoutingItem[] GetRoutingRecords(); + RoutingItem GetRecordByAgentId(string id); RoutingItem GetRecordByName(string name); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs index 447bef04..bdc8f3a2 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/IncomingMessageModel.cs @@ -1,3 +1,5 @@ +using System.Text.Json.Serialization; + namespace BotSharp.Abstraction.Conversations.Models; public class IncomingMessageModel @@ -9,6 +11,7 @@ public class IncomingMessageModel /// /// Model name /// + [JsonPropertyName("model")] public virtual string ModelName { get; set; } = "gpt-3.5-turbo"; /// diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs index 3e7b9cbe..cf9689e6 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.GetChatCompletionsAsyncRecursively.cs @@ -78,7 +78,10 @@ public partial class ConversationService return; } - fn.Content = fn.FunctionArgs.Replace("\r", " ").Replace("\n", " ").Trim() + " => " + fn.ExecutionResult; + var content = fn.FunctionArgs.Replace("\r", " ").Replace("\n", " ").Trim() + " => " + fn.ExecutionResult; + _logger.LogInformation(content); + + fn.Content = content; // Agent has been transferred if (fn.CurrentAgentId != preAgentId) diff --git a/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs index ef7f295c..3bc7cc5d 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RouteToAgentFn.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Functions; -using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Routing.Models; namespace BotSharp.Core.Routing; @@ -39,6 +38,8 @@ public class RouteToAgentFn : IFunctionCallback } } + // Set default execution data + message.ExecutionData = JsonSerializer.Deserialize(message.FunctionArgs); return true; } @@ -60,45 +61,65 @@ public class RouteToAgentFn : IFunctionCallback } agentId = routingRule.AgentId; + // Add routed agent + message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "route_to", agentId); // Check required fields var root = JsonSerializer.Deserialize(message.FunctionArgs); - bool hasMissingField = false; - string missingFieldName = ""; + var missingFields = new List(); foreach (var field in routingRule.RequiredFields) { if (!root.EnumerateObject().Any(x => x.Name == field)) { - message.ExecutionResult = $"missing {field}."; - hasMissingField = true; - missingFieldName = field; - break; + missingFields.Add(field); } else if (root.EnumerateObject().Any(x => x.Name == field) && string.IsNullOrEmpty(root.EnumerateObject().FirstOrDefault(x => x.Name == field).Value.ToString())) { - message.ExecutionResult = $"missing {field}."; - hasMissingField = true; - missingFieldName = field; - break; + missingFields.Add(field); } } // Check if states contains the field according conversation context. var states = _services.GetRequiredService(); - if (!string.IsNullOrEmpty(states.GetState(missingFieldName))) + foreach (var field in missingFields.ToList()) { - var value = states.GetState(missingFieldName); - message.FunctionArgs = message.FunctionArgs.Substring(0, message.FunctionArgs.Length - 1) + $", \"{missingFieldName}\": \"{value}\"" + "}"; - hasMissingField = false; - missingFieldName = ""; + if (!string.IsNullOrEmpty(states.GetState(field))) + { + var value = states.GetState(field); + message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, field, value); + missingFields.Remove(field); + } } - if (hasMissingField && !string.IsNullOrEmpty(routingRule.RedirectTo)) + if (missingFields.Any()) { - agentId = routingRule.RedirectTo; + // Add field to args + message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "missing_fields", missingFields); + message.ExecutionResult = $"missing some information"; + + // Handle redirect + if (!string.IsNullOrEmpty(routingRule.RedirectTo)) + { + agentId = routingRule.RedirectTo; + var agent = router.GetRecordByAgentId(agentId); + + // Add redirected agent + message.FunctionArgs = AppendPropertyToArgs(message.FunctionArgs, "redirect_to", agent.Name); + } } - return hasMissingField; + return missingFields.Any(); + } + + private string AppendPropertyToArgs(string args, string key, string value) + { + return args.Substring(0, args.Length - 1) + $", \"{key}\": \"{value}\"" + "}"; + } + + private string AppendPropertyToArgs(string args, string key, IEnumerable values) + { + string fields = string.Join(",", values.Select(x => $"\"{x}\"")); + return args.Substring(0, args.Length - 1) + $", \"{key}\": [{fields}]" + "}"; } } diff --git a/src/Infrastructure/BotSharp.Core/Routing/Router.cs b/src/Infrastructure/BotSharp.Core/Routing/Router.cs index d33af929..44269e26 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/Router.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/Router.cs @@ -3,7 +3,6 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Settings; -using System.IO; namespace BotSharp.Core.Routing; @@ -56,4 +55,9 @@ public class Router : IAgentRouting { return GetRoutingRecords().First(x => x.Name.ToLower() == name.ToLower()); } + + public RoutingItem GetRecordByAgentId(string id) + { + return GetRoutingRecords().First(x => x.AgentId == id); + } } diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs index ed88bc4b..db108ba0 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ViewModels/OpenAiMessageInput.cs @@ -10,9 +10,6 @@ public class OpenAiMessageInput : IncomingMessageModel public string AgentId { get; set; } = string.Empty; public string ConversationId { get; set; } = string.Empty; - [JsonPropertyName("model")] - public override string ModelName { get; set; } = string.Empty; - public List Messages { get; set; } = new List(); [JsonPropertyName("max_tokens")]