mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-18 08:37:59 +00:00
Added importing of configurations exported from AI Studio (#1007)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
f8c0232cfd
commit
22065783c2
49 files changed
+3257
-263
No files matched your search
@@ -1,5 +1,6 @@
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Settings.DataModel
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@inherits MSGComponentBase
|
||||
|
||||
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||
@@ -115,21 +116,24 @@
|
||||
</MudText>
|
||||
}
|
||||
|
||||
<MudMenu EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@T("Add Data Source")" Color="Color.Primary" Variant="Variant.Filled" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" Class="mt-3 mb-6">
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.ERI_V1))">
|
||||
@T("External Data (ERI-Server v1)")
|
||||
</MudMenuItem>
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_DIRECTORY))">
|
||||
@T("Local Directory")
|
||||
</MudMenuItem>
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_FILE))">
|
||||
@T("Local File")
|
||||
</MudMenuItem>
|
||||
@if (PreviewFeatures.PRE_MAILBOXES_2026.IsEnabled(this.SettingsManager))
|
||||
{
|
||||
@* Shown with a lock rather than left out, like the locked buttons for adding providers: *@
|
||||
<MudMenuItem OnClick="@this.AddMailbox" Disabled="@(!this.MayAddMailbox)" Icon="@(this.MayAddMailbox ? null : Icons.Material.Filled.Lock)">
|
||||
@(this.MayAddMailbox ? T("Mailbox (IMAP)") : T("Mailbox (IMAP), not allowed by your organization"))
|
||||
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
|
||||
<MudMenu EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@T("Add Data Source")" Color="Color.Primary" Variant="Variant.Filled" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft">
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.ERI_V1))">
|
||||
@T("External Data (ERI-Server v1)")
|
||||
</MudMenuItem>
|
||||
}
|
||||
</MudMenu>
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_DIRECTORY))">
|
||||
@T("Local Directory")
|
||||
</MudMenuItem>
|
||||
<MudMenuItem OnClick="@(() => this.AddDataSource(DataSourceType.LOCAL_FILE))">
|
||||
@T("Local File")
|
||||
</MudMenuItem>
|
||||
@if (PreviewFeatures.PRE_MAILBOXES_2026.IsEnabled(this.SettingsManager))
|
||||
{
|
||||
@* Shown with a lock rather than left out, like the locked buttons for adding providers: *@
|
||||
<MudMenuItem OnClick="@this.AddMailbox" Disabled="@(!this.MayAddMailbox)" Icon="@(this.MayAddMailbox ? null : Icons.Material.Filled.Lock)">
|
||||
@(this.MayAddMailbox ? T("Mailbox (IMAP)") : T("Mailbox (IMAP), not allowed by your organization"))
|
||||
</MudMenuItem>
|
||||
}
|
||||
</MudMenu>
|
||||
<LockableButton Text="@T("Import Data Source")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportERIDataSource" ButtonVariant="Variant.Outlined" NoMargin="true" />
|
||||
</MudStack>
|
||||
@@ -185,6 +185,37 @@ public partial class DataSourceManagement : MSGComponentBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private async Task ImportERIDataSource()
|
||||
{
|
||||
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.DATA_SOURCE, T("Import Data Source"));
|
||||
if (import?.ConfigurationObject is not DataSourceERI_V1 dataSource)
|
||||
return;
|
||||
|
||||
var eriDialogParameters = new DialogParameters<DataSourceERI_V1Dialog>
|
||||
{
|
||||
{ x => x.IsEditing, false },
|
||||
{ x => x.IsImport, true },
|
||||
{ x => x.DataSource, dataSource },
|
||||
{ x => x.ImportedSecret, import.Secret },
|
||||
};
|
||||
|
||||
var eriDialogReference = await this.DialogService.ShowAsync<DataSourceERI_V1Dialog>(T("Add ERI v1 Data Source"), eriDialogParameters, DialogOptions.FULLSCREEN);
|
||||
var eriDialogResult = await eriDialogReference.Result;
|
||||
if (eriDialogResult is null || eriDialogResult.Canceled)
|
||||
return;
|
||||
|
||||
//
|
||||
// An organization can lock the import while the user is still filling in the form, e.g.,
|
||||
// with a new version of its configuration plugin. Hence, the permission is checked once
|
||||
// more before the imported data source is stored:
|
||||
//
|
||||
if (!this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DATA_SOURCE))
|
||||
return;
|
||||
|
||||
var eriDataSource = (DataSourceERI_V1)eriDialogResult.Data!;
|
||||
await this.StoreAddedDataSource(eriDataSource with { Num = this.SettingsManager.ConfigurationData.NextDataSourceNum++ });
|
||||
}
|
||||
|
||||
private async Task AddDataSource(DataSourceType type)
|
||||
{
|
||||
IDataSource? addedDataSource = null;
|
||||
@@ -244,6 +275,11 @@ public partial class DataSourceManagement : MSGComponentBase
|
||||
if(addedDataSource is null)
|
||||
return;
|
||||
|
||||
await this.StoreAddedDataSource(addedDataSource);
|
||||
}
|
||||
|
||||
private async Task StoreAddedDataSource(IDataSource addedDataSource)
|
||||
{
|
||||
this.SettingsManager.ConfigurationData.DataSources.Add(addedDataSource);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.DataSourceEmbeddingService.QueueDataSourceAsync(addedDataSource);
|
||||
@@ -616,4 +652,4 @@ public partial class DataSourceManagement : MSGComponentBase
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
@using AIStudio.Provider
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Settings.DataModel
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@inherits SettingsPanelProviderBase
|
||||
|
||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||
@@ -93,6 +94,9 @@
|
||||
</MudText>
|
||||
}
|
||||
|
||||
<LockableButton Text="@T("Add Embedding")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddEmbeddingProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddEmbeddingProvider" Class="mt-3" />
|
||||
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
|
||||
<LockableButton Text="@T("Add Embedding")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddEmbeddingProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddEmbeddingProvider" Class="flex-grow-0" NoMargin="true" />
|
||||
<LockableButton Text="@T("Import Embedding")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.EMBEDDING_PROVIDER))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportEmbeddingProvider" ButtonVariant="Variant.Outlined" Class="flex-grow-0" NoMargin="true" />
|
||||
</MudStack>
|
||||
</ExpansionPanel>
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System.Globalization;
|
||||
using AIStudio.Dialogs;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@@ -59,12 +60,36 @@ public partial class SettingsPanelEmbeddings : SettingsPanelProviderBase
|
||||
{
|
||||
{ x => x.IsEditing, false },
|
||||
};
|
||||
|
||||
|
||||
await this.AddEmbeddingProvider(dialogParameters, isImport: false);
|
||||
}
|
||||
|
||||
private async Task ImportEmbeddingProvider()
|
||||
{
|
||||
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.EMBEDDING_PROVIDER, T("Import Embedding"));
|
||||
if (import?.ConfigurationObject is not EmbeddingProvider embeddingProvider)
|
||||
return;
|
||||
|
||||
var dialogParameters = CreateDialogParameters(embeddingProvider, isEditing: false);
|
||||
dialogParameters.Add(x => x.ImportedAPIKey, import.Secret);
|
||||
await this.AddEmbeddingProvider(dialogParameters, isImport: true);
|
||||
}
|
||||
|
||||
private async Task AddEmbeddingProvider(DialogParameters<EmbeddingProviderDialog> dialogParameters, bool isImport)
|
||||
{
|
||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Add Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
//
|
||||
// An organization can lock the import while the user is still filling in the form, e.g.,
|
||||
// with a new version of its configuration plugin. Hence, the permission is checked once
|
||||
// more before the imported embedding provider is stored:
|
||||
//
|
||||
if (isImport && !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.EMBEDDING_PROVIDER))
|
||||
return;
|
||||
|
||||
var addedEmbedding = (EmbeddingProvider)dialogResult.Data!;
|
||||
addedEmbedding = addedEmbedding with { Num = this.SettingsManager.ConfigurationData.NextEmbeddingNum++ };
|
||||
|
||||
@@ -81,27 +106,7 @@ public partial class SettingsPanelEmbeddings : SettingsPanelProviderBase
|
||||
if (embeddingProvider.IsEnterpriseConfiguration && !embeddingProvider.AllowUserProvidedAPIKey)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<EmbeddingProviderDialog>
|
||||
{
|
||||
{ x => x.DataNum, embeddingProvider.Num },
|
||||
{ x => x.DataId, embeddingProvider.Id },
|
||||
{ x => x.DataName, embeddingProvider.Name },
|
||||
{ x => x.DataLLMProvider, embeddingProvider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, embeddingProvider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, embeddingProvider.Model },
|
||||
{ x => x.DataHostname, embeddingProvider.Hostname },
|
||||
{ x => x.IsSelfHosted, embeddingProvider.IsSelfHosted },
|
||||
{ x => x.IsEditing, true },
|
||||
{ x => x.DataHost, embeddingProvider.Host },
|
||||
{ x => x.DataTokenizerPath, embeddingProvider.TokenizerPath },
|
||||
{ x => x.DataTokenizerFingerprint, embeddingProvider.TokenizerFingerprint },
|
||||
{ x => x.DataTokenLimit, embeddingProvider.EffectiveTokenLimit },
|
||||
{ x => x.DataEmbeddingBatchSize, embeddingProvider.EffectiveEmbeddingBatchSize },
|
||||
{ x => x.HFInferenceProviderId, embeddingProvider.HFInferenceProvider },
|
||||
{ x => x.IsEnterpriseConfiguration, embeddingProvider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Edit Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Edit Embedding Provider"), CreateDialogParameters(embeddingProvider, isEditing: true), DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
@@ -131,6 +136,26 @@ public partial class SettingsPanelEmbeddings : SettingsPanelProviderBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private static DialogParameters<EmbeddingProviderDialog> CreateDialogParameters(EmbeddingProvider embeddingProvider, bool isEditing) => new()
|
||||
{
|
||||
{ x => x.DataNum, embeddingProvider.Num },
|
||||
{ x => x.DataId, embeddingProvider.Id },
|
||||
{ x => x.DataName, embeddingProvider.Name },
|
||||
{ x => x.DataLLMProvider, embeddingProvider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, embeddingProvider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, embeddingProvider.Model },
|
||||
{ x => x.DataHostname, embeddingProvider.Hostname },
|
||||
{ x => x.IsSelfHosted, embeddingProvider.IsSelfHosted },
|
||||
{ x => x.IsEditing, isEditing },
|
||||
{ x => x.DataHost, embeddingProvider.Host },
|
||||
{ x => x.DataTokenizerPath, embeddingProvider.TokenizerPath },
|
||||
{ x => x.DataTokenizerFingerprint, embeddingProvider.TokenizerFingerprint },
|
||||
{ x => x.DataTokenLimit, embeddingProvider.EffectiveTokenLimit },
|
||||
{ x => x.DataEmbeddingBatchSize, embeddingProvider.EffectiveEmbeddingBatchSize },
|
||||
{ x => x.HFInferenceProviderId, embeddingProvider.HFInferenceProvider },
|
||||
{ x => x.IsEnterpriseConfiguration, embeddingProvider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
private async Task DeleteEmbeddingProvider(EmbeddingProvider provider)
|
||||
{
|
||||
var question = string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name);
|
||||
@@ -261,4 +286,4 @@ public partial class SettingsPanelEmbeddings : SettingsPanelProviderBase
|
||||
|
||||
await this.DialogService.ShowAsync<EmbeddingResultDialog>(T("Embedding Result"), resultParameters, DialogOptions.FULLSCREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
@using AIStudio.Provider
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@inherits SettingsPanelProviderBase
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Layers" HeaderText="@T("Configure LLM Providers")">
|
||||
@@ -78,5 +79,8 @@
|
||||
</MudText>
|
||||
}
|
||||
|
||||
<LockableButton Text="@T("Add Provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddLLMProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddLLMProvider" Class="mt-3" />
|
||||
</ExpansionPanel>
|
||||
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
|
||||
<LockableButton Text="@T("Add Provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddLLMProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddLLMProvider" Class="flex-grow-0" NoMargin="true" />
|
||||
<LockableButton Text="@T("Import Provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.LLM_PROVIDER))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportProvider" ButtonVariant="Variant.Outlined" Class="flex-grow-0" NoMargin="true" />
|
||||
</MudStack>
|
||||
</ExpansionPanel>
|
||||
@@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using AIStudio.Dialogs;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
@@ -39,19 +40,43 @@ public partial class SettingsPanelProviders : SettingsPanelProviderBase
|
||||
|
||||
#endregion
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed", Justification = "Managing the provider list is the purpose of this settings panel. Reading providers goes through the settings manager, but adding, editing, and removing them stays here on purpose.")]
|
||||
private async Task AddLLMProvider()
|
||||
{
|
||||
var dialogParameters = new DialogParameters<ProviderDialog>
|
||||
{
|
||||
{ x => x.IsEditing, false },
|
||||
};
|
||||
|
||||
|
||||
await this.AddLLMProvider(dialogParameters, isImport: false);
|
||||
}
|
||||
|
||||
private async Task ImportProvider()
|
||||
{
|
||||
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.LLM_PROVIDER, T("Import Provider"));
|
||||
if (import?.ConfigurationObject is not AIStudio.Settings.Provider provider)
|
||||
return;
|
||||
|
||||
var dialogParameters = CreateDialogParameters(provider, isEditing: false);
|
||||
dialogParameters.Add(x => x.ImportedAPIKey, import.Secret);
|
||||
await this.AddLLMProvider(dialogParameters, isImport: true);
|
||||
}
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed", Justification = "Managing the provider list is the purpose of this settings panel. Reading providers goes through the settings manager, but adding, editing, and removing them stays here on purpose.")]
|
||||
private async Task AddLLMProvider(DialogParameters<ProviderDialog> dialogParameters, bool isImport)
|
||||
{
|
||||
var dialogReference = await this.DialogService.ShowAsync<ProviderDialog>(T("Add LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
//
|
||||
// An organization can lock the import while the user is still filling in the form, e.g.,
|
||||
// with a new version of its configuration plugin. Hence, the permission is checked once
|
||||
// more before the imported provider is stored:
|
||||
//
|
||||
if (isImport && !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.LLM_PROVIDER))
|
||||
return;
|
||||
|
||||
var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data!;
|
||||
addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
|
||||
|
||||
@@ -71,26 +96,7 @@ public partial class SettingsPanelProviders : SettingsPanelProviderBase
|
||||
if (provider.IsEnterpriseConfiguration && !provider.AllowUserProvidedAPIKey)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<ProviderDialog>
|
||||
{
|
||||
{ x => x.DataNum, provider.Num },
|
||||
{ x => x.DataId, provider.Id },
|
||||
{ x => x.DataInstanceName, provider.InstanceName },
|
||||
{ x => x.DataLLMProvider, provider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, provider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, provider.Model },
|
||||
{ x => x.DataHostname, provider.Hostname },
|
||||
{ x => x.IsSelfHosted, provider.IsSelfHosted },
|
||||
{ x => x.IsEditing, true },
|
||||
{ x => x.DataHost, provider.Host },
|
||||
{ x => x.HFInferenceProviderId, provider.HFInferenceProvider },
|
||||
{ x => x.AdditionalJsonApiParameters, provider.AdditionalJsonApiParameters },
|
||||
{ x => x.DataTokenizerPath, provider.TokenizerPath },
|
||||
{ x => x.DataCapabilityOverrides, provider.CapabilityOverrides },
|
||||
{ x => x.IsEnterpriseConfiguration, provider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ProviderDialog>(T("Edit LLM Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogReference = await this.DialogService.ShowAsync<ProviderDialog>(T("Edit LLM Provider"), CreateDialogParameters(provider, isEditing: true), DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
@@ -119,6 +125,25 @@ public partial class SettingsPanelProviders : SettingsPanelProviderBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private static DialogParameters<ProviderDialog> CreateDialogParameters(AIStudio.Settings.Provider provider, bool isEditing) => new()
|
||||
{
|
||||
{ x => x.DataNum, provider.Num },
|
||||
{ x => x.DataId, provider.Id },
|
||||
{ x => x.DataInstanceName, provider.InstanceName },
|
||||
{ x => x.DataLLMProvider, provider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, provider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, provider.Model },
|
||||
{ x => x.DataHostname, provider.Hostname },
|
||||
{ x => x.IsSelfHosted, provider.IsSelfHosted },
|
||||
{ x => x.IsEditing, isEditing },
|
||||
{ x => x.DataHost, provider.Host },
|
||||
{ x => x.HFInferenceProviderId, provider.HFInferenceProvider },
|
||||
{ x => x.AdditionalJsonApiParameters, provider.AdditionalJsonApiParameters },
|
||||
{ x => x.DataTokenizerPath, provider.TokenizerPath },
|
||||
{ x => x.DataCapabilityOverrides, provider.CapabilityOverrides },
|
||||
{ x => x.IsEnterpriseConfiguration, provider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed", Justification = "Managing the provider list is the purpose of this settings panel. Reading providers goes through the settings manager, but adding, editing, and removing them stays here on purpose.")]
|
||||
private async Task DeleteLLMProvider(AIStudio.Settings.Provider provider)
|
||||
{
|
||||
@@ -197,4 +222,4 @@ public partial class SettingsPanelProviders : SettingsPanelProviderBase
|
||||
await this.AvailableLLMProvidersChanged.InvokeAsync(this.AvailableLLMProviders);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
@using AIStudio.Provider
|
||||
@using AIStudio.Settings
|
||||
@using AIStudio.Settings.DataModel
|
||||
@using AIStudio.Tools.PluginSystem
|
||||
@inherits SettingsPanelProviderBase
|
||||
|
||||
@if (PreviewFeatures.PRE_SPEECH_TO_TEXT_2026.IsEnabled(this.SettingsManager))
|
||||
@@ -83,6 +84,9 @@
|
||||
</MudText>
|
||||
}
|
||||
|
||||
<LockableButton Text="@T("Add transcription provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddTranscriptionProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddTranscriptionProvider" Class="mt-3" />
|
||||
<MudStack Row="true" Wrap="Wrap.Wrap" Class="mt-3 mb-6">
|
||||
<LockableButton Text="@T("Add transcription provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.AllowUserToAddProvider || !this.SettingsManager.ConfigurationData.App.AllowUserToAddTranscriptionProvider)" Icon="@Icons.Material.Filled.AddRoad" OnClickAsync="@this.AddTranscriptionProvider" Class="flex-grow-0" NoMargin="true" />
|
||||
<LockableButton Text="@T("Import transcription provider")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER))" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportTranscriptionProvider" ButtonVariant="Variant.Outlined" Class="flex-grow-0" NoMargin="true" />
|
||||
</MudStack>
|
||||
</ExpansionPanel>
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using AIStudio.Dialogs;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
@@ -53,12 +54,36 @@ public partial class SettingsPanelTranscription : SettingsPanelProviderBase
|
||||
{
|
||||
{ x => x.IsEditing, false },
|
||||
};
|
||||
|
||||
|
||||
await this.AddTranscriptionProvider(dialogParameters, isImport: false);
|
||||
}
|
||||
|
||||
private async Task ImportTranscriptionProvider()
|
||||
{
|
||||
var import = await ConfigurationSnippetImportDialog.ShowAsync(this.DialogService, PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER, T("Import transcription provider"));
|
||||
if (import?.ConfigurationObject is not TranscriptionProvider transcriptionProvider)
|
||||
return;
|
||||
|
||||
var dialogParameters = CreateDialogParameters(transcriptionProvider, isEditing: false);
|
||||
dialogParameters.Add(x => x.ImportedAPIKey, import.Secret);
|
||||
await this.AddTranscriptionProvider(dialogParameters, isImport: true);
|
||||
}
|
||||
|
||||
private async Task AddTranscriptionProvider(DialogParameters<TranscriptionProviderDialog> dialogParameters, bool isImport)
|
||||
{
|
||||
var dialogReference = await this.DialogService.ShowAsync<TranscriptionProviderDialog>(T("Add Transcription Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
|
||||
//
|
||||
// An organization can lock the import while the user is still filling in the form, e.g.,
|
||||
// with a new version of its configuration plugin. Hence, the permission is checked once
|
||||
// more before the imported transcription provider is stored:
|
||||
//
|
||||
if (isImport && !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.TRANSCRIPTION_PROVIDER))
|
||||
return;
|
||||
|
||||
var addedTranscription = (TranscriptionProvider)dialogResult.Data!;
|
||||
addedTranscription = addedTranscription with { Num = this.SettingsManager.ConfigurationData.NextTranscriptionNum++ };
|
||||
|
||||
@@ -74,23 +99,7 @@ public partial class SettingsPanelTranscription : SettingsPanelProviderBase
|
||||
if (transcriptionProvider.IsEnterpriseConfiguration && !transcriptionProvider.AllowUserProvidedAPIKey)
|
||||
return;
|
||||
|
||||
var dialogParameters = new DialogParameters<TranscriptionProviderDialog>
|
||||
{
|
||||
{ x => x.DataNum, transcriptionProvider.Num },
|
||||
{ x => x.DataId, transcriptionProvider.Id },
|
||||
{ x => x.DataName, transcriptionProvider.Name },
|
||||
{ x => x.DataLLMProvider, transcriptionProvider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, transcriptionProvider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, transcriptionProvider.Model },
|
||||
{ x => x.DataHostname, transcriptionProvider.Hostname },
|
||||
{ x => x.IsSelfHosted, transcriptionProvider.IsSelfHosted },
|
||||
{ x => x.IsEditing, true },
|
||||
{ x => x.DataHost, transcriptionProvider.Host },
|
||||
{ x => x.HFInferenceProviderId, transcriptionProvider.HFInferenceProvider },
|
||||
{ x => x.IsEnterpriseConfiguration, transcriptionProvider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<TranscriptionProviderDialog>(T("Edit Transcription Provider"), dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogReference = await this.DialogService.ShowAsync<TranscriptionProviderDialog>(T("Edit Transcription Provider"), CreateDialogParameters(transcriptionProvider, isEditing: true), DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
@@ -119,6 +128,22 @@ public partial class SettingsPanelTranscription : SettingsPanelProviderBase
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private static DialogParameters<TranscriptionProviderDialog> CreateDialogParameters(TranscriptionProvider transcriptionProvider, bool isEditing) => new()
|
||||
{
|
||||
{ x => x.DataNum, transcriptionProvider.Num },
|
||||
{ x => x.DataId, transcriptionProvider.Id },
|
||||
{ x => x.DataName, transcriptionProvider.Name },
|
||||
{ x => x.DataLLMProvider, transcriptionProvider.UsedLLMProvider },
|
||||
{ x => x.DataCustomIconDataUrl, transcriptionProvider.CustomIconDataUrl },
|
||||
{ x => x.DataModel, transcriptionProvider.Model },
|
||||
{ x => x.DataHostname, transcriptionProvider.Hostname },
|
||||
{ x => x.IsSelfHosted, transcriptionProvider.IsSelfHosted },
|
||||
{ x => x.IsEditing, isEditing },
|
||||
{ x => x.DataHost, transcriptionProvider.Host },
|
||||
{ x => x.HFInferenceProviderId, transcriptionProvider.HFInferenceProvider },
|
||||
{ x => x.IsEnterpriseConfiguration, transcriptionProvider.IsEnterpriseConfiguration },
|
||||
};
|
||||
|
||||
private async Task DeleteTranscriptionProvider(TranscriptionProvider provider)
|
||||
{
|
||||
var dialogParameters = new DialogParameters<ConfirmDialog>
|
||||
@@ -161,4 +186,4 @@ public partial class SettingsPanelTranscription : SettingsPanelProviderBase
|
||||
|
||||
await this.AvailableTranscriptionProvidersChanged.InvokeAsync(this.AvailableTranscriptionProviders);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user