using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.MLTasks.Settings; using BotSharp.Abstraction.Templating; namespace BotSharp.Core.Routing; public partial class RoutingService { const int MAXIMUM_RECURSION_DEPTH = 3; private int _currentRecursionDepth = 0; public async Task InvokeAgent(string agentId, List dialogs) { _currentRecursionDepth++; if (_currentRecursionDepth > MAXIMUM_RECURSION_DEPTH) { _logger.LogWarning($"Current recursive call depth greater than {MAXIMUM_RECURSION_DEPTH}, which will cause unexpected result."); return false; } var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(agentId); var settings = _services.GetRequiredService(); var chatCompletion = CompletionProvider.GetChatCompletion(_services, provider: settings.Provider, model: settings.Model); RoleDialogModel response = chatCompletion.GetChatCompletions(agent, dialogs); if (response.Role == AgentRole.Function) { await InvokeFunction(agent, response, dialogs); } else { dialogs.Add(response); } return true; } private async Task InvokeFunction(Agent agent, RoleDialogModel message, List dialogs) { // execute function // Save states SaveStateByArgs(JsonSerializer.Deserialize(message.FunctionArgs)); var conversationService = _services.GetRequiredService(); // Call functions await conversationService.CallFunctions(message); // Pass execution result to LLM to get response if (!message.StopCompletion) { // Find response template var templateService = _services.GetRequiredService(); var responseTemplate = await templateService.RenderFunctionResponse(agent.Id, message); if (!string.IsNullOrEmpty(responseTemplate)) { message.Content = responseTemplate.Trim(); message.Role = AgentRole.Assistant; dialogs.Add(message); } else { // Save to memory dialogs dialogs.Add(new RoleDialogModel(AgentRole.Function, message.Content) { FunctionArgs = message.FunctionArgs, FunctionName = message.FunctionName }); // Send to LLM await InvokeAgent(agent.Id, dialogs); } } return true; } }