520 lines
13 KiB
C#
520 lines
13 KiB
C#
using BeWo.Core;
|
|
using BeWo.ServiceProxy;
|
|
using BS.Shared;
|
|
using BS.Shared.DataContracts;
|
|
using BS.Shared.DataContracts.Feature.AI;
|
|
using BS.Shared.Extensions;
|
|
using ChatController.Utilities.Extensions;
|
|
using DevExpress.Mvvm;
|
|
using DevExpress.Xpf.Editors;
|
|
using DevExpress.XtraPrinting.Native;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Runtime.Remoting.Contexts;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using System.Windows.Markup;
|
|
using System.Windows.Threading;
|
|
|
|
namespace BeWo.ViewModel.ListViewModel
|
|
{
|
|
public class AiConversationListVM : AbstractDCListMapperVM<AiConversationDC, AiConversationVM>
|
|
{
|
|
private bool _IsSettingsOpen;
|
|
private bool _IsCloneOpen;
|
|
private bool _IsSending;
|
|
|
|
private string _MessageInput;
|
|
private string _ContextInput;
|
|
|
|
private AiModelDC _SelectedModel;
|
|
private AiConfigVM _Config;
|
|
|
|
public AiConversationListVM() : this(null)
|
|
{
|
|
if (BeWoApp.IsInDesignMode)
|
|
{
|
|
InitDesigner();
|
|
}
|
|
}
|
|
|
|
public AiConversationListVM(List<AiConversationDC> pDCs) : base(pDCs)
|
|
{
|
|
Models = new ObservableSortCollection<AiModelDC>();
|
|
|
|
SendNewMessageCommand = new DelegateCommand(SendNewMessage, () => SelectedVM is object && !string.IsNullOrWhiteSpace(MessageInput) && !IsSending);
|
|
OpenNewConversationCommand = new DelegateCommand(OpenNewConversation, () => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleChatAdd));
|
|
StartConversationWithMessageCommand = new DelegateCommand(StartConversationWithMessage, () => !string.IsNullOrWhiteSpace(MessageInput) && !IsSending);
|
|
|
|
ReloadConfigCommand = new DelegateCommand(ReloadConfig);
|
|
ReloadConversationsCommand = new DelegateCommand(ReloadConversations);
|
|
ReloadModelsCommand = new DelegateCommand(ReloadModels);
|
|
|
|
OpenSettingCommand = new DelegateCommand(OpenSetting, () => (BeWoApp.AppSettings?.ModuleAiSettingsEnabled ?? true) && BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleViewSetting));
|
|
OpenCloneCommand = new DelegateCommand(OpenClone, () => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleChatClone) && SelectedVM is object);
|
|
CloneCommand = new DelegateCommand(Clone);
|
|
|
|
AskDeleteCommand = new DelegateCommand(AskDelete, () => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleChatDelete) && SelectedVM is object);
|
|
|
|
SelectedVMChanged += (s, e) => FirePropertyChanged(nameof(IsNewConversationVisible));
|
|
}
|
|
|
|
public event EventHandler SendNewMessageSuccess;
|
|
|
|
public DelegateCommand SendNewMessageCommand { get; set; }
|
|
public DelegateCommand OpenNewConversationCommand { get; set; }
|
|
public DelegateCommand StartConversationWithMessageCommand { get; set; }
|
|
public DelegateCommand RequestNewConversationCommand { get; set; }
|
|
public DelegateCommand TestCommand { get; set; }
|
|
public DelegateCommand AskDeleteCommand { get; set; }
|
|
public DelegateCommand ReloadConfigCommand { get; set; }
|
|
public DelegateCommand ReloadConversationsCommand { get; set; }
|
|
public DelegateCommand ReloadModelsCommand { get; set; }
|
|
|
|
public DelegateCommand OpenSettingCommand { get; set; }
|
|
public DelegateCommand OpenCloneCommand { get; set; }
|
|
public DelegateCommand CloneCommand { get; set; }
|
|
|
|
public ObservableCollection<AiModelDC> Models { get; set; }
|
|
public AiModelDC SelectedModel
|
|
{
|
|
get { return _SelectedModel; }
|
|
set
|
|
{
|
|
if (_SelectedModel == value)
|
|
return;
|
|
|
|
_SelectedModel = value;
|
|
FirePropertyChanged(nameof(SelectedModel));
|
|
}
|
|
}
|
|
public AiConfigVM Config
|
|
{
|
|
get { return _Config; }
|
|
set
|
|
{
|
|
if (Config == value)
|
|
return;
|
|
|
|
_Config = value;
|
|
FirePropertyChanged(nameof(Config));
|
|
}
|
|
}
|
|
|
|
public string MessageInput
|
|
{
|
|
get { return _MessageInput; }
|
|
set
|
|
{
|
|
if (MessageInput == value)
|
|
return;
|
|
|
|
_MessageInput = value;
|
|
FirePropertyChanged(nameof(MessageInput));
|
|
}
|
|
}
|
|
public string ContextInput
|
|
{
|
|
get { return _ContextInput; }
|
|
set
|
|
{
|
|
if (ContextInput == value)
|
|
return;
|
|
|
|
_ContextInput = value;
|
|
FirePropertyChanged(nameof(ContextInput));
|
|
}
|
|
}
|
|
|
|
public bool IsSettingsOpen
|
|
{
|
|
get => _IsSettingsOpen;
|
|
set
|
|
{
|
|
_IsSettingsOpen = value;
|
|
FirePropertyChanged(nameof(IsSettingsOpen));
|
|
}
|
|
}
|
|
public bool IsCloneOpen
|
|
{
|
|
get => _IsCloneOpen;
|
|
set
|
|
{
|
|
_IsCloneOpen = value;
|
|
FirePropertyChanged(nameof(IsCloneOpen));
|
|
}
|
|
}
|
|
public bool IsSending
|
|
{
|
|
get => _IsSending;
|
|
set
|
|
{
|
|
_IsSending = value;
|
|
FirePropertyChanged(nameof(IsSending));
|
|
}
|
|
}
|
|
public bool IsNewConversationVisible => SelectedVM is null;
|
|
|
|
public int UIContext { get; set; }
|
|
public long? ReferenceObjectOid { get; set; }
|
|
public Dictionary<TableID, long[]> ContextBeWoObjects { get; set; }
|
|
|
|
private void StartConversationWithMessage()
|
|
{
|
|
StartSending();
|
|
|
|
try
|
|
{
|
|
var message = MessageInput;
|
|
|
|
var conv = new AiConversationDC();
|
|
|
|
conv.Created = DateTime.Now;
|
|
conv.Updated = DateTime.Now;
|
|
conv.UIContext = UIContext;
|
|
conv.ContextBeWoObjects = ContextBeWoObjects;
|
|
conv.Messages = new List<AiConversationMessageDC>()
|
|
{
|
|
new AiConversationMessageDC()
|
|
{
|
|
Message = message,
|
|
Role = AiConversationMessageRole.User
|
|
}
|
|
};
|
|
|
|
var vm = InsertConverstion(conv);
|
|
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(
|
|
x => x.CreateAiConversationWithMessage(conv, Config.SelectedModel.Oid.Value, message),
|
|
dc => UpdateConverstion(vm, dc),
|
|
e => EndSending());
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
EndSending();
|
|
}
|
|
}
|
|
private void OpenNewConversation()
|
|
{
|
|
SelectedVM = null;
|
|
}
|
|
private void SendNewMessage()
|
|
{
|
|
StartSending();
|
|
|
|
try
|
|
{
|
|
var conv = SelectedVM;
|
|
|
|
var msg_dc = new AiConversationMessageDC();
|
|
|
|
msg_dc.Message = MessageInput;
|
|
msg_dc.Role = BS.Shared.AiConversationMessageRole.User;
|
|
msg_dc.Created = DateTime.Now;
|
|
|
|
var msg_vm = new AiConversationMessageVM(msg_dc);
|
|
|
|
conv.Messages.VMList.Add(msg_vm);
|
|
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(
|
|
x => x.SendNewMessage(conv.DataContract.Oid.Value, MessageInput),
|
|
(messages) =>
|
|
{
|
|
if (messages.Count != 2)
|
|
throw new InvalidOperationException("message count: " + messages.Count);
|
|
|
|
msg_vm.DataContract = messages[0];
|
|
|
|
conv.Messages.VMList.Add(new AiConversationMessageVM(messages[1]));
|
|
|
|
MessageInput = string.Empty;
|
|
|
|
EndSending();
|
|
|
|
SendNewMessageSuccess?.Invoke(this, EventArgs.Empty);
|
|
},
|
|
(exception) =>
|
|
{
|
|
conv.Messages.VMList.Remove(msg_vm);
|
|
|
|
EndSending();
|
|
}
|
|
);
|
|
}
|
|
catch (Exception ex) {
|
|
EndSending();
|
|
}
|
|
}
|
|
private void StartSending()
|
|
{
|
|
if (IsSending)
|
|
throw new InvalidOperationException("Sendet bereits");
|
|
|
|
IsSending = true;
|
|
}
|
|
private void EndSending()
|
|
{
|
|
if (!IsSending)
|
|
throw new InvalidOperationException("Sendet nicht");
|
|
|
|
IsSending = false;
|
|
}
|
|
private void Test()
|
|
{
|
|
throw new NotImplementedException();
|
|
|
|
//var limit = 5;
|
|
|
|
//var models = ServiceFacade.DoOperationsEnhancedServiceSnyc(x => x.GetAiModels());
|
|
//Models.MakeEqualTo(models);
|
|
|
|
//VMList.Clear();
|
|
|
|
//foreach (var vm in Models)
|
|
//{
|
|
// var dc = new AiConversationDC();
|
|
|
|
// dc.Created = DateTime.Now;
|
|
// dc.Displayname = "Example";
|
|
// dc.Modell = vm.ToString();
|
|
|
|
// var pvm = new AiConversationVM(dc);
|
|
|
|
// VMList.Add(pvm);
|
|
//}
|
|
|
|
//var msg = "Wie alt ist Frau Müller?";
|
|
//var context = "Frau Müller wurde am 1.1.1950 geboren. Aktuelle haben wir folgende Universalzeit: " + DateTime.Now.ToUniversalTime();
|
|
|
|
//for (var i = 0; i < limit; i++)
|
|
//{
|
|
// foreach (var vm in VMList)
|
|
// {
|
|
// ServiceFacade.DoOperationsEnhancedServiceAsnyc(x => x.SendNewMessage(vm.CommitToDataContract(), context, msg), (message) =>
|
|
// {
|
|
// vm.Messages.VMList.Add(new AiConversationMessageVM(message));
|
|
// });
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private AiConversationVM InsertConverstion(AiConversationDC dc)
|
|
{
|
|
var vm = new AiConversationVM(dc);
|
|
VMList.Insert(0, vm);
|
|
SelectedVM = vm;
|
|
|
|
return vm;
|
|
}
|
|
|
|
private void UpdateConverstion(AiConversationVM vm, AiConversationDC dc)
|
|
{
|
|
vm.UpdateByDataContract(dc);
|
|
|
|
MessageInput = string.Empty;
|
|
|
|
EndSending();
|
|
|
|
SendNewMessageSuccess?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
private void ReloadConfig()
|
|
{
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.GetAiConfig(), (x) =>
|
|
{
|
|
if (Config is null)
|
|
Config = new AiConfigVM(x);
|
|
else
|
|
Config.Update(x);
|
|
});
|
|
}
|
|
public void UpdateConfig()
|
|
{
|
|
if (!Config.IsDirty)
|
|
return;
|
|
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiConfig(Config.CommitToDataContract()), (x) =>
|
|
{
|
|
Config.Update(x);
|
|
});
|
|
}
|
|
|
|
private void ReloadModels()
|
|
{
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.GetAiModels(), (x) =>
|
|
{
|
|
Models.MakeEqualTo(x);
|
|
|
|
if (Config.SelectedModel is null && Models.Any())
|
|
Config.SelectedModel = Models.First();
|
|
});
|
|
}
|
|
private void ReloadConversations()
|
|
{
|
|
var ui_context = UIContext;
|
|
var reference = ReferenceObjectOid;
|
|
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.GetAiConversations(ui_context, reference), (x) =>
|
|
{
|
|
x.Reverse();
|
|
var vms = new AiConversationListVM(x);
|
|
VMList.MakeEqualTo(vms.VMList);
|
|
});
|
|
}
|
|
|
|
private void OpenSetting()
|
|
{
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.GetAiModels(), (x) =>
|
|
{
|
|
Models.MakeEqualTo(x);
|
|
IsSettingsOpen = true;
|
|
});
|
|
}
|
|
private void OpenClone()
|
|
{
|
|
foreach (var message in SelectedVM.Messages.VMList)
|
|
{
|
|
message.IsChecked = true;
|
|
}
|
|
|
|
IsCloneOpen = true;
|
|
}
|
|
private void Clone()
|
|
{
|
|
var conv = SelectedVM;
|
|
|
|
AiConversationMessageVM last = null;
|
|
foreach (var msg in conv.Messages.VMList)
|
|
{
|
|
if (!msg.IsChecked)
|
|
break;
|
|
|
|
last = msg;
|
|
}
|
|
|
|
var conv_oid = conv.DataContract.Oid.Value;
|
|
var msg_oid = last?.DataContract.Oid;
|
|
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CloneAiConversation(conv_oid, msg_oid), dc =>
|
|
{
|
|
InsertConverstion(dc);
|
|
CloseClone();
|
|
});
|
|
}
|
|
private void CloseClone()
|
|
{
|
|
IsCloneOpen = false;
|
|
}
|
|
|
|
public void AskDelete()
|
|
{
|
|
var selected = SelectedVM;
|
|
|
|
var oid = selected.DataContract.Oid.Value;
|
|
|
|
var msg = $"Wollen Sie die ausgewählte Konversation ({oid}) löschen?";
|
|
|
|
if (MessageBox.Show(msg, "Konversation löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning) ==
|
|
MessageBoxResult.Yes)
|
|
{
|
|
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.DeleteAiConversation(oid), () => {
|
|
VMList.Remove(selected);
|
|
CommandManager.InvalidateRequerySuggested();
|
|
//SelectedVM = VMList.FirstOrDefault();
|
|
});
|
|
}
|
|
}
|
|
#region Designer
|
|
private void InitDesigner()
|
|
{
|
|
var model = new AiModelDC()
|
|
{
|
|
ModelName = "N llama3.2"
|
|
};
|
|
|
|
var message_dc = new AiConversationMessageDC()
|
|
{
|
|
Created = DateTime.Now,
|
|
Message = "Nu bist eine intelligente Einheit mit ganz ganz vielen Eingaben: value1, value2, value3, value4\r\nTest",
|
|
Role = BS.Shared.AiConversationMessageRole.System
|
|
};
|
|
|
|
var message_dc2 = new AiConversationMessageDC()
|
|
{
|
|
Created = DateTime.Now,
|
|
Message = "N. Dies ist eine Design Frage: Du sollst ganz viele Sachen machen. Dabei sollst du auf ganz viele Sachen achten: Zum Beispiel:\r\nSache 1\r\nSchritt 2",
|
|
Role = BS.Shared.AiConversationMessageRole.User
|
|
};
|
|
|
|
var message_dc3 = new AiConversationMessageDC()
|
|
{
|
|
Created = DateTime.Now,
|
|
Message = "N. Deine Antwort. Dies ist eine Design Antwort. Du hast ganz viele Sachen angefragt. Dabei soll ich auf ganz viele Sachen achten. Wie Test, test, tEst und tesT.\r\nTest\r\nTest\r\nTest",
|
|
Role = BS.Shared.AiConversationMessageRole.Assistent,
|
|
ModelName = model.ModelName,
|
|
Duration = 10,
|
|
};
|
|
|
|
var messages_dc = new List<AiConversationMessageDC>()
|
|
{
|
|
message_dc,
|
|
message_dc2,
|
|
message_dc3,
|
|
message_dc2,
|
|
message_dc3,
|
|
message_dc2,
|
|
message_dc3,
|
|
message_dc2,
|
|
message_dc3,
|
|
};
|
|
|
|
var conversation_dc = new AiConversationDC()
|
|
{
|
|
Created = DateTime.Now,
|
|
Displayname = "Displayname Megamegalange Deluxe Op 3000",
|
|
Messages = messages_dc,
|
|
Modell = model,
|
|
UIContext = 19,
|
|
Updated = DateTime.Now,
|
|
};
|
|
|
|
var conversation_vm = new AiConversationVM(conversation_dc);
|
|
|
|
VMList.Add(conversation_vm);
|
|
|
|
InitDummyConversations(10);
|
|
|
|
//SelectedVM = conversation_vm;
|
|
}
|
|
private void InitDummyConversations(int count)
|
|
{
|
|
var model = new AiModelDC()
|
|
{
|
|
ModelName = "llama3.2"
|
|
};
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var conversation_dc2 = new AiConversationDC()
|
|
{
|
|
Created = DateTime.Now,
|
|
Displayname = "Dummy Num " + i.ToString(),
|
|
Modell = model,
|
|
UIContext = 19,
|
|
Updated = DateTime.Now,
|
|
};
|
|
|
|
var conversation_vm2 = new AiConversationVM(conversation_dc2);
|
|
|
|
VMList.Add(conversation_vm2);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|