Files
BeWoPlaner/Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs

321 lines
8.8 KiB
C#
Raw Normal View History

2025-04-14 12:17:09 +02:00
using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Data.Security;
2025-04-15 16:28:17 +02:00
using BeWo.Service.AI;
2025-04-14 12:17:09 +02:00
using BeWo.Service.DCEntityMapper;
2025-06-02 11:16:35 +02:00
using BeWo.Service.ServiceContracts.Enhanced;
2025-04-14 12:17:09 +02:00
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;
2025-04-14 12:17:09 +02:00
using DevExpress.Entity.Model.Metadata;
2025-04-22 14:05:51 +02:00
using DevExpress.XtraCharts.Native;
2025-04-14 12:17:09 +02:00
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
2025-05-05 13:08:09 +02:00
using System.Runtime.ExceptionServices;
2025-04-14 12:17:09 +02:00
using System.Security.Cryptography;
using System.ServiceModel;
2025-05-13 11:10:24 +02:00
using System.ServiceModel.Description;
2025-04-14 12:17:09 +02:00
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Interop;
2025-04-14 12:17:09 +02:00
2025-06-02 11:16:35 +02:00
namespace BeWo.Service.ServiceImplementations.Enhanced
2025-04-14 12:17:09 +02:00
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class AiEnhancedServiceImp : IAiEnhancedService
{
public AiConfigDC GetAiConfig()
{
var configs = DAOFactory.GenericDAO.GetAllActive<AiConfig>();
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<AiConfig>(oid);
var update = MapperFactory.AiConfig.MergeWithEntity(toUpdate, entity);
DAOFactory.GenericDAO.Update(update);
var dc = MapperFactory.AiConfig.MapToNewDC(update);
return dc;
}
public IEnumerable<AiModelDC> GetAiModels()
{
var models = getAiModels();
return MapperFactory.AiModel.MapToNewDCs(models);
}
2025-05-05 13:08:09 +02:00
public IEnumerable<AiConversationDC> GetAiConversations(int uicontext, long? oid)
2025-04-14 12:17:09 +02:00
{
// SearchDAO
var current_user = UserRightHelper.GetLoggedInUserWithOid();
2025-04-24 16:03:56 +02:00
var convs = DAOFactory.GenericDAO.GetAllActive<AiConversation>();
2025-05-05 13:08:09 +02:00
var filter = new List<AiConversation>();
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);
}
2025-04-14 12:17:09 +02:00
var dcs = MapperFactory.AiConversation.MapToNewDCs(filter);
return dcs;
}
public AiConversationDC CreateAiConversation(AiConversationDC conversation, long modell_oid)
{
2025-05-13 11:10:24 +02:00
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<TableID, long[]> context , long modell_oid) {
2025-04-14 12:17:09 +02:00
var current_user = UserRightHelper.GetLoggedInUserWithOid();
2025-05-13 11:10:24 +02:00
var system_prompt = AiPromptFactory.CreateSystemInstructions(uicontext, context);
2025-04-14 12:17:09 +02:00
var conv = new AiConversation();
conv.Created = DateTime.Now;
2025-05-13 11:10:24 +02:00
conv.ContextBeWoObjects = MapperFactory.AiConversation.Parse(context);
2025-04-14 12:17:09 +02:00
conv.Displayname = "Displayname";
conv.Messages = new List<AiConversationMessage>();
conv.Modell = DAOFactory.GenericDAO.LoadByID<AiModel>(modell_oid);
2025-05-13 11:10:24 +02:00
conv.UIContext = uicontext;
2025-04-14 12:17:09 +02:00
conv.Updated = DateTime.Now;
conv.ApplicationUserOid = current_user.Oid;
var msg = new AiConversationMessage();
2025-04-14 15:06:00 +02:00
msg.Message = system_prompt;
2025-04-14 12:17:09 +02:00
msg.AiConversation = conv;
2025-05-13 11:10:24 +02:00
msg.Role = AiConversationMessageRole.System;
2025-04-14 12:17:09 +02:00
msg.Created = DateTime.Now;
conv.Messages.Add(msg);
DAOFactory.GenericDAO.Insert(conv);
2025-05-13 11:10:24 +02:00
return conv;
}
2025-04-14 12:17:09 +02:00
2025-05-13 11:10:24 +02:00
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;
2025-04-14 12:17:09 +02:00
}
2025-05-13 11:10:24 +02:00
2025-04-22 14:05:51 +02:00
public AiConversationDC CloneAiConversation(long conversation_oid, long? last_message_oid)
{
var parent_conv = DAOFactory.GenericDAO.GetByID<AiConversation>(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<AiConversationMessage>();
clone_conv.Modell = parent_conv.Modell;
clone_conv.UIContext = parent_conv.UIContext;
2025-05-05 11:01:34 +02:00
clone_conv.Updated = DateTime.Now;
2025-04-22 14:05:51 +02:00
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;
2025-04-22 14:05:51 +02:00
if (msg.Oid == last_message_oid)
break;
}
DAOFactory.GenericDAO.Insert(clone_conv);
var dc = MapperFactory.AiConversation.MapToNewDC(clone_conv);
return dc;
}
2025-04-24 16:02:13 +02:00
public void DeleteAiConversation(long conversation_oid)
{
var conversation = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation_oid);
2025-04-24 16:03:56 +02:00
DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted);
2025-04-24 16:02:13 +02:00
}
2025-04-22 14:05:51 +02:00
2025-04-14 12:17:09 +02:00
public AiConversationMessageDC[] SendNewMessage(long conversation, string message)
{
var conv = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation);
2025-05-13 11:10:24 +02:00
return SendNewMessage(conv, message);
}
private AiConversationMessageDC[] SendNewMessage(AiConversation conv, string message)
{
2025-04-14 12:17:09 +02:00
// 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);
2025-04-14 12:17:09 +02:00
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;
2025-05-07 11:24:53 +02:00
var llama = models.Where(x => x.ModelName.Contains("llama3.2"));
if(llama.Any())
return llama.First();
2025-04-14 12:17:09 +02:00
return models.First();
}
private IEnumerable<AiModel> getAiModels()
{
var old_models = DAOFactory.GenericDAO.GetAll<AiModel>();
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<AiModel>();
return models;
}
2025-04-22 14:05:51 +02:00
2025-04-14 12:17:09 +02:00
}
}