Add localization for embedding configuration and dialogs

This commit is contained in:
Thorsten Sommer 2025-05-11 16:55:47 +02:00
parent f10d9a5d88
commit f66428b41e
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
7 changed files with 196 additions and 67 deletions

View File

@ -1120,6 +1120,57 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCHAT::T492357592"]
-- When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown. -- When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCHAT::T582516016"] = "When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELCHAT::T582516016"] = "When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown."
-- Delete
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T1469573738"] = "Delete"
-- Add Embedding
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T1738753945"] = "Add Embedding"
-- Are you sure you want to delete the embedding provider '{0}'?
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T1825371968"] = "Are you sure you want to delete the embedding provider '{0}'?"
-- Add Embedding Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T190634634"] = "Add Embedding Provider"
-- Model
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T2189814010"] = "Model"
-- 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'.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T2419962612"] = "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'."
-- Name
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T266367750"] = "Name"
-- 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.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T3251217940"] = "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."
-- Edit
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T3267849393"] = "Edit"
-- Configured Embeddings
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T3526613453"] = "Configured Embeddings"
-- Actions
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T3865031940"] = "Actions"
-- No embeddings configured yet.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T4068015588"] = "No embeddings configured yet."
-- Edit Embedding Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T4264602229"] = "Edit Embedding Provider"
-- Delete Embedding Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T511304264"] = "Delete Embedding Provider"
-- Open Dashboard
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T78223861"] = "Open Dashboard"
-- Provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T900237532"] = "Provider"
-- Configure Embeddings
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELEMBEDDINGS::T970042679"] = "Configure Embeddings"
-- Edit Profile -- Edit Profile
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROFILES::T1143111468"] = "Edit Profile" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROFILES::T1143111468"] = "Edit Profile"
@ -1447,6 +1498,60 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CONFIRMDIALOG::T1642511898"] = "No"
-- Yes -- Yes
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CONFIRMDIALOG::T3013883440"] = "Yes" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::CONFIRMDIALOG::T3013883440"] = "Yes"
-- Failed to store the API key in the operating system. The message was: {0}. Please try again.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1122745046"] = "Failed to store the API key in the operating system. The message was: {0}. Please try again."
-- API Key
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1324664716"] = "API Key"
-- Create account
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1356621346"] = "Create account"
-- Please enter an embedding model name.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1661085403"] = "Please enter an embedding model name."
-- Hostname
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1727440780"] = "Hostname"
-- Load
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1756340745"] = "Load"
-- Update
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1847791252"] = "Update"
-- Failed to load the API key from the operating system. The message was: {0}. You might ignore this message and provide the API key again.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T1870831108"] = "Failed to load the API key from the operating system. The message was: {0}. You might ignore this message and provide the API key again."
-- Model
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2189814010"] = "Model"
-- (Optional) API Key
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2331453405"] = "(Optional) API Key"
-- Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2615586687"] = "Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually."
-- Add
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2646845972"] = "Add"
-- No models loaded or available.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2810182573"] = "No models loaded or available."
-- Instance Name
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2842060373"] = "Instance Name"
-- Model selection
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T416738168"] = "Model selection"
-- Host
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T808120719"] = "Host"
-- Provider
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T900237532"] = "Provider"
-- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T900713019"] = "Cancel"
-- Tell the AI what you want it to do for you. What are your goals or are you trying to achieve? Like having the AI address you informally. -- Tell the AI what you want it to do for you. What are your goals or are you trying to achieve? Like having the AI address you informally.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROFILEDIALOG::T1458195391"] = "Tell the AI what you want it to do for you. What are your goals or are you trying to achieve? Like having the AI address you informally." UI_TEXT_CONTENT["AISTUDIO::DIALOGS::PROFILEDIALOG::T1458195391"] = "Tell the AI what you want it to do for you. What are your goals or are you trying to achieve? Like having the AI address you informally."
@ -2962,6 +3067,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T2897045472"] = "No
-- Unknown -- Unknown
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T3424652889"] = "Unknown" UI_TEXT_CONTENT["AISTUDIO::PROVIDER::LLMPROVIDERSEXTENSIONS::T3424652889"] = "Unknown"
-- no model selected
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::MODEL::T2234274832"] = "no model selected"
-- Navigation never expands, but there are tooltips -- Navigation never expands, but there are tooltips
UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T1095779033"] = "Navigation never expands, but there are tooltips" UI_TEXT_CONTENT["AISTUDIO::SETTINGS::CONFIGURATIONSELECTDATAFACTORY::T1095779033"] = "Navigation never expands, but there are tooltips"

View File

@ -4,24 +4,17 @@
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager)) @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
{ {
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.IntegrationInstructions" HeaderText="Configure Embeddings"> <ExpansionPanel HeaderIcon="@Icons.Material.Filled.IntegrationInstructions" HeaderText="@T("Configure Embeddings")">
<PreviewPrototype/> <PreviewPrototype/>
<MudText Typo="Typo.h4" Class="mb-3"> <MudText Typo="Typo.h4" Class="mb-3">
Configured Embeddings @T("Configured Embeddings")
</MudText> </MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-3"> <MudJustifiedText Typo="Typo.body1" Class="mb-3">
Embeddings are a way to represent words, sentences, entire documents, or even images and videos as digital @T("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'.")
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'.
</MudJustifiedText> </MudJustifiedText>
<MudJustifiedText Typo="Typo.body1" Class="mb-3"> <MudJustifiedText Typo="Typo.body1" Class="mb-3">
This helps AI Studio understand and compare things in a way that's similar to how humans do. When you're working on @T("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.")
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.
</MudJustifiedText> </MudJustifiedText>
<MudTable Items="@this.SettingsManager.ConfigurationData.EmbeddingProviders" Hover="@true" Class="border-dashed border rounded-lg"> <MudTable Items="@this.SettingsManager.ConfigurationData.EmbeddingProviders" Hover="@true" Class="border-dashed border rounded-lg">
<ColGroup> <ColGroup>
@ -33,10 +26,10 @@
</ColGroup> </ColGroup>
<HeaderContent> <HeaderContent>
<MudTh>#</MudTh> <MudTh>#</MudTh>
<MudTh>Name</MudTh> <MudTh>@T("Name")</MudTh>
<MudTh>Provider</MudTh> <MudTh>@T("Provider")</MudTh>
<MudTh>Model</MudTh> <MudTh>@T("Model")</MudTh>
<MudTh>Actions</MudTh> <MudTh>@T("Actions")</MudTh>
</HeaderContent> </HeaderContent>
<RowTemplate> <RowTemplate>
<MudTd>@context.Num</MudTd> <MudTd>@context.Num</MudTd>
@ -47,13 +40,13 @@
<MudTd> <MudTd>
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap"> <MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())"> <MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())">
Open Dashboard @T("Open Dashboard")
</MudButton> </MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbeddingProvider(context)"> <MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbeddingProvider(context)">
Edit @T("Edit")
</MudButton> </MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbeddingProvider(context)"> <MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbeddingProvider(context)">
Delete @T("Delete")
</MudButton> </MudButton>
</MudStack> </MudStack>
</MudTd> </MudTd>
@ -62,11 +55,13 @@
@if (this.SettingsManager.ConfigurationData.EmbeddingProviders.Count == 0) @if (this.SettingsManager.ConfigurationData.EmbeddingProviders.Count == 0)
{ {
<MudText Typo="Typo.h6" Class="mt-3">No embeddings configured yet.</MudText> <MudText Typo="Typo.h6" Class="mt-3">
@T("No embeddings configured yet.")
</MudText>
} }
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbeddingProvider"> <MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbeddingProvider">
Add Embedding @T("Add Embedding")
</MudButton> </MudButton>
</ExpansionPanel> </ExpansionPanel>
} }

View File

@ -39,7 +39,7 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
{ x => x.IsEditing, false }, { x => x.IsEditing, false },
}; };
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>("Add Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Add Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result; var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled) if (dialogResult is null || dialogResult.Canceled)
return; return;
@ -69,7 +69,7 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
{ x => x.DataHost, embeddingProvider.Host }, { x => x.DataHost, embeddingProvider.Host },
}; };
var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>("Edit Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<EmbeddingProviderDialog>(T("Edit Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result; var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled) if (dialogResult is null || dialogResult.Canceled)
return; return;
@ -92,10 +92,10 @@ public partial class SettingsPanelEmbeddings : SettingsPanelBase
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters
{ {
{ "Message", $"Are you sure you want to delete the embedding provider '{provider.Name}'?" }, { "Message", string.Format(T("Are you sure you want to delete the embedding provider '{0}'?"), provider.Name) },
}; };
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Embedding Provider", dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>(T("Delete Embedding Provider"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogResult = await dialogReference.Result; var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled) if (dialogResult is null || dialogResult.Canceled)
return; return;

View File

@ -1,12 +1,13 @@
@using AIStudio.Provider @using AIStudio.Provider
@using AIStudio.Provider.SelfHosted @using AIStudio.Provider.SelfHosted
@inherits MSGComponentBase
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues"> <MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
<MudStack Row="@true" AlignItems="AlignItems.Center"> <MudStack Row="@true" AlignItems="AlignItems.Center">
@* ReSharper disable once CSharpWarnings::CS8974 *@ @* ReSharper disable once CSharpWarnings::CS8974 *@
<MudSelect @bind-Value="@this.DataLLMProvider" Label="Provider" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingProvider"> <MudSelect @bind-Value="@this.DataLLMProvider" Label="@T("Provider")" Class="mb-3" OpenIcon="@Icons.Material.Filled.AccountBalance" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingProvider">
@foreach (LLMProviders provider in Enum.GetValues(typeof(LLMProviders))) @foreach (LLMProviders provider in Enum.GetValues(typeof(LLMProviders)))
{ {
if (provider.ProvideEmbeddings() || provider is LLMProviders.NONE) if (provider.ProvideEmbeddings() || provider is LLMProviders.NONE)
@ -17,7 +18,9 @@
} }
} }
</MudSelect> </MudSelect>
<MudButton Disabled="@(!this.DataLLMProvider.ShowRegisterButton())" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@this.DataLLMProvider.GetCreationURL()" Target="_blank">Create account</MudButton> <MudButton Disabled="@(!this.DataLLMProvider.ShowRegisterButton())" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.OpenInBrowser" Href="@this.DataLLMProvider.GetCreationURL()" Target="_blank">
@T("Create account")
</MudButton>
</MudStack> </MudStack>
@if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost)) @if (this.DataLLMProvider.IsAPIKeyNeeded(this.DataHost))
@ -41,7 +44,7 @@
<MudTextField <MudTextField
T="string" T="string"
@bind-Text="@this.DataHostname" @bind-Text="@this.DataHostname"
Label="Hostname" Label="@T("Hostname")"
Class="mb-3" Class="mb-3"
Adornment="Adornment.Start" Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Dns" AdornmentIcon="@Icons.Material.Filled.Dns"
@ -52,7 +55,7 @@
@if (this.DataLLMProvider.IsHostNeeded()) @if (this.DataLLMProvider.IsHostNeeded())
{ {
<MudSelect @bind-Value="@this.DataHost" Label="Host" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingHost"> <MudSelect @bind-Value="@this.DataHost" Label="@T("Host")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingHost">
@foreach (Host host in Enum.GetValues(typeof(Host))) @foreach (Host host in Enum.GetValues(typeof(Host)))
{ {
if (host.AreEmbeddingsSupported()) if (host.AreEmbeddingsSupported())
@ -65,39 +68,57 @@
</MudSelect> </MudSelect>
} }
<MudStack Row="@true" AlignItems="AlignItems.Center"> <MudField FullWidth="true" Label="@T("Model selection")" Variant="Variant.Outlined" Class="mb-3">
@if (this.DataLLMProvider.IsEmbeddingModelProvidedManually(this.DataHost)) <MudStack Row="@true" AlignItems="AlignItems.Center" StretchItems="StretchItems.End">
{ @if (this.DataLLMProvider.IsEmbeddingModelProvidedManually(this.DataHost))
<MudTextField {
T="string" <MudTextField
@bind-Text="@this.dataManuallyModel" T="string"
Label="Model" @bind-Text="@this.dataManuallyModel"
Class="mb-3" Label="@T("Model")"
Adornment="Adornment.Start" Class="mb-3"
AdornmentIcon="@Icons.Material.Filled.Dns" Adornment="Adornment.Start"
AdornmentColor="Color.Info" AdornmentIcon="@Icons.Material.Filled.Dns"
Validation="@this.ValidateManuallyModel" AdornmentColor="Color.Info"
UserAttributes="@SPELLCHECK_ATTRIBUTES" Validation="@this.ValidateManuallyModel"
HelperText="Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually." UserAttributes="@SPELLCHECK_ATTRIBUTES"
/> HelperText="@T("Currently, we cannot query the embedding models of self-hosted systems. Therefore, enter the model name manually.")"
} />
else }
{ else
<MudButton Disabled="@(!this.DataLLMProvider.CanLoadModels(this.DataHost, this.dataAPIKey))" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.Refresh" OnClick="this.ReloadModels">Load</MudButton> {
<MudSelect Disabled="@this.IsNoneProvider" @bind-Value="@this.DataModel" Label="Model" Class="mb-3" OpenIcon="@Icons.Material.Filled.FaceRetouchingNatural" AdornmentColor="Color.Info" Adornment="Adornment.Start" Validation="@this.providerValidation.ValidatingModel"> <MudButton Disabled="@(!this.DataLLMProvider.CanLoadModels(this.DataHost, this.dataAPIKey))" Variant="Variant.Filled" Size="Size.Small" StartIcon="@Icons.Material.Filled.Refresh" OnClick="this.ReloadModels">
@foreach (var model in this.availableModels) @T("Load")
</MudButton>
@if(this.availableModels.Count is 0)
{ {
<MudSelectItem Value="@model">@model</MudSelectItem> <MudText Typo="Typo.body1">
@T("No models loaded or available.")
</MudText>
} }
</MudSelect> else
} {
</MudStack> <MudSelect Disabled="@this.IsNoneProvider" @bind-Value="@this.DataModel" Label="@T("Model")"
OpenIcon="@Icons.Material.Filled.FaceRetouchingNatural"
AdornmentColor="Color.Info" Adornment="Adornment.Start"
Validation="@this.providerValidation.ValidatingModel">
@foreach (var model in this.availableModels)
{
<MudSelectItem Value="@model">
@model
</MudSelectItem>
}
</MudSelect>
}
}
</MudStack>
</MudField>
@* ReSharper disable once CSharpWarnings::CS8974 *@ @* ReSharper disable once CSharpWarnings::CS8974 *@
<MudTextField <MudTextField
T="string" T="string"
@bind-Text="@this.DataName" @bind-Text="@this.DataName"
Label="Instance Name" Label="@T("Instance Name")"
Class="mb-3" Class="mb-3"
MaxLength="40" MaxLength="40"
Counter="40" Counter="40"
@ -113,15 +134,17 @@
<Issues IssuesData="@this.dataIssues"/> <Issues IssuesData="@this.dataIssues"/>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">
@T("Cancel")
</MudButton>
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary"> <MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
@if(this.IsEditing) @if(this.IsEditing)
{ {
@:Update @T("Update")
} }
else else
{ {
@:Add @T("Add")
} }
</MudButton> </MudButton>
</DialogActions> </DialogActions>

View File

@ -1,3 +1,4 @@
using AIStudio.Components;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Tools.Services; using AIStudio.Tools.Services;
@ -9,7 +10,7 @@ using Host = AIStudio.Provider.SelfHosted.Host;
namespace AIStudio.Dialogs; namespace AIStudio.Dialogs;
public partial class EmbeddingProviderDialog : ComponentBase, ISecretId public partial class EmbeddingProviderDialog : MSGComponentBase, ISecretId
{ {
[CascadingParameter] [CascadingParameter]
private IMudDialogInstance MudDialog { get; set; } = null!; private IMudDialogInstance MudDialog { get; set; } = null!;
@ -68,9 +69,6 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
[Parameter] [Parameter]
public bool IsEditing { get; init; } public bool IsEditing { get; init; }
[Inject]
private SettingsManager SettingsManager { get; init; } = null!;
[Inject] [Inject]
private ILogger<ProviderDialog> Logger { get; init; } = null!; private ILogger<ProviderDialog> Logger { get; init; } = null!;
@ -175,7 +173,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
this.dataAPIKey = string.Empty; this.dataAPIKey = string.Empty;
if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED) if (this.DataLLMProvider is not LLMProviders.SELF_HOSTED)
{ {
this.dataAPIKeyStorageIssue = $"Failed to load the API key from the operating system. The message was: {requestedSecret.Issue}. You might ignore this message and provide the API key again."; this.dataAPIKeyStorageIssue = string.Format(T("Failed to load the API key from the operating system. The message was: {0}. You might ignore this message and provide the API key again."), requestedSecret.Issue);
await this.form.Validate(); await this.form.Validate();
} }
} }
@ -224,7 +222,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
var storeResponse = await this.RustService.SetAPIKey(this, this.dataAPIKey); var storeResponse = await this.RustService.SetAPIKey(this, this.dataAPIKey);
if (!storeResponse.Success) if (!storeResponse.Success)
{ {
this.dataAPIKeyStorageIssue = $"Failed to store the API key in the operating system. The message was: {storeResponse.Issue}. Please try again."; this.dataAPIKeyStorageIssue = string.Format(T("Failed to store the API key in the operating system. The message was: {0}. Please try again."), storeResponse.Issue);
await this.form.Validate(); await this.form.Validate();
return; return;
} }
@ -236,7 +234,7 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
private string? ValidateManuallyModel(string manuallyModel) private string? ValidateManuallyModel(string manuallyModel)
{ {
if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && string.IsNullOrWhiteSpace(manuallyModel)) if (this.DataLLMProvider is LLMProviders.SELF_HOSTED && string.IsNullOrWhiteSpace(manuallyModel))
return "Please enter an embedding model name."; return T("Please enter an embedding model name.");
return null; return null;
} }
@ -261,8 +259,8 @@ public partial class EmbeddingProviderDialog : ComponentBase, ISecretId
private string APIKeyText => this.DataLLMProvider switch private string APIKeyText => this.DataLLMProvider switch
{ {
LLMProviders.SELF_HOSTED => "(Optional) API Key", LLMProviders.SELF_HOSTED => T("(Optional) API Key"),
_ => "API Key", _ => T("API Key"),
}; };
private bool IsNoneProvider => this.DataLLMProvider is LLMProviders.NONE; private bool IsNoneProvider => this.DataLLMProvider is LLMProviders.NONE;

View File

@ -1,3 +1,5 @@
using AIStudio.Tools.PluginSystem;
namespace AIStudio.Provider; namespace AIStudio.Provider;
/// <summary> /// <summary>
@ -7,6 +9,8 @@ namespace AIStudio.Provider;
/// <param name="DisplayName">The model's display name.</param> /// <param name="DisplayName">The model's display name.</param>
public readonly record struct Model(string Id, string? DisplayName) public readonly record struct Model(string Id, string? DisplayName)
{ {
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(Model).Namespace, nameof(Model));
#region Overrides of ValueType #region Overrides of ValueType
public override string ToString() public override string ToString()
@ -17,7 +21,7 @@ public readonly record struct Model(string Id, string? DisplayName)
if(!string.IsNullOrWhiteSpace(this.Id)) if(!string.IsNullOrWhiteSpace(this.Id))
return this.Id; return this.Id;
return "no model selected"; return TB("no model selected");
} }
#endregion #endregion

View File

@ -1,5 +1,6 @@
# v0.9.43, build 218 (2025-05-xx xx:xx UTC) # v0.9.43, build 218 (2025-05-xx xx:xx UTC)
- Added the ability to select the new Google Gemini embeddings in the embedding configuration. - Added the ability to select the new Google Gemini embeddings in the embedding configuration.
- Added localization for embedding configuration.
- Improved the automatic German translation; thanks Peer (`peerschuett`) for contributing. - Improved the automatic German translation; thanks Peer (`peerschuett`) for contributing.
- Improved Google Gemini LLM model selection by filtering out the new embedding models. - Improved Google Gemini LLM model selection by filtering out the new embedding models.
- Improved the dialog for configuring embeddings: the API key is applied immediately, and provider formatting was enhanced. - Improved the dialog for configuring embeddings: the API key is applied immediately, and provider formatting was enhanced.