using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Models; namespace BotSharp.Core.Conversations.Services; public partial class ConversationService : IConversationService { private readonly ILogger _logger; private readonly IServiceProvider _services; private readonly IUserIdentity _user; private readonly ConversationSetting _settings; private readonly IConversationStorage _storage; private readonly IConversationStateService _state; private string _conversationId; public string ConversationId => _conversationId; public IConversationStateService States => _state; public ConversationService( IServiceProvider services, IUserIdentity user, ConversationSetting settings, IConversationStorage storage, IConversationStateService state, ILogger logger) { _services = services; _user = user; _settings = settings; _storage = storage; _state = state; _logger = logger; } public async Task DeleteConversations(IEnumerable ids) { var db = _services.GetRequiredService(); var fileService = _services.GetRequiredService(); var isDeleted = db.DeleteConversations(ids); fileService.DeleteConversationFiles(ids); return await Task.FromResult(isDeleted); } public async Task UpdateConversationTitle(string id, string title) { var db = _services.GetRequiredService(); db.UpdateConversationTitle(id, title); var conversation = db.GetConversation(id); return conversation; } public async Task GetConversation(string id) { var db = _services.GetRequiredService(); var conversation = db.GetConversation(id); return conversation; } public async Task> GetConversations(ConversationFilter filter) { var db = _services.GetRequiredService(); var conversations = db.GetConversations(filter); return conversations; } public async Task> GetLastConversations() { var db = _services.GetRequiredService(); return db.GetLastConversations(); } public async Task> GetIdleConversations(int batchSize, int messageLimit, int bufferHours) { var db = _services.GetRequiredService(); return db.GetIdleConversations(batchSize, messageLimit, bufferHours); } public async Task NewConversation(Conversation sess) { var db = _services.GetRequiredService(); var user = db.GetUserById(_user.Id); var foundUserId = user?.Id ?? string.Empty; var record = sess; record.Id = sess.Id.IfNullOrEmptyAs(Guid.NewGuid().ToString()); record.UserId = sess.UserId.IfNullOrEmptyAs(foundUserId); record.Title = "New Conversation"; db.CreateNewConversation(record); var hooks = _services.GetServices().ToList(); foreach (var hook in hooks) { // If user connect agent first time await hook.OnUserAgentConnectedInitially(sess); await hook.OnConversationInitialized(record); } return record; } public Task CleanHistory(string agentId) { throw new NotImplementedException(); } public List GetDialogHistory(int lastCount = 50, bool fromBreakpoint = true) { if (string.IsNullOrEmpty(_conversationId)) { throw new ArgumentNullException("ConversationId is null."); } var dialogs = _storage.GetDialogs(_conversationId); if (fromBreakpoint) { var db = _services.GetRequiredService(); var breakpoint = db.GetConversationBreakpoint(_conversationId); if (breakpoint != null) { dialogs = dialogs.Where(x => x.CreatedAt >= breakpoint.Breakpoint).ToList(); if (!string.IsNullOrEmpty(breakpoint.Reason)) { dialogs.Insert(0, new RoleDialogModel(AgentRole.User, breakpoint.Reason)); } } } return dialogs .TakeLast(lastCount) .ToList(); } public void SetConversationId(string conversationId, List states) { _conversationId = conversationId; _state.Load(_conversationId); states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); } }