BotSharp/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.LoadAgent.cs

163 lines
4.6 KiB
C#
Raw Normal View History

2024-08-04 15:01:08 +00:00
using BotSharp.Abstraction.Routing.Models;
using System.Collections.Concurrent;
2023-08-14 17:00:01 +00:00
namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
2024-12-12 08:02:09 +00:00
public static ConcurrentDictionary<string, Dictionary<string, string>> AgentParameterTypes = new();
2024-08-04 15:01:08 +00:00
2025-04-16 21:17:34 +00:00
// [SharpCache(10, perInstanceCache: true)]
2024-12-22 22:36:18 +00:00
public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
2023-08-14 17:00:01 +00:00
{
2024-07-10 04:36:49 +00:00
if (string.IsNullOrEmpty(id) || id == Guid.Empty.ToString())
2023-12-05 00:12:57 +00:00
{
return null;
}
2023-08-14 17:00:01 +00:00
var hooks = _services.GetServices<IAgentHook>();
// Before agent is loaded.
foreach (var hook in hooks)
{
2023-10-24 21:38:34 +00:00
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != id)
{
continue;
}
2023-08-14 17:00:01 +00:00
hook.OnAgentLoading(ref id);
}
2023-09-25 22:46:00 +00:00
var agent = await GetAgent(id);
if (agent == null)
{
2024-06-24 21:39:08 +00:00
return null;
}
2024-08-13 21:36:12 +00:00
await InheritAgent(agent);
OverrideInstructionByChannel(agent);
2024-08-04 15:01:08 +00:00
AddOrUpdateParameters(agent);
2023-10-28 20:59:26 +00:00
// Populate state into dictionary
2024-08-13 21:36:12 +00:00
agent.TemplateDict = new Dictionary<string, object>();
2023-10-28 20:59:26 +00:00
PopulateState(agent.TemplateDict);
2023-08-14 17:00:01 +00:00
// After agent is loaded
foreach (var hook in hooks)
{
2023-10-24 21:38:34 +00:00
if (!string.IsNullOrEmpty(hook.SelfId) && hook.SelfId != id)
{
continue;
}
2023-08-14 17:00:01 +00:00
hook.SetAget(agent);
if (!string.IsNullOrEmpty(agent.Instruction))
{
2023-10-28 20:59:26 +00:00
hook.OnInstructionLoaded(agent.Instruction, agent.TemplateDict);
2023-08-14 17:00:01 +00:00
}
2023-09-28 03:31:58 +00:00
if (agent.Functions != null)
2023-08-14 17:00:01 +00:00
{
hook.OnFunctionsLoaded(agent.Functions);
2023-08-14 17:00:01 +00:00
}
2023-10-19 17:24:00 +00:00
if (agent.Samples != null)
2023-08-14 17:00:01 +00:00
{
2023-10-19 17:24:00 +00:00
hook.OnSamplesLoaded(agent.Samples);
2023-08-14 17:00:01 +00:00
}
2025-04-15 22:58:33 +00:00
if (loadUtility && !agent.Utilities.IsNullOrEmpty())
2024-12-22 22:36:18 +00:00
{
hook.OnAgentUtilityLoaded(agent);
}
2025-02-23 14:55:35 +00:00
2025-03-31 21:43:42 +00:00
if(!agent.McpTools.IsNullOrEmpty())
2025-02-23 14:55:35 +00:00
{
2025-04-01 01:59:19 +00:00
hook.OnAgentMcpToolLoaded(agent);
2025-02-23 14:55:35 +00:00
}
2024-12-22 22:36:18 +00:00
2023-08-17 04:04:23 +00:00
hook.OnAgentLoaded(agent);
2023-08-14 17:00:01 +00:00
}
2023-08-17 04:04:23 +00:00
_logger.LogInformation($"Loaded agent {agent}.");
2023-08-14 17:00:01 +00:00
return agent;
}
2024-08-13 21:36:12 +00:00
private void OverrideInstructionByChannel(Agent agent)
{
var instructions = agent.ChannelInstructions;
if (instructions.IsNullOrEmpty()) return;
var state = _services.GetRequiredService<IConversationStateService>();
var channel = state.GetState("channel");
if (string.IsNullOrWhiteSpace(channel))
{
return;
}
var found = instructions.FirstOrDefault(x => x.Channel.IsEqualTo(channel));
agent.Instruction = !string.IsNullOrWhiteSpace(found?.Instruction) ? found.Instruction : agent.Instruction;
}
private void PopulateState(Dictionary<string, object> dict)
{
2023-09-06 03:19:36 +00:00
var conv = _services.GetRequiredService<IConversationService>();
foreach (var t in conv.States.GetStates())
{
dict[t.Key] = t.Value;
}
}
2024-08-04 15:01:08 +00:00
private void AddOrUpdateParameters(Agent agent)
{
var agentId = agent.Id ?? agent.Name;
if (AgentParameterTypes.ContainsKey(agentId)) return;
2024-12-12 08:02:09 +00:00
2024-08-04 15:01:08 +00:00
AddOrUpdateRoutesParameters(agentId, agent.RoutingRules);
AddOrUpdateFunctionsParameters(agentId, agent.Functions);
}
private void AddOrUpdateRoutesParameters(string agentId, List<RoutingRule> routingRules)
{
2024-12-12 08:02:09 +00:00
if (!AgentParameterTypes.TryGetValue(agentId, out var parameterTypes))
2024-08-13 21:36:12 +00:00
{
parameterTypes = new();
}
2024-08-04 15:01:08 +00:00
foreach (var rule in routingRules.Where(x => x.Required))
{
if (string.IsNullOrEmpty(rule.FieldType)) continue;
parameterTypes.TryAdd(rule.Field, rule.FieldType);
}
2024-08-13 21:36:12 +00:00
2024-08-04 15:01:08 +00:00
AgentParameterTypes.TryAdd(agentId, parameterTypes);
}
private void AddOrUpdateFunctionsParameters(string agentId, List<FunctionDef> functions)
{
2024-08-13 21:36:12 +00:00
if (!AgentParameterTypes.TryGetValue(agentId, out var parameterTypes))
{
parameterTypes = new();
}
2024-08-04 15:01:08 +00:00
var parameters = functions.Select(p => p.Parameters);
foreach (var param in parameters)
{
foreach (JsonProperty prop in param.Properties.RootElement.EnumerateObject())
{
var name = prop.Name;
var node = prop.Value;
if (node.TryGetProperty("type", out var type))
{
parameterTypes.TryAdd(name, type.GetString());
}
}
}
2024-08-13 21:36:12 +00:00
2024-08-04 15:01:08 +00:00
AgentParameterTypes.TryAdd(agentId, parameterTypes);
}
2023-08-14 17:00:01 +00:00
}