From 111d2619f6a7f1e71745ecd05bdc13dc2e5afccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peer=20Sch=C3=BCtt?= <20603780+peerschuett@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:27:27 +0100 Subject: [PATCH] Dialogs work now. Now I need to do the cleanup of unused code --- .../Components/AssistantBlock.razor | 4 +- .../Components/AssistantBlock.razor.cs | 18 +- .../Settings/SettingsPanelTranslation.razor | 20 -- .../SettingsPanelTranslation.razor.cs | 6 - .../SettingsDialogAgentContentCleaner.razor | 20 ++ ...SettingsDialogAgentContentCleaner.razor.cs | 5 + ...ttingsDialogAgentDataSourceSelection.razor | 19 ++ ...ngsDialogAgentDataSourceSelection.razor.cs | 5 + ...ialogAgentRetrievalContextValidation.razor | 28 ++ ...ogAgentRetrievalContextValidation.razor.cs | 5 + .../Dialogs/Settings/SettingsDialogApp.razor | 33 +++ .../Settings/SettingsDialogApp.razor.cs | 13 + .../Dialogs/Settings/SettingsDialogBase.cs | 33 +++ .../Dialogs/Settings/SettingsDialogChat.razor | 30 ++ .../Settings/SettingsDialogChat.razor.cs | 5 + .../Settings/SettingsDialogDataSources.razor | 69 +++++ .../SettingsDialogDataSources.razor.cs | 260 ++++++++++++++++++ .../Settings/SettingsDialogERIServer.razor | 27 ++ .../Settings/SettingsDialogERIServer.razor.cs | 5 + .../Settings/SettingsDialogEmbeddings.razor | 78 ++++++ .../SettingsDialogEmbeddings.razor.cs | 122 ++++++++ .../Settings/SettingsDialogProfiles.razor | 59 ++++ .../Settings/SettingsDialogProfiles.razor.cs | 73 +++++ .../Settings/SettingsDialogProviders.razor | 132 +++++++++ .../Settings/SettingsDialogProviders.razor.cs | 152 ++++++++++ .../Settings/SettingsDialogTranslation.razor | 27 ++ .../SettingsDialogTranslation.razor.cs | 7 + .../Settings/SettingsDialogWorkspaces.razor | 21 ++ .../SettingsDialogWorkspaces.razor.cs | 5 + app/MindWork AI Studio/Pages/Assistants.razor | 29 +- .../Pages/Assistants.razor.cs | 2 - app/MindWork AI Studio/Pages/Settings.razor | 25 +- .../Tools/JsRuntimeExtensions.cs | 2 +- app/MindWork AI Studio/Tools/NoComponent.cs | 16 ++ 34 files changed, 1286 insertions(+), 69 deletions(-) delete mode 100644 app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor delete mode 100644 app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor.cs create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor create mode 100644 app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor.cs create mode 100644 app/MindWork AI Studio/Tools/NoComponent.cs diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor b/app/MindWork AI Studio/Components/AssistantBlock.razor index 49a85803..b0350d7d 100644 --- a/app/MindWork AI Studio/Components/AssistantBlock.razor +++ b/app/MindWork AI Studio/Components/AssistantBlock.razor @@ -1,3 +1,5 @@ +@typeparam TSettings + @@ -24,7 +26,7 @@ - + diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs index 2d109c61..df5c84cd 100644 --- a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs +++ b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs @@ -2,9 +2,11 @@ using AIStudio.Settings; using Microsoft.AspNetCore.Components; +using DialogOptions = AIStudio.Dialogs.DialogOptions; + namespace AIStudio.Components; -public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDisposable +public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDisposable where TSettings : IComponent { [Parameter] public string Name { get; set; } = string.Empty; @@ -29,6 +31,16 @@ public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDispo [Inject] private MessageBus MessageBus { get; init; } = null!; + + [Inject] + private IDialogService DialogService { get; init; } = null!; + + private async Task OpenSettingsDialog() + { + var dialogParameters = new DialogParameters(); + + await this.DialogService.ShowAsync("Open Settings", dialogParameters, DialogOptions.FULLSCREEN); + } #region Overrides of ComponentBase @@ -44,7 +56,7 @@ public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDispo #region Implementation of IMessageBusReceiver - public string ComponentName => nameof(AssistantBlock); + public string ComponentName => nameof(AssistantBlock); public Task ProcessMessage(ComponentBase? sendingComponent, Event triggeredEvent, T? data) { @@ -64,7 +76,7 @@ public partial class AssistantBlock : ComponentBase, IMessageBusReceiver, IDispo } #endregion - + private string BorderColor => this.SettingsManager.IsDarkMode switch { true => this.ColorTheme.GetCurrentPalette(this.SettingsManager).GrayLight, diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor b/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor deleted file mode 100644 index f702807f..00000000 --- a/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor +++ /dev/null @@ -1,20 +0,0 @@ -@using AIStudio.Settings -@inherits SettingsPanelBase - - - - - - - - - - - @if (this.SettingsManager.ConfigurationData.Translation.PreselectedTargetLanguage is CommonLanguages.OTHER) - { - - } - - - - \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor.cs b/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor.cs deleted file mode 100644 index d831bd68..00000000 --- a/app/MindWork AI Studio/Components/Settings/SettingsPanelTranslation.razor.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AIStudio.Components.Settings; - -public partial class SettingsPanelTranslation : SettingsPanelBase -{ - protected override SettingsPanel Type => SettingsPanel.ASSISTANT_TRANSLATION_PANEL; -} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor new file mode 100644 index 00000000..3c12b1c3 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor @@ -0,0 +1,20 @@ +@inherits SettingsDialogBase + + + + Agent: Text Content Cleaner Options + + + + + Use Case: this agent is used to clean up text content. It extracts the main content, removes advertisements and other irrelevant things, + and attempts to convert relative links into absolute links so that they can be used. + + + + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor.cs new file mode 100644 index 00000000..e2d11084 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentContentCleaner.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogAgentContentCleaner : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor new file mode 100644 index 00000000..9d62a33f --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor @@ -0,0 +1,19 @@ +@inherits SettingsDialogBase + + + + Assistant: Agent: Data Source Selection Options + + + + + Use Case: this agent is used to select the appropriate data sources for the current prompt. + + + + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor.cs new file mode 100644 index 00000000..00c5c269 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentDataSourceSelection.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogAgentDataSourceSelection : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor new file mode 100644 index 00000000..408b6523 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor @@ -0,0 +1,28 @@ +@inherits SettingsDialogBase + + + + + Agent: Retrieval Context Validation Options + + + + + Use Case: this agent is used to validate any retrieval context of any retrieval process. Perhaps there are many of these + retrieval contexts and you want to validate them all. Therefore, you might want to use a cheap and fast LLM for this + job. When using a local or self-hosted LLM, look for a small (e.g. 3B) and fast model. + + + @if (this.SettingsManager.ConfigurationData.AgentRetrievalContextValidation.EnableRetrievalContextValidation) + { + + + + + + } + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor.cs new file mode 100644 index 00000000..c5aebc7f --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogAgentRetrievalContextValidation.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogAgentRetrievalContextValidation : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor new file mode 100644 index 00000000..33b9f358 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor @@ -0,0 +1,33 @@ +@using AIStudio.Settings +@using AIStudio.Settings.DataModel +@inherits SettingsDialogBase + + + + App Options + + + + + + + + + + @if (this.SettingsManager.ConfigurationData.App.PreviewVisibility > PreviewVisibility.NONE) + { + var availablePreviewFeatures = ConfigurationSelectDataFactory.GetPreviewFeaturesData(this.SettingsManager).ToList(); + if (availablePreviewFeatures.Count > 0) + { + + } + } + + + + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor.cs new file mode 100644 index 00000000..4b396e04 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogApp.razor.cs @@ -0,0 +1,13 @@ +using AIStudio.Settings.DataModel; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogApp : SettingsDialogBase +{ + private void UpdatePreviewFeatures(PreviewVisibility previewVisibility) + { + this.SettingsManager.ConfigurationData.App.PreviewVisibility = previewVisibility; + this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures = previewVisibility.FilterPreviewFeatures(this.SettingsManager.ConfigurationData.App.EnabledPreviewFeatures); + } + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs new file mode 100644 index 00000000..2ac40392 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogBase.cs @@ -0,0 +1,33 @@ +using System.Runtime.CompilerServices; +using AIStudio.Settings; +using AIStudio.Tools.Services; + +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Dialogs.Settings; + +public abstract class SettingsDialogBase : ComponentBase +{ + [CascadingParameter] + protected MudDialogInstance MudDialog { get; set; } = null!; + + [CascadingParameter] + public Pages.Settings Settings { get; set; } = null!; + + [Parameter] + public Func>> AvailableLLMProvidersFunc { get; set; } = () => []; + + [Inject] + protected SettingsManager SettingsManager { get; init; } = null!; + + [Inject] + protected IDialogService DialogService { get; init; } = null!; + + [Inject] + protected MessageBus MessageBus { get; init; } = null!; + + [Inject] + protected RustService RustService { get; init; } = null!; + + protected void Close() => this.MudDialog.Cancel(); +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor new file mode 100644 index 00000000..a619b38f --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor @@ -0,0 +1,30 @@ +@using AIStudio.Settings +@using AIStudio.Settings.DataModel +@inherits SettingsDialogBase + + + + Chat Options + + + + + + + + + + + + + + @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) + { + + + } + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor.cs new file mode 100644 index 00000000..5e0cc64a --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChat.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogChat : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor new file mode 100644 index 00000000..13532844 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor @@ -0,0 +1,69 @@ +@using AIStudio.Settings.DataModel +@inherits SettingsDialogBase + +@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) +{ + + + Configure Data Sources + + + + + Configured Data Sources + + + You might configure different data sources. A data source can include one file, all files + in a directory, or data from your company. Later, you can incorporate these data sources + as needed when the AI requires this data to complete a certain task. + + + + + + + + + + + + # + Name + Type + Embedding + Actions + + + @context.Num + @context.Name + @context.Type.GetDisplayName() + @this.GetEmbeddingName(context) + + + + + Edit + + + Delete + + + + + + @if (this.SettingsManager.ConfigurationData.DataSources.Count == 0) + { + No data sources configured yet. + } + + + External Data (ERI-Server v1) + Local Directory + Local File + + + + Close + + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor.cs new file mode 100644 index 00000000..12615766 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogDataSources.razor.cs @@ -0,0 +1,260 @@ +using AIStudio.Dialogs; +using AIStudio.Settings; +using AIStudio.Settings.DataModel; +using AIStudio.Tools.ERIClient.DataModel; + +using Microsoft.AspNetCore.Components; + +using DialogOptions = AIStudio.Dialogs.DialogOptions; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogDataSources : SettingsDialogBase +{ + [Parameter] + public List> AvailableDataSources { get; set; } = new(); + + [Parameter] + public EventCallback>> AvailableDataSourcesChanged { get; set; } + + [Parameter] + public Func>> AvailableEmbeddingsFunc { get; set; } = () => []; + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + await this.UpdateDataSources(); + await base.OnInitializedAsync(); + } + + #endregion + + private string GetEmbeddingName(IDataSource dataSource) + { + if(dataSource is IInternalDataSource internalDataSource) + { + var matchedEmbedding = this.SettingsManager.ConfigurationData.EmbeddingProviders.FirstOrDefault(x => x.Id == internalDataSource.EmbeddingId); + if(matchedEmbedding == default) + return "No valid embedding"; + + return matchedEmbedding.Name; + } + + if(dataSource is IExternalDataSource) + return "External (ERI)"; + + return "Unknown"; + } + + private async Task AddDataSource(DataSourceType type) + { + IDataSource? addedDataSource = null; + switch (type) + { + case DataSourceType.LOCAL_FILE: + var localFileDialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + { x => x.AvailableEmbeddings, this.AvailableEmbeddingsFunc() } + }; + + var localFileDialogReference = await this.DialogService.ShowAsync("Add Local File as Data Source", localFileDialogParameters, DialogOptions.FULLSCREEN); + var localFileDialogResult = await localFileDialogReference.Result; + if (localFileDialogResult is null || localFileDialogResult.Canceled) + return; + + var localFile = (DataSourceLocalFile)localFileDialogResult.Data!; + localFile = localFile with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ }; + addedDataSource = localFile; + break; + + case DataSourceType.LOCAL_DIRECTORY: + var localDirectoryDialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + { x => x.AvailableEmbeddings, this.AvailableEmbeddingsFunc() } + }; + + var localDirectoryDialogReference = await this.DialogService.ShowAsync("Add Local Directory as Data Source", localDirectoryDialogParameters, DialogOptions.FULLSCREEN); + var localDirectoryDialogResult = await localDirectoryDialogReference.Result; + if (localDirectoryDialogResult is null || localDirectoryDialogResult.Canceled) + return; + + var localDirectory = (DataSourceLocalDirectory)localDirectoryDialogResult.Data!; + localDirectory = localDirectory with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ }; + addedDataSource = localDirectory; + break; + + case DataSourceType.ERI_V1: + var eriDialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + }; + + var eriDialogReference = await this.DialogService.ShowAsync("Add ERI v1 Data Source", eriDialogParameters, DialogOptions.FULLSCREEN); + var eriDialogResult = await eriDialogReference.Result; + if (eriDialogResult is null || eriDialogResult.Canceled) + return; + + var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!; + eriDataSource = eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ }; + addedDataSource = eriDataSource; + break; + } + + if(addedDataSource is null) + return; + + this.SettingsManager.ConfigurationData.DataSources.Add(addedDataSource); + await this.UpdateDataSources(); + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task EditDataSource(IDataSource dataSource) + { + IDataSource? editedDataSource = null; + switch (dataSource) + { + case DataSourceLocalFile localFile: + var localFileDialogParameters = new DialogParameters + { + { x => x.IsEditing, true }, + { x => x.DataSource, localFile }, + { x => x.AvailableEmbeddings, this.AvailableEmbeddingsFunc() } + }; + + var localFileDialogReference = await this.DialogService.ShowAsync("Edit Local File Data Source", localFileDialogParameters, DialogOptions.FULLSCREEN); + var localFileDialogResult = await localFileDialogReference.Result; + if (localFileDialogResult is null || localFileDialogResult.Canceled) + return; + + editedDataSource = (DataSourceLocalFile)localFileDialogResult.Data!; + break; + + case DataSourceLocalDirectory localDirectory: + var localDirectoryDialogParameters = new DialogParameters + { + { x => x.IsEditing, true }, + { x => x.DataSource, localDirectory }, + { x => x.AvailableEmbeddings, this.AvailableEmbeddingsFunc() } + }; + + var localDirectoryDialogReference = await this.DialogService.ShowAsync("Edit Local Directory Data Source", localDirectoryDialogParameters, DialogOptions.FULLSCREEN); + var localDirectoryDialogResult = await localDirectoryDialogReference.Result; + if (localDirectoryDialogResult is null || localDirectoryDialogResult.Canceled) + return; + + editedDataSource = (DataSourceLocalDirectory)localDirectoryDialogResult.Data!; + break; + + case DataSourceERI_V1 eriDataSource: + var eriDialogParameters = new DialogParameters + { + { x => x.IsEditing, true }, + { x => x.DataSource, eriDataSource }, + }; + + var eriDialogReference = await this.DialogService.ShowAsync("Edit ERI v1 Data Source", eriDialogParameters, DialogOptions.FULLSCREEN); + var eriDialogResult = await eriDialogReference.Result; + if (eriDialogResult is null || eriDialogResult.Canceled) + return; + + editedDataSource = (DataSourceERI_V1)eriDialogResult.Data!; + break; + } + + if(editedDataSource is null) + return; + + this.SettingsManager.ConfigurationData.DataSources[this.SettingsManager.ConfigurationData.DataSources.IndexOf(dataSource)] = editedDataSource; + + await this.UpdateDataSources(); + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task DeleteDataSource(IDataSource dataSource) + { + var dialogParameters = new DialogParameters + { + { "Message", $"Are you sure you want to delete the data source '{dataSource.Name}' of type {dataSource.Type.GetDisplayName()}?" }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Delete Data Source", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var applyChanges = dataSource is IInternalDataSource; + + // External data sources may need a secret for authentication: + if (dataSource is IExternalDataSource externalDataSource) + { + // When the auth method is NONE or KERBEROS, we don't need to delete a secret. + // In the case of KERBEROS, we don't store the Kerberos ticket in the secret store. + if(dataSource is IERIDataSource { AuthMethod: AuthMethod.NONE or AuthMethod.KERBEROS }) + applyChanges = true; + + // All other auth methods require a secret, which we need to delete now: + else + { + var deleteSecretResponse = await this.RustService.DeleteSecret(externalDataSource); + if (deleteSecretResponse.Success) + applyChanges = true; + } + } + + if(applyChanges) + { + this.SettingsManager.ConfigurationData.DataSources.Remove(dataSource); + await this.SettingsManager.StoreSettings(); + await this.UpdateDataSources(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + } + + private async Task ShowInformation(IDataSource dataSource) + { + switch (dataSource) + { + case DataSourceLocalFile localFile: + var localFileDialogParameters = new DialogParameters + { + { x => x.DataSource, localFile }, + }; + + await this.DialogService.ShowAsync("Local File Data Source Information", localFileDialogParameters, DialogOptions.FULLSCREEN); + break; + + case DataSourceLocalDirectory localDirectory: + var localDirectoryDialogParameters = new DialogParameters + { + { x => x.DataSource, localDirectory }, + }; + + await this.DialogService.ShowAsync("Local Directory Data Source Information", localDirectoryDialogParameters, DialogOptions.FULLSCREEN); + break; + + case DataSourceERI_V1 eriV1DataSource: + var eriV1DialogParameters = new DialogParameters + { + { x => x.DataSource, eriV1DataSource }, + }; + + await this.DialogService.ShowAsync("ERI v1 Data Source Information", eriV1DialogParameters, DialogOptions.FULLSCREEN); + break; + } + } + + private async Task UpdateDataSources() + { + this.AvailableDataSources.Clear(); + foreach (var dataSource in this.SettingsManager.ConfigurationData.DataSources) + this.AvailableDataSources.Add(new (dataSource.Name, dataSource.Id)); + + await this.AvailableDataSourcesChanged.InvokeAsync(this.AvailableDataSources); + } + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor new file mode 100644 index 00000000..10bb4a4a --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor @@ -0,0 +1,27 @@ +@using AIStudio.Settings +@inherits SettingsDialogBase + + + + Assistant: ERI Server + + + + + + + + + Most ERI server options can be customized and saved directly in the ERI server assistant. + For this, the ERI server assistant has an auto-save function. + + + + Switch to ERI server assistant + + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor.cs new file mode 100644 index 00000000..9f497c1b --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogERIServer.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogERIServer : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor new file mode 100644 index 00000000..51a41c6d --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor @@ -0,0 +1,78 @@ +@using AIStudio.Provider +@using AIStudio.Settings.DataModel +@inherits SettingsDialogBase + +@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) +{ + + + Configure Embeddings + + + + + Configured Embeddings + + + Embeddings are a way to represent words, sentences, entire documents, or even images and videos as digital + fingerprints. Just like each person has a unique fingerprint, embedding models create unique digital patterns + that capture the meaning and characteristics of the content they analyze. When two things are similar in meaning + or content, their digital fingerprints will look very similar. For example, the fingerprints for 'happy' and + 'joyful' would be more alike than those for 'happy' and 'sad'. + + + + This helps AI Studio understand and compare things in a way that's similar to how humans do. When you're working on + something, AI Studio can automatically identify related documents and data by comparing their digital fingerprints. + For instance, if you're writing about customer service, AI Studio can instantly find other documents in your data that + discuss similar topics or experiences, even if they use different words. + + + + + + + + + + + # + Name + Provider + Model + Actions + + + @context.Num + @context.Name + @context.UsedLLMProvider + @this.GetEmbeddingProviderModelName(context) + + + + Open Dashboard + + + Edit + + + Delete + + + + + + @if (this.SettingsManager.ConfigurationData.EmbeddingProviders.Count == 0) + { + No embeddings configured yet. + } + + + Add Embedding + + + + Close + + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor.cs new file mode 100644 index 00000000..05753559 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogEmbeddings.razor.cs @@ -0,0 +1,122 @@ +using AIStudio.Dialogs; +using AIStudio.Settings; + +using Microsoft.AspNetCore.Components; + +using DialogOptions = AIStudio.Dialogs.DialogOptions; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogEmbeddings : SettingsDialogBase +{ + [Parameter] + public List> AvailableEmbeddingProviders { get; set; } = new(); + + [Parameter] + public EventCallback>> AvailableEmbeddingProvidersChanged { get; set; } + + private string GetEmbeddingProviderModelName(EmbeddingProvider provider) + { + const int MAX_LENGTH = 36; + var modelName = provider.Model.ToString(); + return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; + } + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + await this.UpdateEmbeddingProviders(); + await base.OnInitializedAsync(); + } + + #endregion + + private async Task AddEmbeddingProvider() + { + var dialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Add Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var addedEmbedding = (EmbeddingProvider)dialogResult.Data!; + addedEmbedding = addedEmbedding with { Num = this.SettingsManager.ConfigurationData.NextEmbeddingNum++ }; + + this.SettingsManager.ConfigurationData.EmbeddingProviders.Add(addedEmbedding); + await this.UpdateEmbeddingProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task EditEmbeddingProvider(EmbeddingProvider embeddingProvider) + { + var dialogParameters = new DialogParameters + { + { x => x.DataNum, embeddingProvider.Num }, + { x => x.DataId, embeddingProvider.Id }, + { x => x.DataName, embeddingProvider.Name }, + { x => x.DataLLMProvider, embeddingProvider.UsedLLMProvider }, + { x => x.DataModel, embeddingProvider.Model }, + { x => x.DataHostname, embeddingProvider.Hostname }, + { x => x.IsSelfHosted, embeddingProvider.IsSelfHosted }, + { x => x.IsEditing, true }, + { x => x.DataHost, embeddingProvider.Host }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Edit Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var editedEmbeddingProvider = (EmbeddingProvider)dialogResult.Data!; + + // Set the provider number if it's not set. This is important for providers + // added before we started saving the provider number. + if(editedEmbeddingProvider.Num == 0) + editedEmbeddingProvider = editedEmbeddingProvider with { Num = this.SettingsManager.ConfigurationData.NextEmbeddingNum++ }; + + this.SettingsManager.ConfigurationData.EmbeddingProviders[this.SettingsManager.ConfigurationData.EmbeddingProviders.IndexOf(embeddingProvider)] = editedEmbeddingProvider; + await this.UpdateEmbeddingProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task DeleteEmbeddingProvider(EmbeddingProvider provider) + { + var dialogParameters = new DialogParameters + { + { "Message", $"Are you sure you want to delete the embedding provider '{provider.Name}'?" }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Delete Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var deleteSecretResponse = await this.RustService.DeleteAPIKey(provider); + if(deleteSecretResponse.Success) + { + this.SettingsManager.ConfigurationData.EmbeddingProviders.Remove(provider); + await this.SettingsManager.StoreSettings(); + } + + await this.UpdateEmbeddingProviders(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task UpdateEmbeddingProviders() + { + this.AvailableEmbeddingProviders.Clear(); + foreach (var provider in this.SettingsManager.ConfigurationData.EmbeddingProviders) + this.AvailableEmbeddingProviders.Add(new (provider.Name, provider.Id)); + + await this.AvailableEmbeddingProvidersChanged.InvokeAsync(this.AvailableEmbeddingProviders); + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor new file mode 100644 index 00000000..69543c92 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor @@ -0,0 +1,59 @@ +@inherits SettingsDialogBase + + + + + Configure Profiles + + + Your Profiles + + Store personal data about yourself in various profiles so that the AIs know your personal context. + This saves you from having to explain your context each time, for example, in every chat. When you + have different roles, you can create a profile for each role. + + + + Are you a project manager in a research facility? You might want to create a profile for your project + management activities, one for your scientific work, and a profile for when you need to write program + code. In these profiles, you can record how much experience you have or which methods you like or + dislike using. Later, you can choose when and where you want to use each profile. + + + + + + + + + # + Profile Name + Actions + + + @context.Num + @context.Name + + + Edit + + + Delete + + + + + + @if(this.SettingsManager.ConfigurationData.Profiles.Count == 0) + { + No profiles configured yet. + } + + + Add Profile + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor.cs new file mode 100644 index 00000000..f9116758 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProfiles.razor.cs @@ -0,0 +1,73 @@ +using AIStudio.Dialogs; +using AIStudio.Settings; + +using DialogOptions = AIStudio.Dialogs.DialogOptions; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogProfiles : SettingsDialogBase +{ + private async Task AddProfile() + { + var dialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Add Profile", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var addedProfile = (Profile)dialogResult.Data!; + addedProfile = addedProfile with { Num = this.SettingsManager.ConfigurationData.NextProfileNum++ }; + + this.SettingsManager.ConfigurationData.Profiles.Add(addedProfile); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task EditProfile(Profile profile) + { + var dialogParameters = new DialogParameters + { + { x => x.DataNum, profile.Num }, + { x => x.DataId, profile.Id }, + { x => x.DataName, profile.Name }, + { x => x.DataNeedToKnow, profile.NeedToKnow }, + { x => x.DataActions, profile.Actions }, + { x => x.IsEditing, true }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Edit Profile", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var editedProfile = (Profile)dialogResult.Data!; + this.SettingsManager.ConfigurationData.Profiles[this.SettingsManager.ConfigurationData.Profiles.IndexOf(profile)] = editedProfile; + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private async Task DeleteProfile(Profile profile) + { + var dialogParameters = new DialogParameters + { + { "Message", $"Are you sure you want to delete the profile '{profile.Name}'?" }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Delete Profile", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + this.SettingsManager.ConfigurationData.Profiles.Remove(profile); + await this.SettingsManager.StoreSettings(); + + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor new file mode 100644 index 00000000..aa414072 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor @@ -0,0 +1,132 @@ +@using AIStudio.Provider +@using AIStudio.Settings +@using AIStudio.Provider.SelfHosted +@inherits SettingsDialogBase + + + + Configure Providers + + + Configured Providers + + What we call a provider is the combination of an LLM provider such as OpenAI and a model like GPT-4o. + You can configure as many providers as you want. This way, you can use the appropriate model for each + task. As an LLM provider, you can also choose local providers. However, to use this app, you must + configure at least one provider. + + + + + + + + + + + # + Instance Name + Provider + Model + Actions + + + @context.Num + @context.InstanceName + @context.UsedLLMProvider + + @if (context.UsedLLMProvider is not LLMProviders.SELF_HOSTED) + { + @this.GetLLMProviderModelName(context) + } + else if (context.UsedLLMProvider is LLMProviders.SELF_HOSTED && context.Host is not Host.LLAMACPP) + { + @this.GetLLMProviderModelName(context) + } + else + { + @("as selected by provider") + } + + + + Open Dashboard + + + Edit + + + Delete + + + + + + @if(this.SettingsManager.ConfigurationData.Providers.Count == 0) + { + No providers configured yet. + } + + + Add Provider + + + LLM Provider Confidence + + Do you want to always be able to recognize how trustworthy your LLM providers are? This way, + you keep control over which provider you send your data to. You have two options for this: + Either you choose a common schema, or you configure the trust levels for each LLM provider yourself. + + + + @if(this.SettingsManager.ConfigurationData.LLMProviders.EnforceGlobalMinimumConfidence) + { + + } + + + @if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence) + { + + @if (this.SettingsManager.ConfigurationData.LLMProviders.ConfidenceScheme is ConfidenceSchemes.CUSTOM) + { + + + + + + + + LLM Provider + Description + Confidence Level + + + + @context.ToName() + + + + + + + @foreach (var confidenceLevel in Enum.GetValues().OrderBy(n => n)) + { + if(confidenceLevel is ConfidenceLevel.NONE or ConfidenceLevel.UNKNOWN) + continue; + + + @confidenceLevel.GetName() + + } + + + + + } + } + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor.cs new file mode 100644 index 00000000..b000f571 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogProviders.razor.cs @@ -0,0 +1,152 @@ +using System.Diagnostics.CodeAnalysis; + +using AIStudio.Dialogs; +using AIStudio.Provider; +using AIStudio.Settings; + +using Microsoft.AspNetCore.Components; + +using DialogOptions = AIStudio.Dialogs.DialogOptions; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogProviders : SettingsDialogBase +{ + [Parameter] + public List> AvailableLLMProviders { get; set; } = new(); + + [Parameter] + public EventCallback>> AvailableLLMProvidersChanged { get; set; } + + #region Overrides of ComponentBase + + protected override async Task OnInitializedAsync() + { + await this.UpdateProviders(); + await base.OnInitializedAsync(); + } + + #endregion + + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + private async Task AddLLMProvider() + { + var dialogParameters = new DialogParameters + { + { x => x.IsEditing, false }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Add LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; + addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; + + this.SettingsManager.ConfigurationData.Providers.Add(addedProvider); + await this.UpdateProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + private async Task EditLLMProvider(AIStudio.Settings.Provider provider) + { + var dialogParameters = new DialogParameters + { + { x => x.DataNum, provider.Num }, + { x => x.DataId, provider.Id }, + { x => x.DataInstanceName, provider.InstanceName }, + { x => x.DataLLMProvider, provider.UsedLLMProvider }, + { x => x.DataModel, provider.Model }, + { x => x.DataHostname, provider.Hostname }, + { x => x.IsSelfHosted, provider.IsSelfHosted }, + { x => x.IsEditing, true }, + { x => x.DataHost, provider.Host }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Edit LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var editedProvider = (AIStudio.Settings.Provider)dialogResult.Data!; + + // Set the provider number if it's not set. This is important for providers + // added before we started saving the provider number. + if(editedProvider.Num == 0) + editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; + + this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider; + await this.UpdateProviders(); + + await this.SettingsManager.StoreSettings(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider) + { + var dialogParameters = new DialogParameters + { + { "Message", $"Are you sure you want to delete the provider '{provider.InstanceName}'?" }, + }; + + var dialogReference = await this.DialogService.ShowAsync("Delete LLM Provider", dialogParameters, DialogOptions.FULLSCREEN); + var dialogResult = await dialogReference.Result; + if (dialogResult is null || dialogResult.Canceled) + return; + + var deleteSecretResponse = await this.RustService.DeleteAPIKey(provider); + if(deleteSecretResponse.Success) + { + this.SettingsManager.ConfigurationData.Providers.Remove(provider); + await this.SettingsManager.StoreSettings(); + } + + await this.UpdateProviders(); + await this.MessageBus.SendMessage(this, Event.CONFIGURATION_CHANGED); + } + + private string GetLLMProviderModelName(AIStudio.Settings.Provider provider) + { + const int MAX_LENGTH = 36; + var modelName = provider.Model.ToString(); + return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; + } + + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + private async Task UpdateProviders() + { + this.AvailableLLMProviders.Clear(); + foreach (var provider in this.SettingsManager.ConfigurationData.Providers) + this.AvailableLLMProviders.Add(new (provider.InstanceName, provider.Id)); + + await this.AvailableLLMProvidersChanged.InvokeAsync(this.AvailableLLMProviders); + } + + private string GetCurrentConfidenceLevelName(LLMProviders llmProvider) + { + if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) + return level.GetName(); + + return "Not yet configured"; + } + + private string SetCurrentConfidenceLevelColorStyle(LLMProviders llmProvider) + { + if (this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme.TryGetValue(llmProvider, out var level)) + return $"background-color: {level.GetColor(this.SettingsManager)};"; + + return $"background-color: {ConfidenceLevel.UNKNOWN.GetColor(this.SettingsManager)};"; + } + + private async Task ChangeCustomConfidenceLevel(LLMProviders llmProvider, ConfidenceLevel level) + { + this.SettingsManager.ConfigurationData.LLMProviders.CustomConfidenceScheme[llmProvider] = level; + await this.SettingsManager.StoreSettings(); + } + +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor new file mode 100644 index 00000000..0a6749cc --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor @@ -0,0 +1,27 @@ +@using AIStudio.Settings +@inherits SettingsDialogBase + + + Assistant: Translator Options + + + + + + + + + + + @if (this.SettingsManager.ConfigurationData.Translation.PreselectedTargetLanguage is CommonLanguages.OTHER) + { + + } + + + + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor.cs new file mode 100644 index 00000000..9e1d60c3 --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogTranslation.razor.cs @@ -0,0 +1,7 @@ +using AIStudio.Dialogs.Settings; + +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogTranslation : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor new file mode 100644 index 00000000..c6f4e8ab --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor @@ -0,0 +1,21 @@ +@using AIStudio.Settings +@using AIStudio.Settings.DataModel +@inherits SettingsDialogBase + + + + Workspace Options + + + + + @if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES) + { + + + } + + + Close + + \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor.cs new file mode 100644 index 00000000..7954d8cf --- /dev/null +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogWorkspaces.razor.cs @@ -0,0 +1,5 @@ +namespace AIStudio.Dialogs.Settings; + +public partial class SettingsDialogWorkspaces : SettingsDialogBase +{ +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Pages/Assistants.razor b/app/MindWork AI Studio/Pages/Assistants.razor index 9cef736d..25a50f19 100644 --- a/app/MindWork AI Studio/Pages/Assistants.razor +++ b/app/MindWork AI Studio/Pages/Assistants.razor @@ -1,3 +1,4 @@ +@using AIStudio.Dialogs.Settings @using AIStudio.Settings.DataModel @attribute [Route(Routes.ASSISTANTS)] @@ -12,40 +13,40 @@ General - - - - - + + + + + Business - - - - - - + + + + + + Learning - + Software Engineering - + @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) { - + } diff --git a/app/MindWork AI Studio/Pages/Assistants.razor.cs b/app/MindWork AI Studio/Pages/Assistants.razor.cs index 83feb114..ef2af6db 100644 --- a/app/MindWork AI Studio/Pages/Assistants.razor.cs +++ b/app/MindWork AI Studio/Pages/Assistants.razor.cs @@ -8,6 +8,4 @@ public partial class Assistants : ComponentBase { [Inject] public SettingsManager SettingsManager { get; set; } = null!; - - //TODO: On click aus AssistantBase.razor.cs -> private method mit hardcoded T } \ No newline at end of file diff --git a/app/MindWork AI Studio/Pages/Settings.razor b/app/MindWork AI Studio/Pages/Settings.razor index 11ba4f50..8cbc725d 100644 --- a/app/MindWork AI Studio/Pages/Settings.razor +++ b/app/MindWork AI Studio/Pages/Settings.razor @@ -8,36 +8,17 @@ - + @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) { } - + - - - - - - @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) - { - - } - - - - - - - - - - - + @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) { diff --git a/app/MindWork AI Studio/Tools/JsRuntimeExtensions.cs b/app/MindWork AI Studio/Tools/JsRuntimeExtensions.cs index 1e940adc..e00cf16a 100644 --- a/app/MindWork AI Studio/Tools/JsRuntimeExtensions.cs +++ b/app/MindWork AI Studio/Tools/JsRuntimeExtensions.cs @@ -7,7 +7,7 @@ public static class JsRuntimeExtensions { public static async Task GenerateAndShowDiff(this IJSRuntime jsRuntime, string text1, string text2) { - await jsRuntime.InvokeVoidAsync("generateDiff", text1, text2, AssistantBase.RESULT_DIV_ID, AssistantBase.BEFORE_RESULT_DIV_ID); + await jsRuntime.InvokeVoidAsync("generateDiff", text1, text2, AssistantBase.RESULT_DIV_ID, AssistantBase.BEFORE_RESULT_DIV_ID); } public static async Task ClearDiv(this IJSRuntime jsRuntime, string divId) diff --git a/app/MindWork AI Studio/Tools/NoComponent.cs b/app/MindWork AI Studio/Tools/NoComponent.cs new file mode 100644 index 00000000..f0072efa --- /dev/null +++ b/app/MindWork AI Studio/Tools/NoComponent.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Components; + +namespace AIStudio.Tools; + +public sealed class NoComponent: IComponent +{ + public void Attach(RenderHandle renderHandle) + { + throw new NotImplementedException(); + } + + public Task SetParametersAsync(ParameterView parameters) + { + throw new NotImplementedException(); + } +} \ No newline at end of file