diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs index 2a19fd290..20599d654 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs @@ -10,7 +10,7 @@ public interface IAgentService Task> GetAgents(); /// - /// Load agent configurations and trigghe hooks + /// Load agent configurations and trigger hooks /// /// /// diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs index 907ed5ad8..20ac5a05b 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.GetNextInstruction.cs @@ -1,11 +1,7 @@ using BotSharp.Abstraction.Functions.Models; -using BotSharp.Abstraction.Repositories; -using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Templating; using System.Drawing; -using System.IO; using System.Text.RegularExpressions; - namespace BotSharp.Core.Routing; public partial class RoutingService @@ -96,29 +92,10 @@ public async Task GetNextInstruction() _logger.LogInformation(response.Content); #endif - // Sometimes it populate malformed Function in Agent name - if (!string.IsNullOrEmpty(args.Function) && args.Function == args.AgentName) - { - args.Function = "route_to_agent"; - _logger.LogWarning($"Captured LLM malformed response"); - } - - // Another case of malformed response - var agentService = _services.GetRequiredService(); - var agents = await agentService.GetAgents(); - if (string.IsNullOrEmpty(args.AgentName) && agents.Select(x => x.Name).Contains(args.Function)) - { - args.AgentName = args.Function; - args.Function = "route_to_agent"; - _logger.LogWarning($"Captured LLM malformed response"); - } - - if (args.Arguments != null) - { - SaveStateByArgs(args.Arguments); - } + // Fix LLM malformed response + FixMalformedResponse(args); - args.Function = args.Function.Split('.').Last(); + SaveStateByArgs(args.Arguments); #if DEBUG Console.WriteLine($"*** Next Instruction *** {args}", Color.Green); @@ -145,4 +122,54 @@ private string GetNextStepPrompt() { "enabled_reasoning", _settings.EnableReasoning } }); } + + /// + /// Sometimes LLM hallucinates and fails to set function names correctly. + /// + /// + private void FixMalformedResponse(FunctionCallFromLlm args) + { + var agentService = _services.GetRequiredService(); + var agents = agentService.GetAgents().Result; + var malformed = false; + + // Sometimes it populate malformed Function in Agent name + if (!string.IsNullOrEmpty(args.Function) && + args.Function == args.AgentName) + { + args.Function = "route_to_agent"; + malformed = true; + } + + // Another case of malformed response + if (string.IsNullOrEmpty(args.AgentName) && + agents.Select(x => x.Name).Contains(args.Function)) + { + args.AgentName = args.Function; + args.Function = "route_to_agent"; + malformed = true; + } + + // It should be Route to agent, but it is used as Response to user. + if (string.IsNullOrEmpty(args.AgentName) && + agents.Select(x => x.Name).Contains(args.AgentName) && + args.Function != "route_to_agent") + { + args.Function = "route_to_agent"; + malformed = true; + } + + // Function name shouldn't contain dot symbol + if (!string.IsNullOrEmpty(args.Function) && + args.Function.Contains('.')) + { + args.Function = args.Function.Split('.').Last(); + malformed = true; + } + + if (malformed) + { + _logger.LogWarning($"Captured LLM malformed response"); + } + } } diff --git a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json index 1951ab9b0..af5d7e1a9 100644 --- a/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json +++ b/src/WebStarter/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/agent.json @@ -3,5 +3,6 @@ "description": "Pizza restaurant AI Bot", "createdDateTime": "2023-08-18T14:39:32.2349685Z", "updatedDateTime": "2023-08-18T14:39:32.2349686Z", - "id": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a" + "id": "01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a", + "isPublic": true } \ No newline at end of file