using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Data.Security; using BeWo.Service.AI; using BeWo.Service.DCEntityMapper; using BeWo.Service.ServiceContracts; using BeWo.Service.ServiceProxy; using BeWo.Service.ServiceUtils; using BS.Shared; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Feature.AI; using BS.Shared.DataContracts.MikePHPContracts; using DevExpress.Drawing.Internal.Interop; using DevExpress.Entity.Model.Metadata; using DevExpress.XtraCharts.Native; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.ExceptionServices; using System.Security.Cryptography; using System.ServiceModel; using System.ServiceModel.Description; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Interop; namespace BeWo.Service.ServiceImplementations { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class AiEnhancedServiceImp : IAiEnhancedService { public AiConfigDC GetAiConfig() { var configs = DAOFactory.GenericDAO.GetAllActive(); var config = configs.FirstOrDefault(); if(config == null) { config = getDefaultAiConfig(); DAOFactory.GenericDAO.Insert(config); } var config_dc = MapperFactory.AiConfig.MapToNewDC(config); return config_dc; } public AiConfigDC UpdateAiConfig(AiConfigDC toUpdate) { if (toUpdate?.Oid is null) throw new InvalidOperationException(); var oid = toUpdate.Oid.Value; var entity = DAOFactory.GenericDAO.LoadByID(oid); var update = MapperFactory.AiConfig.MergeWithEntity(toUpdate, entity); DAOFactory.GenericDAO.Update(update); var dc = MapperFactory.AiConfig.MapToNewDC(update); return dc; } public IEnumerable GetAiModels() { var models = getAiModels(); return MapperFactory.AiModel.MapToNewDCs(models); } public IEnumerable GetAiConversations(int uicontext, long? oid) { // SearchDAO var current_user = UserRightHelper.GetLoggedInUserWithOid(); var convs = DAOFactory.GenericDAO.GetAllActive(); var filter = new List(); foreach (var conv in convs) { if (conv.UIContext != uicontext) continue; if (conv.ApplicationUserOid != current_user.Oid) continue; if (oid is long ref_oid) { var first = conv.ContextBeWoObjects?.FirstOrDefault(); if (first is null) continue; if (first.Oid != ref_oid) continue; } filter.Add(conv); } var dcs = MapperFactory.AiConversation.MapToNewDCs(filter); return dcs; } public AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid) { var conv = CreateAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid); var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv); return conv_dc; } private AiConversation CreateAiConversation(int uicontext, Dictionary context , long modell_oid) { var current_user = UserRightHelper.GetLoggedInUserWithOid(); var system_prompt = AiPromptFactory.CreateSystemInstructions(uicontext, context); var conv = new AiConversation(); conv.Created = DateTime.Now; conv.ContextBeWoObjects = MapperFactory.AiConversation.Parse(context); conv.Displayname = "Displayname"; conv.Messages = new List(); conv.Modell = DAOFactory.GenericDAO.LoadByID(modell_oid); conv.UIContext = uicontext; conv.Updated = DateTime.Now; conv.ApplicationUserOid = current_user.Oid; var msg = new AiConversationMessage(); msg.Message = system_prompt; msg.AiConversation = conv; msg.Role = AiConversationMessageRole.System; msg.Created = DateTime.Now; conv.Messages.Add(msg); DAOFactory.GenericDAO.Insert(conv); return conv; } public AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message) { var conv = CreateAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid); var new_messages = SendNewMessage(conv, message); var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv); return conv_dc; } public AiConversationDC CloneAiConversation(long conversation_oid, long? last_message_oid) { var parent_conv = DAOFactory.GenericDAO.GetByID(conversation_oid); if (parent_conv is null) throw new InvalidOperationException("conv_oid unknown"); var clone_conv = new AiConversation(); clone_conv.Created = DateTime.Now; clone_conv.ContextBeWoObjects = parent_conv.ContextBeWoObjects.ToList(); clone_conv.Displayname = "Klon von " + parent_conv.Displayname; clone_conv.Messages = new List(); clone_conv.Modell = parent_conv.Modell; clone_conv.UIContext = parent_conv.UIContext; clone_conv.Updated = DateTime.Now; clone_conv.ApplicationUserOid = parent_conv.ApplicationUserOid; foreach (var msg in parent_conv.Messages) { var clone_msg = new AiConversationMessage(); clone_msg.Created = msg.Created; clone_msg.Message = msg.Message; clone_msg.Role = msg.Role; clone_msg.Duration = msg.Duration; clone_msg.ModelName = msg.ModelName; clone_conv.Messages.Add(clone_msg); clone_msg.AiConversation = clone_conv; if (msg.Oid == last_message_oid) break; } DAOFactory.GenericDAO.Insert(clone_conv); var dc = MapperFactory.AiConversation.MapToNewDC(clone_conv); return dc; } public void DeleteAiConversation(long conversation_oid) { var conversation = DAOFactory.GenericDAO.LoadByID(conversation_oid); DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted); } public AiConversationMessageDC[] SendNewMessage(long conversation, string message) { var conv = DAOFactory.GenericDAO.LoadByID(conversation); return SendNewMessage(conv, message); } private AiConversationMessageDC[] SendNewMessage(AiConversation conv, string message) { // Updated conv.Updated = DateTime.Now; // Füge Message hinzu var user_msg = new AiConversationMessage(); user_msg.Message = message; user_msg.AiConversation = conv; user_msg.Role = BS.Shared.AiConversationMessageRole.User; user_msg.Created = DateTime.Now; conv.Messages.Add(user_msg); // Update DB Entity // DAOFactory.GenericDAO.Update(conv); var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv); var user_msg_dc = MapperFactory.AiConversationMessage.MapToNewDC(user_msg); // Hole Config var config = GetAiConfig(); // Send Request, wait for Response var dt_before_request = DateTime.Now; var result = ServiceFacade.OpenWebUI.SendAiMessageRequest(conv_dc, config, out var model, out var duration); // Antwort var assi_msg = new AiConversationMessage(); assi_msg.Message = result; assi_msg.AiConversation = conv; assi_msg.Role = BS.Shared.AiConversationMessageRole.Assistent; assi_msg.Created = dt_before_request; assi_msg.Duration = duration ?? 0; assi_msg.ModelName = model; conv.Messages.Add(assi_msg); // Update conv. DAOFactory.GenericDAO.Update(conv); var assi_msg_dc = MapperFactory.AiConversationMessage.MapToNewDC(assi_msg); return new AiConversationMessageDC[] { user_msg_dc, assi_msg_dc }; } private AiConfig getDefaultAiConfig() { var config = new AiConfig(); config.Temperature = 1; config.Top_P = 1; config.Max_Gen_Len = 1000; config.SelectedModel = getDefaultAiModel(); return config; } private AiModel getDefaultAiModel() { var models = getAiModels(); if (models == null || !models.Any()) return null; var llama = models.Where(x => x.ModelName.Contains("llama3.2")); if(llama.Any()) return llama.First(); return models.First(); } private IEnumerable getAiModels() { var old_models = DAOFactory.GenericDAO.GetAll(); var new_models = ServiceFacade.OpenWebUI.GetAiModelle(); var unknown_models = new_models.ToList(); foreach (var old_model in old_models) { bool found = false; foreach (var new_model in new_models) { if (old_model.ModelName == new_model.ModelName) { if (old_model.IsActive != BS.Shared.ActivationTypeId.Active) DAOFactory.GenericDAO.SetActivationType(old_model, BS.Shared.ActivationTypeId.Active); found = true; unknown_models.Remove(new_model); break; } } if (!found) DAOFactory.GenericDAO.Deactivate(old_model); } if (unknown_models.Count != 0) { foreach (var unknown_model in unknown_models) { DAOFactory.GenericDAO.Insert(unknown_model); } } var models = DAOFactory.GenericDAO.GetAllActive(); return models; } } }