using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; namespace BotSharp.Core.Conversations.Services; public partial class ConversationService { public async Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDialog, Func onMessageReceived, Func onFunctionExecuting, Func onFunctionExecuted) { var converation = await GetConversation(conversationId); // Create conversation if this conversation not exists if (converation == null) { var sess = new Conversation { Id = conversationId, AgentId = agentId }; converation = await NewConversation(sess); } // conversation state var stateService = _services.GetRequiredService(); stateService.SetConversation(conversationId); stateService.Load(); stateService.SetState("channel", lastDialog.Channel); var router = _services.GetRequiredService(); var agent = await router.LoadRouter(); _logger.LogInformation($"[{agent.Name}] {lastDialog.Role}: {lastDialog.Content}"); lastDialog.CurrentAgentId = agent.Id; var wholeDialogs = GetDialogHistory(conversationId); wholeDialogs.Add(lastDialog); _storage.Append(conversationId, agent.Id, lastDialog); // Get relevant domain knowledge /*if (_settings.EnableKnowledgeBase) { var knowledge = _services.GetRequiredService(); agent.Knowledges = await knowledge.GetKnowledges(new KnowledgeRetrievalModel { AgentId = agentId, Question = string.Join("\n", wholeDialogs.Select(x => x.Content)) }); }*/ var hooks = _services.GetServices().ToList(); // Before chat completion hook foreach (var hook in hooks) { hook.SetAgent(agent) .SetConversation(converation); await hook.OnDialogsLoaded(wholeDialogs); await hook.BeforeCompletion(); } var chatCompletion = GetChatCompletion(); var result = await GetChatCompletionsAsyncRecursively(chatCompletion, conversationId, agent, wholeDialogs, onMessageReceived, onFunctionExecuting, onFunctionExecuted); return result; } private void SaveStateByArgs(string args) { var stateService = _services.GetRequiredService(); var jo = JsonSerializer.Deserialize(args); if (jo is JsonElement root) { foreach (JsonProperty property in root.EnumerateObject()) { stateService.SetState(property.Name, property.Value.ToString()); } } } public IChatCompletion GetChatCompletion() { var completions = _services.GetServices(); return completions.FirstOrDefault(x => x.GetType().FullName.EndsWith(_settings.ChatCompletion)); } }