using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Templating; namespace BotSharp.Core.Routing; public partial class RoutingService { private int _currentRecursionDepth = 0; public async Task InvokeAgent(string agentId, List dialogs) { var agentService = _services.GetRequiredService(); var agent = await agentService.LoadAgent(agentId); _currentRecursionDepth++; if (_currentRecursionDepth > agent.LlmConfig.MaxRecursionDepth) { _logger.LogWarning($"Current recursive call depth greater than {agent.LlmConfig.MaxRecursionDepth}, which will cause unexpected result."); return false; } var chatCompletion = CompletionProvider.GetChatCompletion(_services, agentConfig: agent.LlmConfig); var message = dialogs.Last(); var response = await chatCompletion.GetChatCompletions(agent, dialogs); if (response.Role == AgentRole.Function) { message = RoleDialogModel.From(message, role: AgentRole.Function); message.FunctionName = response.FunctionName; message.FunctionArgs = response.FunctionArgs; message.CurrentAgentId = agent.Id; await InvokeFunction(message, dialogs); } else { message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: response.Content); message.CurrentAgentId = agent.Id; dialogs.Add(message); } return true; } private async Task InvokeFunction(RoleDialogModel message, List dialogs) { // execute function // Save states var states = _services.GetRequiredService(); states.SaveStateByArgs(message.FunctionArgs?.JsonContent()); var conversationService = _services.GetRequiredService(); // Call functions await conversationService.CallFunctions(message); // Router selected the wrong agent, handle this excluding the agent if (message.UnmatchedAgent) { // Save to memory dialogs var msg = RoleDialogModel.From(message, role: AgentRole.Function, content: message.Content); msg.UnmatchedAgent = true; dialogs.Add(msg); } // Pass execution result to LLM to get response else if (!message.StopCompletion) { var routing = _services.GetRequiredService(); // Find response template var templateService = _services.GetRequiredService(); var responseTemplate = await templateService.RenderFunctionResponse(message.CurrentAgentId, message); if (!string.IsNullOrEmpty(responseTemplate)) { dialogs.Add(RoleDialogModel.From(message, role: AgentRole.Assistant, content: responseTemplate)); } else { // Save to memory dialogs dialogs.Add(RoleDialogModel.From(message, role: AgentRole.Function, content: message.Content)); // Send to Next LLM var agentId = routing.GetCurrentAgentId(); await InvokeAgent(agentId, dialogs); } } else { dialogs.Add(RoleDialogModel.From(message, role: AgentRole.Assistant, content: message.Content)); } return true; } }