UIContextType -> AiActionType

This commit is contained in:
2026-05-26 12:30:29 +02:00
parent 709937eee3
commit 9c10386b87
46 changed files with 396 additions and 625 deletions

View File

@@ -73,7 +73,7 @@ namespace BeWo.ViewModel
public string Context => DataContract.Context;
public Dictionary<TableID, long[]> ContextBeWoObjects => DataContract.ContextBeWoObjects;
public AiDataContextType Context_Type => DataContract.ContextType;
public UIContext UIContext => (UIContext)DataContract.UIContext;
public AiActionType AiActionType => DataContract.ActionType;
protected override void InitByDataContract(AiConversationDC pDataContract)
{

View File

@@ -1,29 +1,51 @@
using BeWo.ViewModel.View.AI;
using BeWo.ServiceProxy;
using BeWo.View.Controls.AI;
using BeWo.View.Detail.AI;
using BeWo.ViewModel.View.AI;
using BS.Shared;
using BS.Shared.DataContracts.Feature.AI;
using DevExpress.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace BeWo.ViewModel.Controls.AI
{
public enum AiChatButtonState
{
Hidden,
Normal,
Loading,
Warning,
Disabled
}
public class AiChatButtonViewModel : AbstractBaseVM
{
private bool canExecute;
private AiChatButtonState buttonState;
public AiActionType ActionType { get; protected set; }
public bool IsFavoritenOpen { get; set; }
public List<AiMenuItemTemplate> AssistentCommands { get; protected set; }
public virtual bool IsHistoryEnabled => false;
public bool IsEnabled => BeWoApp.AppSettings.ShowAI && BeWoApp.HasLoggedOnUserRight(GetUserRightType());
public bool CanExecute
{
get => canExecute;
set => SetProperty(ref canExecute, value, nameof(CanExecute));
}
public AiChatButtonState ButtonState
{
get => buttonState;
set => SetProperty(ref buttonState, value, nameof(ButtonState));
}
public Func<AiConversationChatViewModel> GetAiConversationChatViewModel { get; set; }
public Func<AiViewContextDC> GetAiVisualContext { get; set; }
public AiPromptbausteinSelectionComplexViewModel AllPromptsViewModel { get; set; }
@@ -31,8 +53,13 @@ namespace BeWo.ViewModel.Controls.AI
public DelegateCommand OpenAllPromptsPopupCommand { get; protected set; }
public DelegateCommand OpenFavoritePromptsPopupCommand { get; protected set; }
public AiChatButtonViewModel()
public AiChatButtonViewModel(AiActionType aiActionType)
{
ActionType = aiActionType;
if (!IsEnabled)
return;
canExecute = true;
OpenConversationPopupCommand = new DelegateCommand(OpenConversationPopup);
@@ -40,21 +67,67 @@ namespace BeWo.ViewModel.Controls.AI
OpenFavoritePromptsPopupCommand = new DelegateCommand(OpenFavoritePromptsPopup);
}
public void OpenConversationPopup()
public void CheckContextSize()
{
BeWoApp.MainControl.WindowService.ShowAiConversationWindow(GetAiConversationChatViewModel());
if (!IsEnabled)
{
return;
}
ButtonState = AiChatButtonState.Loading;
var context = GetAiVisualContext();
if (context != null)
{
var context2 = context.References.ToDictionary(kv => kv.Key, kv => kv.Value.ToList());
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CheckContextSize(ActionType, context2, null),
isValid =>
{
if (isValid)
ButtonState = AiChatButtonState.Normal;
else
ButtonState = AiChatButtonState.Warning;
},
(exp) => ButtonState = AiChatButtonState.Disabled);
}
}
public void OpenAllPromptsPopup()
private void OpenConversationPopup()
{
var context = GetAiVisualContext();
var chat_viewmodel = VMFactory.CreateAiConversationChatViewModel(ActionType, context.References, (long)context.Primary, true);
BeWoApp.MainControl.WindowService.Show(chat_viewmodel);
}
private void OpenAllPromptsPopup()
{
BeWoApp.MainControl.WindowService.Show(AllPromptsViewModel);
}
public void OpenFavoritePromptsPopup()
private void OpenFavoritePromptsPopup()
{
IsFavoritenOpen = true;
FirePropertyChanged(nameof(IsFavoritenOpen));
}
private UserRightType GetUserRightType()
{
switch (ActionType)
{
case AiActionType.ServiceRecord:
break;
case AiActionType.ServiceRecordConversation:
return UserRightType.AiModuleServiceRecordChat;
case AiActionType.ServiceRecordDocumentation:
return UserRightType.AiModuleServiceRecordDocu;
default:
break;
}
throw new InvalidOperationException($"UserRightType '{ActionType}' not implemented");
}
}
public class AiMenuItemTemplate

View File

@@ -1,4 +1,7 @@
using System;
using BS.Shared;
using DevExpress.Mvvm;
using DevExpress.XtraPrinting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -19,12 +22,15 @@ namespace BeWo.ViewModel.Controls.AI
set => SetProperty(ref currentValue, value, nameof(CurrentValue));
}
public override bool IsHistoryEnabled => true;
public bool IsUndoButtonVisible => CurrentIndex > 0;
public bool IsRedoButtonVisible => CurrentIndex < History.Count - 1;
public override bool IsHistoryEnabled => true;
public DelegateCommand UndoAiActionCommand { get; protected set; }
public DelegateCommand RedoAiActionCommand { get; protected set; }
public AiChatButtonWithHistoryViewModel() : base()
public AiChatButtonWithHistoryViewModel(AiActionType aiActionType) : base(aiActionType)
{
History = new List<string>();
CurrentIndex = 0;
@@ -32,17 +38,19 @@ namespace BeWo.ViewModel.Controls.AI
{
new AiMenuItemTemplate()
{
Command = new DevExpress.Mvvm.DelegateCommand<AiConversationMessageVM>(x => Accept1(x.Message)),
Command = new DelegateCommand<AiConversationMessageVM>(x => AddValue(x.Message)),
Icon = null,
Name = "Akzeptieren"
Name = "Anfügen"
},
new AiMenuItemTemplate()
{
Command = new DevExpress.Mvvm.DelegateCommand<AiConversationMessageVM>(x => Accept2(x.Message)),
Command = new DelegateCommand<AiConversationMessageVM>(x => ReplaceValue(x.Message)),
Icon = null,
Name = "Ersetzen"
},
};
UndoAiActionCommand= new DelegateCommand(UndoAiAction);
RedoAiActionCommand= new DelegateCommand(RedoAiAction);
}
public void ClearHistory()
@@ -97,14 +105,24 @@ namespace BeWo.ViewModel.Controls.AI
CurrentValue = History[CurrentIndex];
}
public void Accept1(string s)
public void AddValue(string s)
{
var sb = new StringBuilder();
sb.AppendLine("Antwort:");
sb.AppendLine(s);
sb.AppendLine();
sb.AppendLine("Original:");
sb.AppendLine(CurrentValue);
var str = sb.ToString();
Accept(str);
}
public void Accept2(string s)
public void ReplaceValue(string str)
{
Accept(str);
}
}
}

View File

@@ -90,7 +90,7 @@ namespace BeWo.ViewModel.ListViewModel
Displayname = "Displayname Megamegalange Deluxe Op 3000",
Messages = messages_dc,
Modell = model,
UIContext = AiContextType.ServiceRecord,
ActionType = AiActionType.ServiceRecordDocumentation,
Updated = DateTime.Now,
};
@@ -116,7 +116,7 @@ namespace BeWo.ViewModel.ListViewModel
Created = DateTime.Now,
Displayname = "Dummy Num " + i.ToString(),
Modell = model,
UIContext = AiContextType.ServiceRecord,
ActionType = AiActionType.ServiceRecordDocumentation,
Updated = DateTime.Now,
};

View File

@@ -102,19 +102,6 @@ namespace BeWo.ViewModel.ListViewModel
//private static List<DarreichungsformDC> _AllDosageForms;
private List<string> _AiActionHistory;
private int _AiActionHistoryIndex;
private AiConversationButtonState _AiConversationButtonState;
public ICommand UndoAiActionCommand { get; set; }
public ICommand RedoAiActionCommand { get; set; }
private List<string> _EditAiActionHistory;
private int _EditAiActionHistoryIndex;
public ICommand UndoEditAiActionCommand { get; set; }
public ICommand RedoEditAiActionCommand { get; set; }
public AiUserSettingVM AiUserSetting { get; set; }
public AiChatButtonViewModel AiChatButtonConversationViewModel { get; set; }
@@ -193,17 +180,16 @@ namespace BeWo.ViewModel.ListViewModel
private void InitAiStuff()
{
AiChatButtonConversationViewModel = new AiChatButtonViewModel()
AiChatButtonConversationViewModel = new AiChatButtonViewModel(AiActionType.ServiceRecordConversation)
{
};
AiChatButtonDocumentationViewModel = new AiChatButtonWithHistoryViewModel()
};
AiChatButtonDocumentationViewModel = new AiChatButtonWithHistoryViewModel(AiActionType.ServiceRecordDocumentation)
{
};
AiChatButtonDocumentationEditViewModel = new AiChatButtonWithHistoryViewModel()
AiChatButtonDocumentationEditViewModel = new AiChatButtonWithHistoryViewModel(AiActionType.ServiceRecordDocumentation)
{
};
@@ -224,12 +210,6 @@ namespace BeWo.ViewModel.ListViewModel
FirePropertyChanged(nameof(AiUserSetting));
}
public AiConversationButtonState AiConversationButtonState
{
get => _AiConversationButtonState;
set => SetProperty(ref _AiConversationButtonState, value, nameof(AiConversationButtonState));
}
public IEnumerable<ServiceRecordVM> CurrentVisibleVMs { get; set; }
public string AktuellerDokutext
{
@@ -257,252 +237,11 @@ namespace BeWo.ViewModel.ListViewModel
public bool IsAiChatButtonVisible => SelectedCustomerNode is object && IsAiModuleEnabled && BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleServiceRecordChat);
public bool IsAiDocuButtonVisible => SelectedCustomerNode is object && IsAiModuleEnabled && BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleServiceRecordDocu);
public bool IsAiRowVisible => IsAiDocuButtonVisible || VoiceToTextButtonControl.HasRightToUseAIVoice;
public void ItemAccepted(object sender, AbstractBaseVM item)
{
if(item is AiPromptbausteinRoutineVM)
{
MessageBox.Show("");
return;
}
var prompt = item as AiPromptbausteinPromptVM;
if (prompt is null)
throw new NotImplementedException();
// 1. Information aufbereiten
// 1.1 Prompt
var prompt_oid = prompt.DataContract.Oid.Value;
var prompt_version = prompt.DataContract.Version;
// 1.2 Hilfeplan
var support_concept = SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept;
var support_concept_oid = support_concept.SupportConceptOid;
var support_concept_version = support_concept.SupportConceptVersion;
// 1.3 Aktuelles Doku Feld
var doku_feld = AktuellerDokutext;
// 1.4 Sichtbaren Zeiterfassungseinträge
var service_records = CurrentVisibleVMs;
var sr_refs = service_records.Select(x => new BeWoRefDC(x.DataContract.ServiceRecordOid.Value, x.DataContract.ServiceRecordVersion));
// 1.5 Costbearer
var costbearer = SelectedCustomerNode.SupportConceptTreeNodeDC.CostBearer;
var cb_oid = costbearer.CostBearerOid.Value;
var cb_ver = costbearer.CostBearerVersion;
// Service Aufruf
var req = new AiFunctionDocRequest()
{
AiPromptbausteinPrompt = new BeWoRefDC(prompt_oid, prompt_version),
SupportConcept = new BeWoRefDC(support_concept_oid, support_concept_version),
ServiceRecords = sr_refs,
CostBearer = new BeWoRefDC(cb_oid, cb_ver),
Dokumentation = doku_feld,
};
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.ExecuteAiFunctionServiceRecordDocumentation(req),
callback =>
{
var viewModel = new AiPromptbausteinActionResultViewModel();
viewModel.Result = callback.Result;
viewModel.Accept_Button_Clicked += (s, e) =>
{
var sb = new StringBuilder();
sb.AppendLine("AI Antwort:");
sb.AppendLine(viewModel.Result);
sb.AppendLine();
sb.AppendLine("Original:");
sb.AppendLine(AktuellerDokutext);
var str = sb.ToString();
var idx = _AiActionHistoryIndex;
var count = _AiActionHistory.Count;
if (count - 1 > idx)
{
_AiActionHistory.RemoveRange(idx + 1, count - idx - 1);
}
if (AktuellerDokutext != _AiActionHistory[_AiActionHistoryIndex])
{
_AiActionHistory.Add(AktuellerDokutext);
_AiActionHistoryIndex++;
}
_AiActionHistory.Add(str);
_AiActionHistoryIndex++;
AktuellerDokutext = str;
};
viewModel.Replace_Button_Clicked += (s, e) =>
{
var str = viewModel.Result;
var idx = _AiActionHistoryIndex;
var count = _AiActionHistory.Count;
if (count - 1 > idx)
{
_AiActionHistory.RemoveRange(idx + 1, count - idx - 1);
}
if (AktuellerDokutext != _AiActionHistory[_AiActionHistoryIndex])
{
_AiActionHistory.Add(AktuellerDokutext);
_AiActionHistoryIndex++;
}
_AiActionHistory.Add(str);
_AiActionHistoryIndex++;
AktuellerDokutext = str;
};
viewModel.Retry_Button_Clicked += (s, e) =>
{
ItemAccepted(sender, prompt);
};
BeWoApp.MainControl.WindowService.Show(viewModel);
}
);
}
public void EditPromptAccepted(object sender, AiPromptbausteinPromptVM prompt)
{
if (prompt is null)
throw new NotImplementedException();
// 1. Information aufbereiten
// 1.1 Prompt
var prompt_oid = prompt.DataContract.Oid.Value;
var prompt_version = prompt.DataContract.Version;
// 1.2 Hilfeplan
var support_concept = SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept;
var support_concept_oid = support_concept.SupportConceptOid;
var support_concept_version = support_concept.SupportConceptVersion;
// 1.3 Aktuelles Doku Feld
var doku_feld = AktuellerEditDokutext;
// 1.4 Sichtbaren Zeiterfassungseinträge
var service_records = CurrentVisibleVMs;
var sr_refs = service_records.Select(x => new BeWoRefDC(x.DataContract.ServiceRecordOid.Value, x.DataContract.ServiceRecordVersion));
// 1.5 Costbearer
var costbearer = SelectedCustomerNode.SupportConceptTreeNodeDC.CostBearer;
var cb_oid = costbearer.CostBearerOid.Value;
var cb_ver = costbearer.CostBearerVersion;
// Service Aufruf
var req = new AiFunctionDocRequest()
{
AiPromptbausteinPrompt = new BeWoRefDC(prompt_oid, prompt_version),
SupportConcept = new BeWoRefDC(support_concept_oid, support_concept_version),
ServiceRecords = sr_refs,
CostBearer = new BeWoRefDC(cb_oid, cb_ver),
Dokumentation = doku_feld,
};
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.ExecuteAiFunctionServiceRecordDocumentation(req),
callback =>
{
var viewModel = new AiPromptbausteinActionResultViewModel();
viewModel.Result = callback.Result;
viewModel.Accept_Button_Clicked += (s, e) =>
{
var sb = new StringBuilder();
sb.AppendLine("AI Antwort:");
sb.AppendLine(viewModel.Result);
sb.AppendLine();
sb.AppendLine("Original:");
sb.AppendLine(AktuellerEditDokutext);
var str = sb.ToString();
var idx = _EditAiActionHistoryIndex;
var count = _EditAiActionHistory.Count;
if (count - 1 > idx)
{
_EditAiActionHistory.RemoveRange(idx + 1, count - idx - 1);
}
if (AktuellerEditDokutext != _EditAiActionHistory[_EditAiActionHistoryIndex])
{
_EditAiActionHistory.Add(AktuellerEditDokutext);
_EditAiActionHistoryIndex++;
}
_EditAiActionHistory.Add(str);
_EditAiActionHistoryIndex++;
AktuellerEditDokutext = str;
};
viewModel.Replace_Button_Clicked += (s, e) =>
{
var str = viewModel.Result;
var idx = _EditAiActionHistoryIndex;
var count = _EditAiActionHistory.Count;
if (count - 1 > idx)
{
_EditAiActionHistory.RemoveRange(idx + 1, count - idx - 1);
}
if (AktuellerEditDokutext != _EditAiActionHistory[_EditAiActionHistoryIndex])
{
_EditAiActionHistory.Add(AktuellerEditDokutext);
_EditAiActionHistoryIndex++;
}
_EditAiActionHistory.Add(str);
_EditAiActionHistoryIndex++;
AktuellerEditDokutext = str;
};
viewModel.Retry_Button_Clicked += (s, e) =>
{
ItemAccepted(sender, prompt);
};
BeWoApp.MainControl.WindowService.Show(viewModel);
}
);
}
public void UpdateViewYearFilter(IEnumerable<ServiceRecordVM> enumerable)
{
if (!IsAiChatButtonVisible)
{
AiConversationButtonState = AiConversationButtonState.Hidden;
return;
}
AiConversationButtonState = AiConversationButtonState.Loading;
var context = GetVisibleInformationReferences(enumerable);
if (context != null)
{
var context2 = context.ToDictionary(kv => kv.Key, kv => kv.Value.ToList());
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CheckContextSize(AiContextType.ServiceRecord, context2, null),
isValid =>
{
if (isValid)
AiConversationButtonState = AiConversationButtonState.Normal;
else
AiConversationButtonState = AiConversationButtonState.Warning;
},
(exp) => AiConversationButtonState = AiConversationButtonState.Disabled);
}
AiChatButtonConversationViewModel.CheckContextSize();
AiChatButtonDocumentationViewModel.CheckContextSize();
}
public Dictionary<TableID, long[]> GetVisibleInformationReferences(IEnumerable<ServiceRecordVM> selected_records)

View File

@@ -912,12 +912,12 @@ namespace BeWo.ViewModel
einheit_vm_list.VMList.Sort(WohneinheitVM.Compare);
}
public static AiConversationChatViewModel CreateAiConversationChatViewModel(AiContextType uIContext, Dictionary<TableID, long[]> bewoObjects,
public static AiConversationChatViewModel CreateAiConversationChatViewModel(AiActionType actionType, Dictionary<TableID, long[]> bewoObjects,
long? reference_oid = null, bool canSendNewMessage = true)
{
var vm = new AiConversationChatViewModel();
vm.AiContext = uIContext;
vm.ActionType = actionType;
vm.ContextBeWoObjects = bewoObjects;
vm.ReferenceObjectOid = reference_oid;
vm.CanSendNewMessage = canSendNewMessage;
@@ -925,19 +925,19 @@ namespace BeWo.ViewModel
return vm;
}
public static AiConversationListVM CreateAiConversationListVM(AiContextType uIContext, long? reference_oid)
public static AiConversationListVM CreateAiConversationListVM(AiActionType actionType, long? reference_oid)
{
var list = ServiceFacade.DoAiEnhancedServiceSnyc(s => s.GetAiConversations(uIContext, reference_oid));
var list = ServiceFacade.DoAiEnhancedServiceSnyc(s => s.GetAiConversations(actionType, reference_oid));
list.Reverse();
return new AiConversationListVM(list);
}
public static void CreateAiConversationListVMAsync(AiContextType uIContext, long? reference_oid, Action<AiConversationListVM> callback)
public static void CreateAiConversationListVMAsync(AiActionType actionType, long? reference_oid, Action<AiConversationListVM> callback)
{
ServiceFacade.DoAiEnhancedServiceAsnyc(
s => s.GetAiConversations(uIContext, reference_oid),
s => s.GetAiConversations(actionType, reference_oid),
cb =>
{
cb.Reverse();

View File

@@ -163,7 +163,7 @@ namespace BeWo.ViewModel.View.AI
}
public bool IsNewConversationVisible => ListVM.SelectedVM is null;
public AiContextType AiContext { get; set; }
public AiActionType ActionType { get; set; }
public long? ReferenceObjectOid { get; set; }
public Dictionary<TableID, long[]> ContextBeWoObjects { get; set; }
@@ -200,7 +200,7 @@ namespace BeWo.ViewModel.View.AI
conv.Created = DateTime.Now;
conv.Updated = DateTime.Now;
conv.UIContext = AiContext;
conv.ActionType = ActionType;
conv.ContextBeWoObjects = ContextBeWoObjects;
conv.Messages = new List<AiConversationMessageDC>()
{
@@ -355,7 +355,7 @@ namespace BeWo.ViewModel.View.AI
}
private void ReloadConversations()
{
var ui_context = AiContext;
var ui_context = ActionType;
var reference = ReferenceObjectOid;
var list = VMFactory.CreateAiConversationListVM(ui_context, reference);