BotSharp/src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs

144 lines
5.1 KiB
C#
Raw Normal View History

2025-02-23 14:55:35 +00:00
using BotSharp.Core.Mcp;
using BotSharp.Core.MCP;
2024-12-06 06:57:46 +00:00
namespace BotSharp.Core.Agents.Hooks;
2024-12-06 07:27:57 +00:00
public class BasicAgentHook : AgentHookBase
2024-12-06 06:57:46 +00:00
{
public override string SelfId => string.Empty;
2024-12-22 22:36:18 +00:00
private const string UTIL_PREFIX = "util-";
2024-12-06 07:27:57 +00:00
public BasicAgentHook(IServiceProvider services, AgentSettings settings)
2024-12-06 06:57:46 +00:00
: base(services, settings)
{
}
public override void OnAgentUtilityLoaded(Agent agent)
{
if (agent.Type == AgentType.Routing) return;
var conv = _services.GetRequiredService<IConversationService>();
var isConvMode = conv.IsConversationMode();
if (!isConvMode) return;
2024-12-22 22:36:18 +00:00
agent.SecondaryFunctions ??= [];
agent.SecondaryInstructions ??= [];
2024-12-06 06:57:46 +00:00
agent.Utilities ??= [];
var (functions, templates) = GetUtilityContent(agent);
foreach (var fn in functions)
{
2024-12-22 22:36:18 +00:00
if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
2024-12-06 06:57:46 +00:00
{
2024-12-22 22:36:18 +00:00
agent.SecondaryFunctions.Add(fn);
2024-12-06 06:57:46 +00:00
}
}
foreach (var prompt in templates)
{
2024-12-22 22:36:18 +00:00
agent.SecondaryInstructions.Add(prompt);
2024-12-06 06:57:46 +00:00
}
}
2025-02-23 14:55:35 +00:00
public override void OnAgentMCPLoaded(Agent agent)
{
if (agent.Type == AgentType.Routing)
return;
var conv = _services.GetRequiredService<IConversationService>();
var isConvMode = conv.IsConversationMode();
if (!isConvMode) return;
agent.SecondaryFunctions ??= [];
agent.SecondaryInstructions ??= [];
agent.Mcps ??= [];
var (functions, templates) = GetMCPContent(agent);
foreach (var fn in functions)
{
if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
{
agent.SecondaryFunctions.Add(fn);
}
}
foreach (var prompt in templates)
{
agent.SecondaryInstructions.Add(prompt);
}
}
2024-12-06 06:57:46 +00:00
private (IEnumerable<FunctionDef>, IEnumerable<string>) GetUtilityContent(Agent agent)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var (functionNames, templateNames) = GetUniqueContent(agent.Utilities);
if (agent.MergeUtility)
{
var routing = _services.GetRequiredService<IRoutingContext>();
var entryAgentId = routing.EntryAgentId;
if (!string.IsNullOrEmpty(entryAgentId))
{
2024-12-13 20:34:17 +00:00
var entryAgent = db.GetAgent(entryAgentId, basicsOnly: true);
2024-12-06 06:57:46 +00:00
var (fns, tps) = GetUniqueContent(entryAgent?.Utilities);
functionNames = functionNames.Concat(fns).Distinct().ToList();
templateNames = templateNames.Concat(tps).Distinct().ToList();
}
}
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<string>, IEnumerable<string>) GetUniqueContent(IEnumerable<AgentUtility>? utilities)
{
if (utilities.IsNullOrEmpty())
{
return ([], []);
}
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
var functionNames = utilities.SelectMany(x => x.Functions)
2024-12-22 22:36:18 +00:00
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
2024-12-06 06:57:46 +00:00
.Select(x => x.Name)
.Distinct().ToList();
var templateNames = utilities.SelectMany(x => x.Templates)
2024-12-22 22:36:18 +00:00
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
2024-12-06 06:57:46 +00:00
.Select(x => x.Name)
.Distinct().ToList();
return (functionNames, templateNames);
}
2025-02-23 14:55:35 +00:00
private (IEnumerable<FunctionDef>, IEnumerable<string>) GetMCPContent(Agent agent)
{
List<FunctionDef> functionDefs = new List<FunctionDef>();
IEnumerable<string> templates = new List<string>();
var mcpClientManager = _services.GetRequiredService<MCPClientManager>();
var mcps = agent.Mcps;
foreach (var item in mcps)
{
var ua = mcpClientManager.Factory.GetClientAsync(item.ServerId).Result;
if (ua != null)
{
var tools = ua.ListToolsAsync().Result;
var funcnames = item.Functions.Select(x => x.Name).ToList();
foreach (var tool in tools.Tools.Where(x=> funcnames.Contains(x.Name,StringComparer.OrdinalIgnoreCase)))
{
var funDef = AIFunctionUtilities.MapToFunctionDef(tool);
functionDefs.Add(funDef);
}
}
}
return (functionDefs, templates);
}
2024-12-06 06:57:46 +00:00
}