661 lines
20 KiB
C#
661 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IdentityModel.Metadata;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Security;
|
|
using System.Security.Cryptography;
|
|
using System.ServiceModel;
|
|
using System.Text;
|
|
using System.Web.Hosting;
|
|
using System.Windows.Interop;
|
|
using AICore.Context.Summary;
|
|
using AICore.Core;
|
|
using AICore.Prompt;
|
|
using AICore.Prompt.SystemPrompts;
|
|
using BeWo.Data.Access;
|
|
using BeWo.Data.Entities;
|
|
using BeWo.Data.Security;
|
|
using BeWo.Service.Core;
|
|
using BeWo.Service.DCEntityMapper;
|
|
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.Feature.AI.Functions.ServiceRecords;
|
|
using BS.Shared.Exceptions;
|
|
using BS.Shared.Extensions;
|
|
using BS.Shared.Interface.Feature.AICore;
|
|
using DevExpress.Charts.Native;
|
|
using DevExpress.CodeParser;
|
|
using DevExpress.DataAccess.Native.Sql;
|
|
using DevExpress.XtraCharts.Native;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace BeWo.Service.Plugins
|
|
{
|
|
public class AiService2
|
|
{
|
|
// Was wird alles benötigt:
|
|
// - WebConfig
|
|
// - DBs
|
|
|
|
// ======================[ Config ]======================
|
|
public virtual AiConfigDC GetAiConfig()
|
|
{
|
|
var configs = DAOFactory.GenericDAO.GetAllActive<AiConfig>();
|
|
|
|
var config = configs.FirstOrDefault();
|
|
|
|
if (config == null)
|
|
{
|
|
config = getDefaultAiConfig();
|
|
|
|
DAOFactory.GenericDAO.Insert(config);
|
|
}
|
|
|
|
if (config.SelectedModel is null)
|
|
{
|
|
config.SelectedModel = getDefaultAiModel();
|
|
}
|
|
|
|
var config_dc = MapperFactory.AiConfig.MapToNewDC(config);
|
|
|
|
return config_dc;
|
|
}
|
|
public virtual 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;
|
|
}
|
|
|
|
// ======================[ Models ]======================
|
|
public virtual IEnumerable<AiModelDC> GetAiModels()
|
|
{
|
|
var models = getAiModels();
|
|
|
|
return MapperFactory.AiModel.MapToNewDCs(models);
|
|
}
|
|
|
|
|
|
// ======================[ Conversations ]======================
|
|
public virtual IEnumerable<AiConversationDC> GetAiConversations(AiActionType actionType, long? oid)
|
|
{
|
|
// SearchDAO
|
|
var current_user = UserRightHelper.GetLoggedInUserWithOid();
|
|
var convs = DAOFactory.GenericDAO.GetAllActive<AiConversation>();
|
|
|
|
var filter = new List<AiConversation>();
|
|
foreach (var conv in convs)
|
|
{
|
|
if (conv.ActionType != actionType)
|
|
continue;
|
|
|
|
if (conv.ApplicationUserOid != current_user.Oid)
|
|
continue;
|
|
|
|
if (oid is long ref_oid)
|
|
{
|
|
var main_ref_obj = conv.ContextBeWoObjects?.FirstOrDefault();
|
|
|
|
// ServiceRecord
|
|
if (actionType == AiActionType.ServiceRecordConversation || actionType == AiActionType.ServiceRecordDocumentation)
|
|
main_ref_obj = conv.ContextBeWoObjects.FirstOrDefault(x => x.Tid == TableID.SupportConcept);
|
|
|
|
if (main_ref_obj?.Oid != ref_oid)
|
|
continue;
|
|
}
|
|
|
|
filter.Add(conv);
|
|
}
|
|
|
|
var dcs = MapperFactory.AiConversation.MapToNewDCs(filter);
|
|
|
|
return dcs;
|
|
}
|
|
|
|
public virtual AiConversationDC CreateAiConversation(AiConversationDC conversation, AiViewContextDC view_context)
|
|
{
|
|
var conv = createAiConversation(conversation.ActionType, view_context, null);
|
|
|
|
if (conversation.ReferencePrompt?.Oid is long oid2)
|
|
conv.ReferencePrompt = DAOFactory.GenericDAO.LoadByID<AiPromptbausteinPrompt>(oid2);
|
|
|
|
if (conversation.ReferenceRoutine?.Oid is long oid3)
|
|
conv.ReferenceRoutine = DAOFactory.GenericDAO.LoadByID<AiPromptbausteinRoutine>(oid3);
|
|
|
|
DAOFactory.GenericDAO.Insert(conv);
|
|
|
|
var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv);
|
|
|
|
return conv_dc;
|
|
}
|
|
public virtual AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, AiViewContextDC view_context, string message)
|
|
{
|
|
var config = GetAiConfig();
|
|
|
|
var conv = createAiConversation(conversation.ActionType, view_context, config);
|
|
|
|
addSystemPrompt(conv, view_context);
|
|
|
|
sendNewMessage(conv, message, false);
|
|
|
|
DAOFactory.GenericDAO.Insert(conv);
|
|
|
|
var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv);
|
|
|
|
return conv_dc;
|
|
}
|
|
//public AiConversationDC CreateAiConversationWithPromptbaustein(AiConversationDC conversation, AiViewContextDC view_context, long oid)
|
|
//{
|
|
// var config = GetAiConfig();
|
|
|
|
// var conv = createAiConversation(conversation.ActionType, view_context, config);
|
|
|
|
// var promptbaustein = DAOFactory.GenericDAO.LoadByID<AiPromptbausteinPrompt>(oid);
|
|
|
|
// var new_messages = sendNewMessage(conv, promptbaustein.Prompt, config);
|
|
|
|
// DAOFactory.GenericDAO.Insert(conv);
|
|
|
|
// var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv);
|
|
|
|
// return conv_dc;
|
|
//}
|
|
public virtual 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.ActionType = parent_conv.ActionType;
|
|
clone_conv.Updated = DateTime.Now;
|
|
clone_conv.ApplicationUserOid = parent_conv.ApplicationUserOid;
|
|
|
|
if (last_message_oid is null)
|
|
last_message_oid = parent_conv.Messages[0].Oid;
|
|
|
|
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_msg.ShowMessage = msg.ShowMessage;
|
|
clone_msg.UsedPromptbausteinTitle = msg.UsedPromptbausteinTitle;
|
|
|
|
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 virtual long UpdateAiConversationDisplayname(long oid, long version, string displayname)
|
|
{
|
|
var conv = DAOFactory.GenericDAO.GetByID<AiConversation>(oid);
|
|
|
|
ServiceLogic.ConcurrencyCheck(version, conv);
|
|
|
|
conv.Displayname = displayname;
|
|
|
|
DAOFactory.GenericDAO.Update(conv);
|
|
|
|
return conv.Version.Value;
|
|
}
|
|
|
|
public virtual void DeleteAiConversation(long conversation_oid)
|
|
{
|
|
var conversation = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation_oid);
|
|
|
|
DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted);
|
|
}
|
|
|
|
// ======================[ Conversationmessages ]======================
|
|
public virtual AiConversationMessageDC[] SendNewMessage(long conversation, string message)
|
|
{
|
|
var conv = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation);
|
|
|
|
return sendNewMessage(conv, message, true);
|
|
}
|
|
|
|
public virtual AiConversationMessageDC[] ExecuteAiConversationWithPrompt(long conversation, AiViewContextDC view_context, long prompt_oid)
|
|
{
|
|
return executePrompt(conversation, view_context, prompt_oid, AiRoutineType.Stack);
|
|
}
|
|
|
|
public virtual AiConversationMessageDC[] ExecuteAiConversationWithRoutine(long conversation, AiViewContextDC view_context, long routine, int step)
|
|
{
|
|
var conv = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation);
|
|
|
|
var routine_ent = DAOFactory.GenericDAO.LoadByID<AiPromptbausteinRoutine>(routine);
|
|
|
|
var step_ent = routine_ent.Steps[step];
|
|
|
|
var prompt = step_ent.PromptReference;
|
|
|
|
return executePrompt(conversation, view_context, prompt.Oid.Value, routine_ent.RoutineType);
|
|
}
|
|
|
|
public virtual bool CheckContextSize(AiActionType actionType, AiViewContextDC view_context)
|
|
{
|
|
var modell_oid_value = GetAiConfig().SelectedModel.Oid.Value;
|
|
|
|
var modell = DAOFactory.GenericDAO.LoadByID<AiModel>(modell_oid_value);
|
|
|
|
if (modell.Value < 0)
|
|
return true;
|
|
|
|
var conversation = createAiConversation(actionType, view_context);
|
|
|
|
addSystemPrompt(conversation, view_context);
|
|
|
|
var messages2 = conversation.Messages.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Message }).ToList();
|
|
|
|
return ContextSizeAnalyzer.CheckContextSize(messages2, modell.Value, ContextSizeAnalyzeMode.InitContextSize, out var token_count);
|
|
}
|
|
|
|
public virtual AiUserSettingDC GetUserSetting()
|
|
{
|
|
var usersetting = getCurrentAiUserSetting();
|
|
|
|
var usersetting_dc = MapperFactory.AiUserSetting.MapToNewDC(usersetting);
|
|
|
|
return usersetting_dc;
|
|
}
|
|
|
|
public virtual AiUserSettingDC UpdateUserSetting(AiUserSettingDC aiUserSettingDC)
|
|
{
|
|
var usersetting = getCurrentAiUserSetting();
|
|
|
|
MapperFactory.AiUserSetting.MergeWithEntity(aiUserSettingDC, usersetting);
|
|
|
|
DAOFactory.GenericDAO.Update(usersetting);
|
|
|
|
var new_dc = MapperFactory.AiUserSetting.MapToNewDC(usersetting);
|
|
|
|
return new_dc;
|
|
}
|
|
|
|
// ======================[ private ]======================
|
|
protected virtual AiConfig getDefaultAiConfig()
|
|
{
|
|
var config = new AiConfig();
|
|
|
|
config.Temperature = 1;
|
|
config.Top_P = 1;
|
|
config.Max_Gen_Len = 1000;
|
|
config.SelectedModel = getDefaultAiModel();
|
|
|
|
return config;
|
|
}
|
|
protected virtual AiModel getDefaultAiModel()
|
|
{
|
|
var models = getAiModels();
|
|
|
|
Func<AiModel, bool>[] conditions = new Func<AiModel, bool>[]
|
|
{
|
|
x => x.ModelSource == AiModelSource.ollama2,
|
|
x => x.ModelName.Contains("gemma3"),
|
|
x => x.ModelName.Contains("max"),
|
|
x => x.ModelName.Contains("context"),
|
|
x => x.ModelName.Contains("12b")
|
|
};
|
|
|
|
for (int i = conditions.Length; i > 0; i--)
|
|
{
|
|
var match = models.FirstOrDefault(m => conditions.Take(i).All(c => c(m)));
|
|
if (match != null)
|
|
return match;
|
|
}
|
|
|
|
return models.First();
|
|
}
|
|
protected virtual IEnumerable<AiModel> getAiModels()
|
|
{
|
|
var current_models = DAOFactory.GenericDAO.GetAll<AiModel>();
|
|
var current_models_actives = current_models.Where(x => x.IsActive == ActivationTypeId.Active);
|
|
var current_models_deactives = current_models.Where(x => x.IsActive != ActivationTypeId.Active);
|
|
var actives_llm_clients = ServiceFacade.GetActiveApiClients();
|
|
var actives_llm_clients_models = actives_llm_clients.SelectMany(x => x.GetAiModelle().GetResponseData());
|
|
var request_models = MapperFactory.AiModel.MapToNewEntities(actives_llm_clients_models);
|
|
//var request_models_dc_owui = ServiceFacade.OpenWebApiClient.GetAiModelle().GetResponseData();
|
|
//var request_models_dc = request_models_dc_ollama.Union(request_models_dc_owui);
|
|
//var request_models = MapperFactory.AiModel.MapToNewEntities(request_models_dc);
|
|
|
|
var toadd = request_models.Except(current_models);
|
|
var toremove = current_models_actives.Except(request_models);
|
|
var toreadd = current_models_deactives.Intersect(request_models);
|
|
|
|
DAOFactory.GenericDAO.Insert(toadd);
|
|
DAOFactory.GenericDAO.Deactivate(toremove);
|
|
DAOFactory.GenericDAO.SetActivationType(toreadd, ActivationTypeId.Active);
|
|
|
|
var models = DAOFactory.GenericDAO.GetAllActive<AiModel>();
|
|
return models;
|
|
}
|
|
|
|
protected virtual AiConversation createAiConversation(AiActionType actionType, AiViewContextDC view_context, AiConfigDC config = null)
|
|
{
|
|
if (config is null)
|
|
config = GetAiConfig();
|
|
|
|
var context_Type = config.Context_Type;
|
|
var modell_oid = config.SelectedModel.Oid.Value;
|
|
|
|
var current_user = UserRightHelper.GetLoggedInUserWithOid();
|
|
|
|
var conv = new AiConversation();
|
|
conv.Created = DateTime.Now;
|
|
|
|
// RETODO Muss noch bzgl Sicherheit geprüft werden.
|
|
conv.ContextBeWoObjects = MapperFactory.AiConversation.Parse(view_context.References);
|
|
conv.Displayname = "Neue Unterhaltung";
|
|
conv.Messages = new List<AiConversationMessage>();
|
|
conv.Modell = DAOFactory.GenericDAO.LoadByID<AiModel>(modell_oid);
|
|
conv.ActionType = actionType;
|
|
conv.ContextType = context_Type;
|
|
conv.Updated = DateTime.Now;
|
|
conv.ApplicationUserOid = current_user.Oid;
|
|
|
|
return conv;
|
|
}
|
|
|
|
protected virtual AiConversationMessage addSystemPrompt(AiConversation conversation, AiViewContextDC view_context, AiConfigDC config = null, AiPromptbausteinPrompt prompt = null)
|
|
{
|
|
if (config is null)
|
|
config = GetAiConfig();
|
|
|
|
var actionType = conversation.ActionType;
|
|
var context_Type = config.Context_Type;
|
|
|
|
var sampleCount = prompt?.SamplesCount;
|
|
if (prompt is object && !prompt.IsOwnsoftPrompt)
|
|
{
|
|
sampleCount = null;
|
|
}
|
|
|
|
var context_loaded = AiContextLoader.LoadContext(actionType, view_context, sampleCount);
|
|
var configPath = getPromptPath(actionType);
|
|
var system_prompt = AiSystemPromptFactory.BuildContext(actionType, configPath, view_context, context_loaded, context_Type);
|
|
|
|
var msg = new AiConversationMessage();
|
|
msg.Message = system_prompt;
|
|
msg.AiConversation = conversation;
|
|
msg.Role = AiConversationMessageRole.System;
|
|
msg.Created = DateTime.Now;
|
|
msg.ShowMessage = true;
|
|
|
|
conversation.Messages.Add(msg);
|
|
|
|
return msg;
|
|
}
|
|
|
|
protected virtual AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message, bool save = true, bool show_message = true, string used_promptbaustein_title = null)
|
|
{
|
|
CheckPermissions(conv.ActionType);
|
|
|
|
IAiModel configModel = conv.Modell;
|
|
if (configModel == null)
|
|
{
|
|
configModel = GetAiConfig().SelectedModel;
|
|
}
|
|
|
|
var configModelName = configModel.ModelName;
|
|
var configMaxContextWindow = configModel.Value;
|
|
var logger = ServiceLogger.GetRequestLogger(out string id);
|
|
|
|
// 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;
|
|
user_msg.ShowMessage = show_message;
|
|
user_msg.UsedPromptbausteinTitle = used_promptbaustein_title;
|
|
|
|
conv.Messages.Add(user_msg);
|
|
|
|
// Build Payload
|
|
var messages2send = new List<AiConversationMessage>();
|
|
bool systemPromptAdded = false;
|
|
foreach (var msg in conv.Messages)
|
|
{
|
|
if (msg.Role == AiConversationMessageRole.System)
|
|
{
|
|
if (systemPromptAdded)
|
|
continue;
|
|
|
|
systemPromptAdded = true;
|
|
}
|
|
|
|
messages2send.Add(msg);
|
|
}
|
|
|
|
if (!systemPromptAdded)
|
|
{
|
|
throw new Exception("sp not found - invalid request");
|
|
}
|
|
|
|
var messages2 = messages2send.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Message }).ToList();
|
|
|
|
var payload = new
|
|
{
|
|
model = configModelName,
|
|
messages = messages2,
|
|
customerid = UserRightHelper.GetTenant(),
|
|
requestid = id
|
|
};
|
|
|
|
int estimated_tokens = 0;
|
|
|
|
var mode = conv.Messages.Count <= 2 ? ContextSizeAnalyzeMode.FirstMessage : ContextSizeAnalyzeMode.ConversationMessage;
|
|
|
|
var success = ContextSizeAnalyzer.CheckContextSize(messages2, configMaxContextWindow, mode, out estimated_tokens);
|
|
|
|
if (!success)
|
|
{
|
|
var error = $"send error: windowsize exceeded ({estimated_tokens}/{configMaxContextWindow} (mode:{mode}))";
|
|
|
|
throw new BeWoInvalidOperationException(error);
|
|
}
|
|
|
|
// Update DB Entity
|
|
// DAOFactory.GenericDAO.Update(conv);
|
|
|
|
var conv_dc = MapperFactory.AiConversation.MapToNewDC(conv);
|
|
var user_msg_dc = MapperFactory.AiConversationMessage.MapToNewDC(user_msg);
|
|
|
|
// Send Request, wait for Response
|
|
var dt_before_request = DateTime.Now;
|
|
|
|
var client = ServiceFacade.GetLLMApiClientByConfig(configModel.ModelSource);
|
|
|
|
var response = client.SendAiMessageRequest(payload, out var llm_response, logger);
|
|
|
|
var result = response.GetResponseData();
|
|
|
|
if (llm_response.PromptEvalCount is int prompt_eval_count &&
|
|
llm_response.EvalCount is int eval_count)
|
|
{
|
|
if (ContextSizeAnalyzer.CheckForTruncation(estimated_tokens, prompt_eval_count))
|
|
{
|
|
throw new BeWoInvalidOperationException($"send error: truncation ({estimated_tokens}/{llm_response.PromptEvalCount.Value})");
|
|
}
|
|
|
|
if (!ContextSizeAnalyzer.CheckForValidAssistent(eval_count, prompt_eval_count, configMaxContextWindow))
|
|
{
|
|
throw new BeWoInvalidOperationException($"send error: assist check failed: ({eval_count}/{prompt_eval_count}/{configMaxContextWindow})");
|
|
}
|
|
}
|
|
|
|
// Antwort
|
|
var assi_msg = new AiConversationMessage();
|
|
assi_msg.Message = llm_response.Message;
|
|
assi_msg.AiConversation = conv;
|
|
assi_msg.Role = BS.Shared.AiConversationMessageRole.Assistent;
|
|
assi_msg.Created = dt_before_request;
|
|
assi_msg.Duration = llm_response.Duration ?? 0;
|
|
assi_msg.ModelName = llm_response.Model;
|
|
assi_msg.ShowMessage = true;
|
|
|
|
conv.Messages.Add(assi_msg);
|
|
|
|
// Update conv.
|
|
if (save)
|
|
DAOFactory.GenericDAO.Update(conv);
|
|
|
|
var assi_msg_dc = MapperFactory.AiConversationMessage.MapToNewDC(assi_msg);
|
|
|
|
return new AiConversationMessageDC[] { user_msg_dc, assi_msg_dc };
|
|
}
|
|
|
|
protected virtual AiUserSetting getCurrentAiUserSetting()
|
|
{
|
|
var current_user = UserRightHelper.GetLoggedInUser();
|
|
|
|
var usersetting = DAOFactory.GenericSearchDAO.LoadEntityByProperty<AiUserSetting>(nameof(AiUserSetting.Oid), current_user.Oid);
|
|
|
|
if (usersetting == null)
|
|
{
|
|
var new_usersetting = new AiUserSettingDC();
|
|
|
|
usersetting = MapperFactory.AiUserSetting.MapToNewEntity(new_usersetting);
|
|
|
|
DAOFactory.GenericDAO.Insert(usersetting);
|
|
}
|
|
|
|
return usersetting;
|
|
}
|
|
|
|
private string getPromptPath(AiActionType actionType)
|
|
{
|
|
SpecialConfig? specialConfig = null;
|
|
|
|
switch (actionType)
|
|
{
|
|
case AiActionType.ServiceRecord:
|
|
break;
|
|
case AiActionType.ServiceRecordConversation:
|
|
specialConfig = SpecialConfig.CustomPreSystemPrompt;
|
|
break;
|
|
case AiActionType.ServiceRecordDocumentation:
|
|
specialConfig = SpecialConfig.CustomFunctionPreSystemPrompt;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (specialConfig == null)
|
|
throw BeWoNotImplementedException.CreateFromEnum(actionType);
|
|
|
|
var path = ConfigReader.GetConfigPath(specialConfig.Value);
|
|
|
|
return path;
|
|
}
|
|
private void CheckPermissions(AiActionType actionType)
|
|
{
|
|
UserRightType userRightType;
|
|
|
|
if (actionType == AiActionType.ServiceRecordConversation)
|
|
{
|
|
userRightType = UserRightType.AiModuleServiceRecordChat;
|
|
}
|
|
else if (actionType == AiActionType.ServiceRecordDocumentation)
|
|
{
|
|
userRightType = UserRightType.AiModuleServiceRecordDocu;
|
|
}
|
|
else
|
|
{
|
|
throw BeWoNotImplementedException.CreateFromEnum(actionType);
|
|
}
|
|
|
|
if (!UserRightHelper.LoggedInUserHasRight(userRightType))
|
|
{
|
|
throw new SecurityException("Invalid permissions");
|
|
}
|
|
}
|
|
|
|
private AiConversationMessageDC[] executePrompt(long conversation_oid, AiViewContextDC view_context, long prompt_oid, AiRoutineType aiRoutineType)
|
|
{
|
|
var ai_config = GetAiConfig();
|
|
|
|
var conversation = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation_oid);
|
|
var prompt = DAOFactory.GenericDAO.LoadByID<AiPromptbausteinPrompt>(prompt_oid);
|
|
|
|
var new_conv = createAiConversation(conversation.ActionType, view_context, ai_config);
|
|
var systemPrompt = addSystemPrompt(new_conv, view_context, ai_config, prompt);
|
|
var systemPromptDc = MapperFactory.AiConversationMessage.MapToNewDC(systemPrompt);
|
|
|
|
if (aiRoutineType == AiRoutineType.Chain)
|
|
{
|
|
// Conversation = (S(n), U(n)) => A(n)
|
|
}
|
|
else if (aiRoutineType == AiRoutineType.Stack)
|
|
{
|
|
// Conversation = (S(n), U(0), A(0), U(1), ..., U(n-1), A(n-1), U(n)) => A(n)
|
|
var messages_filtered = conversation.Messages.Where(m => m.Role != AiConversationMessageRole.System);
|
|
|
|
new_conv.Messages.AddRange(messages_filtered);
|
|
}
|
|
else
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(aiRoutineType));
|
|
}
|
|
|
|
// Server Request
|
|
sendNewMessage(new_conv, prompt.Prompt, false, false, prompt.Title).ToList();
|
|
|
|
var result = new List<AiConversationMessage>
|
|
{
|
|
systemPrompt,
|
|
new_conv.Messages.Last(x => x.Role == AiConversationMessageRole.User),
|
|
new_conv.Messages.Last(x => x.Role == AiConversationMessageRole.Assistent)
|
|
};
|
|
|
|
// Nachrichten in Konversation packen
|
|
foreach (var msg in result)
|
|
{
|
|
msg.AiConversation = conversation;
|
|
conversation.Messages.Add(msg);
|
|
}
|
|
DAOFactory.GenericDAO.Update(conversation);
|
|
|
|
return MapperFactory.AiConversationMessage.MapToNewDCs(result).ToArray();
|
|
}
|
|
}
|
|
} |