diff --git a/Host/Web.config b/Host/Web.config
index 480e8f19a..7e12ffae7 100644
--- a/Host/Web.config
+++ b/Host/Web.config
@@ -310,6 +310,8 @@
+
+
diff --git a/Service/Plugins/AiService2.cs b/Service/Plugins/AiService2.cs
new file mode 100644
index 000000000..b1e08228c
--- /dev/null
+++ b/Service/Plugins/AiService2.cs
@@ -0,0 +1,387 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.ServiceModel;
+using System.Text;
+using BeWo.Data.Access;
+using BeWo.Data.Entities;
+using BeWo.Data.Security;
+using BeWo.Service.AI;
+using BeWo.Service.Core;
+using BeWo.Service.DCEntityMapper;
+using BeWo.Service.Invoicing;
+using BeWo.Service.ServiceContracts;
+using BeWo.Service.ServiceProxy;
+using BS.Shared;
+using BS.Shared.Core;
+using BS.Shared.DataContracts;
+using BS.Shared.DataContracts.Compact;
+using BS.Shared.DataContracts.Feature.AI;
+using BS.Shared.Extensions;
+using Microsoft.ML.Tokenizers;
+using Newtonsoft.Json;
+
+namespace BeWo.Service.Plugins
+{
+ public class AiService2
+ {
+ // Was wird alles benötigt:
+ // - WebConfig
+ // - DBs
+
+ // ======================[ Config ]======================
+ 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;
+ }
+
+ // ======================[ Models ]======================
+ public IEnumerable GetAiModels()
+ {
+ var models = getAiModels();
+
+ return MapperFactory.AiModel.MapToNewDCs(models);
+ }
+
+
+ // ======================[ Conversations ]======================
+ 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 main_ref_obj = conv.ContextBeWoObjects?.FirstOrDefault();
+
+ // ServiceRecord
+ if (uicontext == 19)
+ 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 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;
+ }
+ 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;
+
+ 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_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 long UpdateAiConversationDisplayname(long oid, long version, string displayname)
+ {
+ var conv = DAOFactory.GenericDAO.GetByID(oid);
+
+ ServiceLogic.ConcurrencyCheck(version, conv);
+
+ conv.Displayname = displayname;
+
+ DAOFactory.GenericDAO.Update(conv);
+
+ return conv.Version.Value;
+ }
+
+ public void DeleteAiConversation(long conversation_oid)
+ {
+ var conversation = DAOFactory.GenericDAO.LoadByID(conversation_oid);
+
+ DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted);
+ }
+
+ // ======================[ Conversationmessages ]======================
+ public AiConversationMessageDC[] SendNewMessage(long conversation, string message)
+ {
+ var conv = DAOFactory.GenericDAO.LoadByID(conversation);
+
+ return sendNewMessage(conv, message);
+ }
+
+
+ // ======================[ private ]======================
+ 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.OpenWebApiClient.GetAiModelle().GetResponseData();
+ 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;
+ }
+
+ 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 = "Neue Unterhaltung";
+ 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;
+ }
+
+ private AiConversationMessageDC[] sendNewMessage(AiConversation conv, string message)
+ {
+ // Hole Config
+ var config = GetAiConfig();
+ var configModelName = config.SelectedModel.ModelName;
+
+ // Build Payload
+ var payload = new
+ {
+ model = configModelName,
+ messages = conv.Messages.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Message })
+ };
+
+ // Check Token Size
+ checkTokenSize(conv.Messages, configModelName);
+
+ // 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);
+
+ // Send Request, wait for Response
+ var dt_before_request = DateTime.Now;
+ var response = ServiceFacade.OpenWebApiClient.SendAiMessageRequest(payload, out var message2, out var model, out var duration);
+
+ if (!response.Success)
+ {
+ var json = JsonConvert.SerializeObject(response.Copy());
+ File.WriteAllText(MergedConfig.GetSetting("AiServiceLogFilePath"), json);
+ }
+
+ var result = response.GetResponseData();
+
+ // Antwort
+ var assi_msg = new AiConversationMessage();
+ assi_msg.Message = message2;
+ 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 void checkTokenSize(IList messages, string configModelName)
+ {
+ Tokenizer tokenizer = TiktokenTokenizer.CreateForModel(configModelName);
+
+ int tokens = countChatTokens(messages, tokenizer);
+ }
+
+ private int countChatTokens(IList messages, Tokenizer tokenizer)
+ {
+ int tokensPerMessage = 4; // OpenAI Overhead
+ int tokensPerReply = 2;
+
+ int total = 0;
+
+ foreach (var msg in messages)
+ {
+ total += tokensPerMessage;
+ total += tokenizer.CountTokens(msg.Role.ToString());
+ total += tokenizer.CountTokens(msg.Message);
+ }
+
+ return total + tokensPerReply;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Service/Service.csproj b/Service/Service.csproj
index 409e26c61..592076b4a 100644
--- a/Service/Service.csproj
+++ b/Service/Service.csproj
@@ -457,6 +457,7 @@
+
diff --git a/Service/ServiceImplementations/AiEnhancedServiceImp.cs b/Service/ServiceImplementations/AiEnhancedServiceImp.cs
index 9aad7bf69..f84df5952 100644
--- a/Service/ServiceImplementations/AiEnhancedServiceImp.cs
+++ b/Service/ServiceImplementations/AiEnhancedServiceImp.cs
@@ -5,6 +5,7 @@ using BeWo.Data.Security;
using BeWo.Service.AI;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
+using BeWo.Service.Plugins;
using BeWo.Service.ServiceContracts;
using BeWo.Service.ServiceProxy;
using BS.Shared;
@@ -22,6 +23,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.ExceptionServices;
+using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Description;
@@ -35,325 +37,58 @@ namespace BeWo.Service.ServiceImplementations
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class AiEnhancedServiceImp : IAiEnhancedService
{
- // Was wird alles benötigt:
- // - WebConfig
- // - DBs
-
- // ======================[ Config ]======================
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;
+ var p = PluginLoader.FindClass();
+ return p.GetAiConfig();
}
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;
+ var p = PluginLoader.FindClass();
+ return p.UpdateAiConfig(toUpdate);
}
- // ======================[ Models ]======================
public IEnumerable GetAiModels()
{
- var models = getAiModels();
-
- return MapperFactory.AiModel.MapToNewDCs(models);
+ var p = PluginLoader.FindClass();
+ return p.GetAiModels();
}
-
-
- // ======================[ Conversations ]======================
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 main_ref_obj = conv.ContextBeWoObjects?.FirstOrDefault();
-
- // ServiceRecord
- if (uicontext == 19)
- 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;
+ var p = PluginLoader.FindClass();
+ return p.GetAiConversations(uicontext, oid);
}
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;
+ var p = PluginLoader.FindClass();
+ return p.CreateAiConversation(conversation, modell_oid);
}
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;
+ var p = PluginLoader.FindClass();
+ return p.CreateAiConversationWithMessage(conversation, modell_oid, message);
}
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;
-
- 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_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;
+ var p = PluginLoader.FindClass();
+ return p.CloneAiConversation(conversation_oid, last_message_oid);
}
-
public long UpdateAiConversationDisplayname(long oid, long version, string displayname)
{
- var conv = DAOFactory.GenericDAO.GetByID(oid);
-
- ServiceLogic.ConcurrencyCheck(version, conv);
-
- conv.Displayname = displayname;
-
- DAOFactory.GenericDAO.Update(conv);
-
- return conv.Version.Value;
+ var p = PluginLoader.FindClass();
+ return p.UpdateAiConversationDisplayname(oid, version, displayname);
}
-
public void DeleteAiConversation(long conversation_oid)
{
- var conversation = DAOFactory.GenericDAO.LoadByID(conversation_oid);
-
- DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted);
+ var p = PluginLoader.FindClass();
+ p.DeleteAiConversation(conversation_oid);
}
- // ======================[ Conversationmessages ]======================
public AiConversationMessageDC[] SendNewMessage(long conversation, string message)
{
- var conv = DAOFactory.GenericDAO.LoadByID(conversation);
-
- return SendNewMessage(conv, message);
- }
-
-
- // ======================[ private ]======================
- 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.OpenWebApiClient.GetAiModelle().GetResponseData();
- 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;
- }
-
- 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 = "Neue Unterhaltung";
- 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;
- }
-
- 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 response = ServiceFacade.OpenWebApiClient.SendAiMessageRequest(conv_dc, config, out var message2, out var model, out var duration);
-
- if (!response.Success)
- {
- var json = JsonConvert.SerializeObject(response.Copy());
- File.WriteAllText(MergedConfig.GetSetting("AiServiceLogFilePath"), json);
- }
-
- var result = response.GetResponseData();
-
- // Antwort
- var assi_msg = new AiConversationMessage();
- assi_msg.Message = message2;
- 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 };
+ var p = PluginLoader.FindClass();
+ return p.SendNewMessage(conversation, message);
}
}
}
diff --git a/Service/ServiceProxy/OpenWebApiClient.cs b/Service/ServiceProxy/OpenWebApiClient.cs
index ee5923648..9fad4453d 100644
--- a/Service/ServiceProxy/OpenWebApiClient.cs
+++ b/Service/ServiceProxy/OpenWebApiClient.cs
@@ -18,6 +18,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
+using System.Text.Json.Nodes;
using System.Threading.Tasks;
using static DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper;
@@ -62,7 +63,7 @@ namespace BeWo.Service.ServiceProxy
return ApiResponse>.SuccessResponse(data);
}
- public ApiResponse SendAiMessageRequest(AiConversationDC conversation, AiConfigDC config, out string message, out string model, out int? duration)
+ public ApiResponse SendAiMessageRequest(dynamic payload, out string message, out string model, out int? duration)
{
message = null;
duration = null;
@@ -70,12 +71,6 @@ namespace BeWo.Service.ServiceProxy
var sub_url = "api/chat/completions";
- var payload = new
- {
- model = config.SelectedModel.ModelName,
- messages = conversation.Messages.Select(m => new { role = m.Role.ToString().ToLower(), content = m.Message })
- };
-
var response_format = new
{
id = string.Empty,
@@ -101,6 +96,17 @@ namespace BeWo.Service.ServiceProxy
_PostClientFacade.JsonObject = payload;
+ if (MergedConfig.GetSetting("AiServiceLastRequestEnabled") is string str && bool.TryParse(str, out bool b) && b)
+ {
+ var path = MergedConfig.GetSetting("AiServiceLastRequestFilePath");
+ if (Directory.GetParent(path) == null)
+ throw new ArgumentException("AiServiceLastRequestFilePath ungültig");
+
+ var payload_ser = JsonConvert.SerializeObject(_PostClientFacade.JsonObject, Formatting.Indented);
+
+ File.WriteAllText(path, payload_ser);
+ }
+
var response = _PostClientFacade.GetAnonymousTypeAsync(sub_url, response_format, _ErrorExtractor).GetAwaiter().GetResult();
if (!response.Success)