Conversation Rename

This commit is contained in:
2025-07-08 16:30:58 +02:00
parent 3318efd37e
commit 3aba7250d0
10 changed files with 377 additions and 139 deletions

View File

@@ -43,6 +43,11 @@ namespace BeWo.ServiceProxy
[System.ServiceModel.FaultContractAttribute(typeof(BeWo.ServiceProxy.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/CloneAiConversationBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BeWo.Service.ServiceContracts")]
BS.Shared.DataContracts.Feature.AI.AiConversationDC CloneAiConversation(long conversation_oid, System.Nullable<long> message_oid);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/UpdateAiConversationDisplayname", ReplyAction="http://tempuri.org/IAiEnhancedService/UpdateAiConversationDisplaynameResponse")]
[System.ServiceModel.FaultContractAttribute(typeof(BeWo.ServiceProxy.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/UpdateAiConversationDisplaynameBeWoFaultFau" +
"lt", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BeWo.Service.ServiceContracts")]
long UpdateAiConversationDisplayname(long oid, long version, string displayname);
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAiEnhancedService/DeleteAiConversation", ReplyAction="http://tempuri.org/IAiEnhancedService/DeleteAiConversationResponse")]
[System.ServiceModel.FaultContractAttribute(typeof(BeWo.ServiceProxy.BeWoFault), Action="http://tempuri.org/IAiEnhancedService/DeleteAiConversationBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BeWo.Service.ServiceContracts")]
void DeleteAiConversation(long conversation_oid);
@@ -121,6 +126,11 @@ namespace BeWo.ServiceProxy
return base.Channel.CloneAiConversation(conversation_oid, message_oid);
}
public long UpdateAiConversationDisplayname(long oid, long version, string displayname)
{
return base.Channel.UpdateAiConversationDisplayname(oid, version, displayname);
}
public void DeleteAiConversation(long conversation_oid)
{
base.Channel.DeleteAiConversation(conversation_oid);

View File

@@ -230,6 +230,85 @@
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="PopupToolbarButtonSmallStyle"
BasedOn="{StaticResource HideDisabledButton}"
TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="#FFFFFFFF" />
<Setter Property="FontWeight" Value="Medium" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames
AccelerationRatio="1"
BeginTime="00:00:00"
Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
Duration="00:00:00.2">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1.15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
AccelerationRatio="1"
BeginTime="00:00:00"
Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
Duration="00:00:00.2">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1.15" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Storyboard2">
<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
DecelerationRatio="1"
Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
Duration="00:00:00.2">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames
BeginTime="00:00:00"
DecelerationRatio="1"
Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"
Duration="00:00:00.2">
<SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ContentPresenter
x:Name="contentPresenter"
Width="Auto"
Margin="3,0,3,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5">
<ContentPresenter.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.ExitActions>
<BeginStoryboard x:Name="Storyboard2_BeginStoryboard" Storyboard="{StaticResource Storyboard2}" />
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Storyboard1}" />
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- EndRegion -->
<!-- Region Weiße Buttons im MainNavigationView -->

View File

@@ -137,49 +137,7 @@
<dxwui:HamburgerMenuNavigationButton Content="{Binding Displayname}" />
</DataTemplate>
<!-- Conversation Control -->
<DataTemplate x:Key="ConversationTemplate">
<Border
Width="auto"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
Background="#17000000"
BorderBrush="Black"
BorderThickness="0"
CornerRadius="10, 10, 10, 10">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBlock
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextForegroundPrimary}"
Text="{Binding Displayname}"
TextTrimming="CharacterEllipsis" />
<TextBlock
Grid.Row="1"
FontSize="11"
Foreground="{DynamicResource TextForegroundSecondary}"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Created, StringFormat=Erstellt: {0:dd.MM.yy HH:mm}}" />
<TextBlock
Grid.Row="2"
FontSize="11"
Foreground="{DynamicResource TextForegroundSecondary}"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Updated, StringFormat=Aktualisiert: {0:dd.MM.yy HH:mm}}" />
<!--<TextBlock
Grid.Row="2"
FontSize="10"
FontWeight="Thin"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Modell.ModelName, StringFormat=Modell: {0}}" />-->
</Grid>
</Border>
</DataTemplate>
<!-- Assistent Message Control -->
<DataTemplate x:Key="AssistentMessageTemplate">

View File

@@ -33,7 +33,67 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..\..\..\Styles\ModernOrangeBlack.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Conversation Control -->
<DataTemplate x:Key="ConversationTemplate">
<Border
Width="auto"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
Background="#17000000"
BorderBrush="Black"
BorderThickness="0"
CornerRadius="10, 10, 10, 10">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBlock
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextForegroundPrimary}"
Text="{Binding Displayname}"
TextTrimming="CharacterEllipsis"
MouseDown="ConversationRenameTextBlock_MouseDown"
Visibility="{Binding IsEditing, Converter={StaticResource BoolVisibilityConverter}, ConverterParameter=false}" />
<TextBox
Margin="0"
Padding="0"
Background="Transparent"
BorderThickness="0"
FontSize="14"
FontWeight="SemiBold"
Foreground="{DynamicResource TextForegroundPrimary}"
IsVisibleChanged="ConversationRenameTextBox_IsVisibleChanged"
KeyDown="ConversationRenameTextBox_KeyDown"
LostFocus="ConversationRenameTextBox_LostFocus"
Text="{Binding Displayname, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding IsEditing, Converter={StaticResource BoolVisibilityConverter}}" />
<TextBlock
Grid.Row="1"
FontSize="11"
Foreground="{DynamicResource TextForegroundSecondary}"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Created, StringFormat=Erstellt: {0:dd.MM.yy HH:mm}}" />
<TextBlock
Grid.Row="2"
FontSize="11"
Foreground="{DynamicResource TextForegroundSecondary}"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Updated, StringFormat=Aktualisiert: {0:dd.MM.yy HH:mm}}" />
<!--<TextBlock
Grid.Row="2"
FontSize="10"
FontWeight="Thin"
Style="{StaticResource TextBlockStyle}"
Text="{Binding Modell.ModelName, StringFormat=Modell: {0}}" />-->
</Grid>
</Border>
</DataTemplate>
</ResourceDictionary>
</localView:BeWoView.Resources>
<Grid>
<GroupBox x:Name="rootgroupbox" Style="{StaticResource ModuleAiControlSupportConceptStyle}">
@@ -272,7 +332,7 @@
VerticalAlignment="Stretch">
<Grid>
<Grid.Resources>
<Style BasedOn="{StaticResource PopupToolbarButtonStyle}" TargetType="Button" />
<Style BasedOn="{StaticResource PopupToolbarButtonSmallStyle}" TargetType="Button" />
</Grid.Resources>
<Rectangle Fill="#FF000000">
<Rectangle.OpacityMask>
@@ -306,6 +366,11 @@
Command="{Binding TestCommand}"
Content="Test Szenario"
Visibility="Collapsed" />
<Button
x:Name="btnRename"
Margin="4,0,0,0"
Command="{Binding RenameCommand}"
Content="Umbennen" />
<Button
x:Name="btnClone"
Margin="4,0,0,0"
@@ -357,15 +422,15 @@
x:Name="popup_settings"
Width="auto"
Height="auto"
AllowsTransparency="True"
IsOpen="{Binding IsSettingsOpen}"
Placement="Center"
StaysOpen="False"
AllowsTransparency="True">
StaysOpen="False">
<Border
Padding="5"
Background="{DynamicResource NavigationContentBrush}"
BorderThickness="1"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="5">
<ai:AiConfigView />
</Border>

View File

@@ -1,5 +1,6 @@
using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.ViewModel;
using BeWo.ViewModel.ListViewModel;
using BeWo.ViewModel.View;
using BS.Shared.Extensions;
@@ -110,5 +111,54 @@ namespace BeWo.View.Detail.AI
// e.Handled = true;
}
}
private void ConversationRenameTextBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if(sender is TextBox textBox && e.NewValue is bool b && b)
{
textBox.Focus();
textBox.SelectAll();
}
}
private void ConversationRenameTextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (sender is TextBox textbox && textbox.DataContext is AiConversationVM vm && vm.IsEditing)
{
vm.SaveDisplayname();
}
}
private void ConversationRenameTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (sender is TextBox textbox && textbox.DataContext is AiConversationVM vm && vm.IsEditing)
{
if(e.Key == Key.Enter)
{
vm.SaveDisplayname();
e.Handled = true;
}
else if(e.Key == Key.Escape)
{
vm.IsEditing = true;
vm.ResetDisplayname();
e.Handled = true;
}
}
}
private void ConversationRenameTextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
if(e.ClickCount == 2)
{
if (sender is TextBlock textBlock && textBlock.DataContext is AiConversationVM vm && !vm.IsEditing)
{
vm.IsEditing = true;
e.Handled = true;
}
}
}
}
}

View File

@@ -2223,9 +2223,10 @@
SelectedValue="{Binding Path=TerminationReason, Mode=TwoWay}" />
<Label
Name="lblFremdHilfe"
Grid.Row="4"
Grid.Column="0"
Name="lblFremdHilfe" Content="{markup:Translate Fremde Hilfen}" />
Content="{markup:Translate Fremde Hilfen}" />
<uc:NullItemComboBox
x:Name="comboBox_Fremdhilfe"
Grid.Row="4"
@@ -2265,9 +2266,10 @@
</Grid>
<Label
Name="lblEinkommenBeginn"
Grid.Row="0"
Grid.Column="2"
Name="lblEinkommenBeginn" Content="{markup:Translate Einkommensart zu Beginn}" />
Content="{markup:Translate Einkommensart zu Beginn}" />
<uc:NullItemComboBox
x:Name="comboBox_EinkommenBeginn"
Grid.Row="0"
@@ -2279,9 +2281,10 @@
ItemsSource="{Binding Path=EinkommenBeginnTypen, Mode=OneWay}"
SelectedValue="{Binding Path=EinkommenBeginnType, Mode=TwoWay}" />
<Label
Name="lblEinkommenEnde"
Grid.Row="1"
Grid.Column="2"
Name="lblEinkommenEnde" Content="{markup:Translate Einkommensart zum Ende}" />
Content="{markup:Translate Einkommensart zum Ende}" />
<uc:NullItemComboBox
x:Name="comboBox_EinkommenEnde"
Grid.Row="1"
@@ -2294,9 +2297,10 @@
SelectedValue="{Binding Path=EinkommenEndeType, Mode=TwoWay}" />
<Label
Name="lblHilfenRegion"
Grid.Row="2"
Grid.Column="2"
Name="lblHilfenRegion" Content="{markup:Translate Region der Hilfe}" />
Content="{markup:Translate Region der Hilfe}" />
<uc:NullItemComboBox
x:Name="comboBox_HilfenRegion"
Grid.Row="2"
@@ -2309,9 +2313,10 @@
SelectedValue="{Binding Path=RegionType, Mode=TwoWay}" />
<Label
Name="lblSozSchwierigkeiten"
Grid.Row="3"
Grid.Column="2"
Name="lblSozSchwierigkeiten" Content="{markup:Translate Soziale Schwierigkeiten}" />
Content="{markup:Translate Soziale Schwierigkeiten}" />
<uc:NullItemComboBox
x:Name="comboBox_SozSchwierigkeiten"
Grid.Row="3"
@@ -2323,9 +2328,10 @@
ItemsSource="{Binding Path=SozSchwierigkeitenTypen, Mode=OneWay}"
SelectedValue="{Binding Path=SozSchwierigkeitenType, Mode=TwoWay}" />
<Label
Name="lblSozBeziehungen"
Grid.Row="4"
Grid.Column="2"
Name="lblSozBeziehungen" Content="{markup:Translate Soziale Beziehungen}" />
Content="{markup:Translate Soziale Beziehungen}" />
<uc:NullItemComboBox
x:Name="SozBeziehungen"
Grid.Row="4"

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using BeWo.ServiceProxy;
using BeWo.ViewModel.ListViewModel;
using BS.Shared;
using BS.Shared.DataContracts;
@@ -16,6 +17,7 @@ namespace BeWo.ViewModel
[JsonObject(MemberSerialization.OptIn)]
public class AiConversationVM : AbstractDCMapperVM<AiConversationDC>
{
private bool _IsEditing = false;
private string _Displayname;
private DateTime _Updated;
private AiConversationMessageListVM _Messages;
@@ -76,6 +78,14 @@ namespace BeWo.ViewModel
}
}
public bool IsEditing
{
get => _IsEditing;
set => SetProperty(ref _IsEditing, value, nameof(IsEditing));
}
public long Oid => DataContract.Oid.Value;
public long Version => DataContract.Version.Value;
public DateTime Created => DataContract.Created;
public AiModelDC Modell => DataContract.Modell;
public string Context => DataContract.Context;
@@ -119,5 +129,32 @@ namespace BeWo.ViewModel
}
return new AiConversationMessageListVM(messages);
}
public void ResetDisplayname()
{
Displayname = DataContract.Displayname;
}
public void SaveDisplayname()
{
if (!IsEditing)
return;
IsEditing = false;
if (DataContract.Displayname == Displayname)
return;
ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.UpdateAiConversationDisplayname(Oid, Version, Displayname),
callback =>
{
DataContract.Version = callback;
DataContract.Displayname = Displayname;
},
(ex) =>
{
ResetDisplayname();
});
}
}
}

View File

@@ -42,6 +42,7 @@ namespace BeWo.ViewModel.View
ReloadModelsCommand = new DelegateCommand(ReloadModels);
OpenSettingCommand = new DelegateCommand(OpenSetting, () => (BeWoApp.AppSettings?.ModuleAiSettingsEnabled ?? true) && BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleViewSetting));
RenameCommand = new DelegateCommand(Rename, () => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleChatEdit) && ListVM.SelectedVM is object);
OpenCloneCommand = new DelegateCommand(OpenClone, () => BeWoApp.HasLoggedOnUserRight(UserRightType.AiModuleChatClone) && ListVM.SelectedVM is object);
CloneCommand = new DelegateCommand(Clone);
@@ -64,6 +65,7 @@ namespace BeWo.ViewModel.View
public ICommand ReloadModelsCommand { get; set; }
public ICommand OpenSettingCommand { get; set; }
public ICommand RenameCommand { get; set; }
public ICommand OpenCloneCommand { get; set; }
public ICommand CloneCommand { get; set; }
@@ -333,6 +335,13 @@ namespace BeWo.ViewModel.View
IsSettingsOpen = true;
});
}
private void Rename()
{
if(ListVM.SelectedVM is AiConversationVM vm)
{
vm.IsEditing = !vm.IsEditing;
}
}
private void OpenClone()
{
foreach (var message in ListVM.SelectedVM.Messages.VMList)

View File

@@ -50,6 +50,11 @@ namespace BeWo.Service.ServiceContracts
[RequirePermission(UserRightType.AiModuleChatClone)]
AiConversationDC CloneAiConversation(long conversation_oid, long? message_oid);
[FaultContract(typeof(BeWoFault))]
[OperationContract]
[RequirePermission(UserRightType.AiModuleChatEdit)]
long UpdateAiConversationDisplayname(long oid, long version, string displayname);
[FaultContract(typeof(BeWoFault))]
[OperationContract]
[RequirePermission(UserRightType.AiModuleChatDelete)]

View File

@@ -39,6 +39,7 @@ namespace BeWo.Service.ServiceImplementations
// - WebConfig
// - DBs
// ======================[ Config ]======================
public AiConfigDC GetAiConfig()
{
var configs = DAOFactory.GenericDAO.GetAllActive<AiConfig>();
@@ -72,6 +73,7 @@ namespace BeWo.Service.ServiceImplementations
return dc;
}
// ======================[ Models ]======================
public IEnumerable<AiModelDC> GetAiModels()
{
var models = getAiModels();
@@ -79,6 +81,8 @@ namespace BeWo.Service.ServiceImplementations
return MapperFactory.AiModel.MapToNewDCs(models);
}
// ======================[ Conversations ]======================
public IEnumerable<AiConversationDC> GetAiConversations(int uicontext, long? oid)
{
// SearchDAO
@@ -102,10 +106,7 @@ namespace BeWo.Service.ServiceImplementations
if (uicontext == 19)
main_ref_obj = conv.ContextBeWoObjects.FirstOrDefault(x => x.Tid == TableID.SupportConcept);
if (main_ref_obj is null)
continue;
if (main_ref_obj.Oid != ref_oid)
if (main_ref_obj?.Oid != ref_oid)
continue;
}
@@ -116,41 +117,13 @@ namespace BeWo.Service.ServiceImplementations
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;
}
private AiConversation CreateAiConversation(int uicontext, Dictionary<TableID, long[]> 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 = "Displayname";
conv.Messages = new List<AiConversationMessage>();
conv.Modell = DAOFactory.GenericDAO.LoadByID<AiModel>(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;
}
public AiConversationDC CreateAiConversationWithMessage(AiConversationDC conversation, long modell_oid, string message)
{
var conv = CreateAiConversation(conversation.UIContext, conversation.ContextBeWoObjects, modell_oid);
@@ -161,7 +134,6 @@ namespace BeWo.Service.ServiceImplementations
return conv_dc;
}
public AiConversationDC CloneAiConversation(long conversation_oid, long? last_message_oid)
{
var parent_conv = DAOFactory.GenericDAO.GetByID<AiConversation>(conversation_oid);
@@ -206,6 +178,20 @@ namespace BeWo.Service.ServiceImplementations
return dc;
}
public 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 void DeleteAiConversation(long conversation_oid)
{
var conversation = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation_oid);
@@ -213,66 +199,16 @@ namespace BeWo.Service.ServiceImplementations
DAOFactory.GenericDAO.SetActivationType(conversation, ActivationTypeId.Deleted);
}
// ======================[ Conversationmessages ]======================
public AiConversationMessageDC[] SendNewMessage(long conversation, string message)
{
var conv = DAOFactory.GenericDAO.LoadByID<AiConversation>(conversation);
return SendNewMessage(conv, message);
}
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<string>());
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 ]======================
private AiConfig getDefaultAiConfig()
{
var config = new AiConfig();
@@ -336,5 +272,88 @@ namespace BeWo.Service.ServiceImplementations
return models;
}
private AiConversation CreateAiConversation(int uicontext, Dictionary<TableID, long[]> 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<AiConversationMessage>();
conv.Modell = DAOFactory.GenericDAO.LoadByID<AiModel>(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<string>());
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 };
}
}
}