diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs index f727403d..3cfc7011 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/AgentHookBase.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Settings; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Repositories; +using BotSharp.Abstraction.Routing; using Microsoft.Extensions.DependencyInjection; using System.Data; @@ -65,63 +66,59 @@ public abstract class AgentHookBase : IAgentHook var isConvMode = conv.IsConversationMode(); if (!isConvMode) return; - var render = _services.GetRequiredService(); - agent.Functions ??= []; agent.Utilities ??= []; - foreach (var utillity in agent.Utilities) + var (functions, templates) = GetUtilityContent(agent); + + agent.Functions.AddRange(functions); + foreach (var prompt in templates) { - if (utillity == null || string.IsNullOrWhiteSpace(utillity.Name)) continue; - - var (fns, prompts) = GetUtilityContent(utillity); - - if (!fns.IsNullOrEmpty()) - { - agent.Functions.AddRange(fns); - } - - if (!prompts.IsNullOrEmpty()) - { - foreach (var prompt in prompts) - { - agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n"; - } - } + agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n"; } } - private (IEnumerable, IEnumerable) GetUtilityContent(AgentUtility utility) + private (IEnumerable, IEnumerable) GetUtilityContent(Agent agent) { var db = _services.GetRequiredService(); - var render = _services.GetRequiredService(); + var (functionNames, templateNames) = GetUniqueContent(agent.Utilities); - var fns = new List(); - var prompts = new List(); - - var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant); - if (agent == null) + if (agent.MergeUtility) { - return (fns, prompts); - } - - if (!utility.Functions.IsNullOrEmpty()) - { - var functionNames = utility.Functions?.Select(x => x.Name)?.ToList() ?? []; - fns = agent?.Functions?.Where(x => functionNames.Contains(x.Name, StringComparer.OrdinalIgnoreCase))?.ToList() ?? []; - } - - if (!utility.Templates.IsNullOrEmpty()) - { - foreach (var template in utility.Templates) + var routing = _services.GetRequiredService(); + var entryAgentId = routing.EntryAgentId; + if (!string.IsNullOrEmpty(entryAgentId)) { - var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(template.Name))?.Content ?? string.Empty; - if (string.IsNullOrWhiteSpace(prompt)) continue; - - prompts.Add(prompt); + var entryAgent = db.GetAgent(entryAgentId); + var (fns, tps) = GetUniqueContent(entryAgent?.Utilities); + functionNames = functionNames.Concat(fns).Distinct().ToList(); + templateNames = templateNames.Concat(tps).Distinct().ToList(); } } - return (fns, prompts); + var ua = db.GetAgent(BuiltInAgentId.UtilityAssistant); + var functions = ua?.Functions?.Where(x => functionNames.Contains(x.Name, StringComparer.OrdinalIgnoreCase))?.ToList() ?? []; + var templates = ua?.Templates?.Where(x => templateNames.Contains(x.Name, StringComparer.OrdinalIgnoreCase))?.Select(x => x.Content)?.ToList() ?? []; + return (functions, templates); + } + + private (IEnumerable, IEnumerable) GetUniqueContent(IEnumerable? utilities) + { + if (utilities.IsNullOrEmpty()) + { + return ([], []); + } + + utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? []; + var functionNames = utilities.SelectMany(x => x.Functions) + .Where(x => !string.IsNullOrEmpty(x.Name)) + .Select(x => x.Name) + .Distinct().ToList(); + var templateNames = utilities.SelectMany(x => x.Templates) + .Where(x => !string.IsNullOrEmpty(x.Name)) + .Select(x => x.Name) + .Distinct().ToList(); + + return (functionNames, templateNames); } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentUtility.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentUtility.cs index 1617e173..40828944 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentUtility.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentUtility.cs @@ -2,13 +2,9 @@ namespace BotSharp.Abstraction.Agents.Models; public class AgentUtility { - [JsonPropertyName("name")] public string Name { get; set; } - - [JsonPropertyName("functions")] + public bool Disabled { get; set; } public IEnumerable Functions { get; set; } = []; - - [JsonPropertyName("templates")] public IEnumerable Templates { get; set; } = []; public AgentUtility() diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentUtilityMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentUtilityMongoElement.cs index 0eecee90..c05f07ef 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentUtilityMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/AgentUtilityMongoElement.cs @@ -5,6 +5,7 @@ namespace BotSharp.Plugin.MongoStorage.Models; public class AgentUtilityMongoElement { public string Name { get; set; } + public bool Disabled { get; set; } public List Functions { get; set; } = []; public List Templates { get; set; } = []; @@ -13,6 +14,7 @@ public class AgentUtilityMongoElement return new AgentUtilityMongoElement { Name = utility.Name, + Disabled = utility.Disabled, Functions = utility.Functions?.Select(x => new UtilityFunctionMongoElement(x.Name))?.ToList() ?? [], Templates = utility.Templates?.Select(x => new UtilityTemplateMongoElement(x.Name))?.ToList() ?? [] }; @@ -23,6 +25,7 @@ public class AgentUtilityMongoElement return new AgentUtility { Name = utility.Name, + Disabled = utility.Disabled, Functions = utility.Functions?.Select(x => new UtilityFunction(x.Name))?.ToList() ?? [], Templates = utility.Templates?.Select(x => new UtilityTemplate(x.Name))?.ToList() ?? [] }; diff --git a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json index fff27f86..d1b5eb52 100644 --- a/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json +++ b/src/Plugins/BotSharp.Plugin.Planner/data/agents/282a7128-69a1-44b0-878c-a9159b88f3b9/agent.json @@ -10,39 +10,7 @@ "isPublic": true, "profiles": [ "planning" ], "mergeUtility": true, - "utilities": [ - { - "name": "two-stage-planner", - "functions": [ - { "name": "plan_primary_stage" }, - { "name": "plan_secondary_stage" }, - { "name": "plan_summary" } - ], - "templates": [ - { "name": "plan_primary_stage.fn" }, - { "name": "plan_secondary_stage.fn" }, - { "name": "plan_summary.fn" } - ] - }, - { - "name": "sql-dictionary-lookup", - "functions": [ - { "name": "verify_dictionary_term" } - ], - "templates": [ - { "name": "verify_dictionary_term.fn" } - ] - }, - { - "name": "excel-handler", - "functions": [ - { "name": "handle_excel_request" } - ], - "templates": [ - { "name": "handle_excel_request.fn" } - ] - } - ], + "utilities": [], "llmConfig": { "provider": "openai", "model": "gpt-4o",