mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 21:59:48 +00:00
Implemented the retrieval process configuration
This commit is contained in:
parent
5f542295fc
commit
67ab9c6d97
@ -201,6 +201,44 @@
|
|||||||
Data retrieval settings
|
Data retrieval settings
|
||||||
</MudText>
|
</MudText>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-2">
|
||||||
|
For your ERI server, you need to retrieve data that matches a chat or prompt in some way. We call this the retrieval process.
|
||||||
|
You must describe at least one such process. You may offer several retrieval processes from which users can choose. This allows
|
||||||
|
you to test with beta users which process works better. Or you might generally want to give users the choice so they can select
|
||||||
|
the process that best suits their circumstances.
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudTable Items="@this.retrievalProcesses" Hover="@true" Class="border-dashed border rounded-lg">
|
||||||
|
<ColGroup>
|
||||||
|
<col/>
|
||||||
|
<col style="width: 34em;"/>
|
||||||
|
</ColGroup>
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>Name</MudTh>
|
||||||
|
<MudTh Style="text-align: left;">Actions</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd>@context.Name</MudTd>
|
||||||
|
<MudTd Style="text-align: left;">
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" Class="ma-2" OnClick="() => this.EditRetrievalProcess(context)">
|
||||||
|
Edit
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" Class="ma-2" OnClick="() => this.DeleteRetrievalProcess(context)">
|
||||||
|
Delete
|
||||||
|
</MudButton>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
|
||||||
|
@if(this.retrievalProcesses.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h6" Class="mt-3">No retrieval process configured yet.</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddRetrievalProcess">
|
||||||
|
Add Retrieval Process
|
||||||
|
</MudButton>
|
||||||
|
|
||||||
<MudText Typo="Typo.body1" Class="mb-1">
|
<MudText Typo="Typo.body1" Class="mb-1">
|
||||||
You can integrate additional libraries. Perhaps you want to evaluate the prompts in advance using a machine learning method or analyze them with a text
|
You can integrate additional libraries. Perhaps you want to evaluate the prompts in advance using a machine learning method or analyze them with a text
|
||||||
mining approach? Or maybe you want to preprocess images in the prompts? For such advanced scenarios, you can specify which libraries you want to use here.
|
mining approach? Or maybe you want to preprocess images in the prompts? For such advanced scenarios, you can specify which libraries you want to use here.
|
||||||
|
@ -64,6 +64,7 @@ public partial class AssistantERI : AssistantBaseCore
|
|||||||
this.selectedOperatingSystem = OperatingSystem.NONE;
|
this.selectedOperatingSystem = OperatingSystem.NONE;
|
||||||
this.allowedLLMProviders = AllowedLLMProviders.NONE;
|
this.allowedLLMProviders = AllowedLLMProviders.NONE;
|
||||||
this.embeddings = new();
|
this.embeddings = new();
|
||||||
|
this.retrievalProcesses = new();
|
||||||
this.additionalLibraries = string.Empty;
|
this.additionalLibraries = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,6 +93,7 @@ public partial class AssistantERI : AssistantBaseCore
|
|||||||
this.selectedOperatingSystem = this.SettingsManager.ConfigurationData.ERI.PreselectedOperatingSystem;
|
this.selectedOperatingSystem = this.SettingsManager.ConfigurationData.ERI.PreselectedOperatingSystem;
|
||||||
this.allowedLLMProviders = this.SettingsManager.ConfigurationData.ERI.PreselectedAllowedLLMProviders;
|
this.allowedLLMProviders = this.SettingsManager.ConfigurationData.ERI.PreselectedAllowedLLMProviders;
|
||||||
this.embeddings = this.SettingsManager.ConfigurationData.ERI.PreselectedEmbeddingInfos;
|
this.embeddings = this.SettingsManager.ConfigurationData.ERI.PreselectedEmbeddingInfos;
|
||||||
|
this.retrievalProcesses = this.SettingsManager.ConfigurationData.ERI.PreselectedRetrievalInfos;
|
||||||
this.additionalLibraries = this.SettingsManager.ConfigurationData.ERI.PreselectedAdditionalLibraries;
|
this.additionalLibraries = this.SettingsManager.ConfigurationData.ERI.PreselectedAdditionalLibraries;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -125,6 +127,7 @@ public partial class AssistantERI : AssistantBaseCore
|
|||||||
this.SettingsManager.ConfigurationData.ERI.PreselectedOperatingSystem = this.selectedOperatingSystem;
|
this.SettingsManager.ConfigurationData.ERI.PreselectedOperatingSystem = this.selectedOperatingSystem;
|
||||||
this.SettingsManager.ConfigurationData.ERI.PreselectedAllowedLLMProviders = this.allowedLLMProviders;
|
this.SettingsManager.ConfigurationData.ERI.PreselectedAllowedLLMProviders = this.allowedLLMProviders;
|
||||||
this.SettingsManager.ConfigurationData.ERI.PreselectedEmbeddingInfos = this.embeddings;
|
this.SettingsManager.ConfigurationData.ERI.PreselectedEmbeddingInfos = this.embeddings;
|
||||||
|
this.SettingsManager.ConfigurationData.ERI.PreselectedRetrievalInfos = this.retrievalProcesses;
|
||||||
this.SettingsManager.ConfigurationData.ERI.PreselectedAdditionalLibraries = this.additionalLibraries;
|
this.SettingsManager.ConfigurationData.ERI.PreselectedAdditionalLibraries = this.additionalLibraries;
|
||||||
await this.SettingsManager.StoreSettings();
|
await this.SettingsManager.StoreSettings();
|
||||||
}
|
}
|
||||||
@ -146,6 +149,7 @@ public partial class AssistantERI : AssistantBaseCore
|
|||||||
private OperatingSystem selectedOperatingSystem = OperatingSystem.NONE;
|
private OperatingSystem selectedOperatingSystem = OperatingSystem.NONE;
|
||||||
private AllowedLLMProviders allowedLLMProviders = AllowedLLMProviders.NONE;
|
private AllowedLLMProviders allowedLLMProviders = AllowedLLMProviders.NONE;
|
||||||
private List<EmbeddingInfo> embeddings = new();
|
private List<EmbeddingInfo> embeddings = new();
|
||||||
|
private List<RetrievalInfo> retrievalProcesses = new();
|
||||||
private string additionalLibraries = string.Empty;
|
private string additionalLibraries = string.Empty;
|
||||||
|
|
||||||
private string? ValidateServerName(string name)
|
private string? ValidateServerName(string name)
|
||||||
@ -460,6 +464,65 @@ public partial class AssistantERI : AssistantBaseCore
|
|||||||
this.embeddings.Remove(embeddingInfo);
|
this.embeddings.Remove(embeddingInfo);
|
||||||
await this.AutoSave();
|
await this.AutoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task AddRetrievalProcess()
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<RetrievalProcessDialog>
|
||||||
|
{
|
||||||
|
{ x => x.IsEditing, false },
|
||||||
|
{ x => x.AvailableEmbeddings, this.embeddings },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<RetrievalProcessDialog>("Add Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var addedRetrievalProcess = (RetrievalInfo)dialogResult.Data!;
|
||||||
|
this.retrievalProcesses.Add(addedRetrievalProcess);
|
||||||
|
await this.AutoSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EditRetrievalProcess(RetrievalInfo retrievalInfo)
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<RetrievalProcessDialog>
|
||||||
|
{
|
||||||
|
{ x => x.DataName, retrievalInfo.Name },
|
||||||
|
{ x => x.DataDescription, retrievalInfo.Description },
|
||||||
|
{ x => x.DataLink, retrievalInfo.Link },
|
||||||
|
{ x => x.DataParametersDescription, retrievalInfo.ParametersDescription },
|
||||||
|
{ x => x.DataEmbeddings, retrievalInfo.Embeddings?.ToHashSet() },
|
||||||
|
|
||||||
|
{ x => x.IsEditing, true },
|
||||||
|
{ x => x.AvailableEmbeddings, this.embeddings },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<EmbeddingMethodDialog>("Edit Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var editedRetrievalProcess = (RetrievalInfo)dialogResult.Data!;
|
||||||
|
|
||||||
|
this.retrievalProcesses[this.retrievalProcesses.IndexOf(retrievalInfo)] = editedRetrievalProcess;
|
||||||
|
await this.AutoSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteRetrievalProcess(RetrievalInfo retrievalInfo)
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Message", $"Are you sure you want to delete the retrieval process '{retrievalInfo.Name}'?" },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Retrieval Process", dialogParameters, DialogOptions.FULLSCREEN);
|
||||||
|
var dialogResult = await dialogReference.Result;
|
||||||
|
if (dialogResult is null || dialogResult.Canceled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.retrievalProcesses.Remove(retrievalInfo);
|
||||||
|
await this.AutoSave();
|
||||||
|
}
|
||||||
|
|
||||||
private async Task GenerateServer()
|
private async Task GenerateServer()
|
||||||
{
|
{
|
||||||
|
18
app/MindWork AI Studio/Assistants/ERI/RetrievalInfo.cs
Normal file
18
app/MindWork AI Studio/Assistants/ERI/RetrievalInfo.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
namespace AIStudio.Assistants.ERI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Information about a retrieval process, which this data source implements.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Name">The name of the retrieval process, e.g., "Keyword-Based Wikipedia Article Retrieval".</param>
|
||||||
|
/// <param name="Description">A short description of the retrieval process. What kind of retrieval process is it?</param>
|
||||||
|
/// <param name="Link">A link to the retrieval process's documentation, paper, Wikipedia article, or the source code. Might be null.</param>
|
||||||
|
/// <param name="ParametersDescription">A dictionary that describes the parameters of the retrieval process. The key is the parameter name,
|
||||||
|
/// and the value is a description of the parameter. Although each parameter will be sent as a string, the description should indicate the
|
||||||
|
/// expected type and range, e.g., 0.0 to 1.0 for a float parameter.</param>
|
||||||
|
/// <param name="Embeddings">A list of embeddings used in this retrieval process. It might be empty in case no embedding is used.</param>
|
||||||
|
public readonly record struct RetrievalInfo(
|
||||||
|
string Name,
|
||||||
|
string Description,
|
||||||
|
string? Link,
|
||||||
|
Dictionary<string, string>? ParametersDescription,
|
||||||
|
List<EmbeddingInfo>? Embeddings);
|
14
app/MindWork AI Studio/Assistants/ERI/RetrievalParameter.cs
Normal file
14
app/MindWork AI Studio/Assistants/ERI/RetrievalParameter.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace AIStudio.Assistants.ERI;
|
||||||
|
|
||||||
|
public sealed class RetrievalParameter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the parameter.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The description of the parameter.
|
||||||
|
/// </summary>
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
}
|
213
app/MindWork AI Studio/Dialogs/RetrievalProcessDialog.razor
Normal file
213
app/MindWork AI Studio/Dialogs/RetrievalProcessDialog.razor
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
@using AIStudio.Assistants.ERI
|
||||||
|
@using MudExtensions
|
||||||
|
<MudDialog>
|
||||||
|
<DialogContent>
|
||||||
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
|
General Information
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
|
Please provide some general information about your retrieval process first. This data may be
|
||||||
|
displayed to the users.
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataName"
|
||||||
|
Label="Retrieval Process Name"
|
||||||
|
HelperText="The name of your retrieval process."
|
||||||
|
Class="mb-3"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Label"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Validation="@this.ValidateName"
|
||||||
|
Counter="26"
|
||||||
|
MaxLength="26"
|
||||||
|
Immediate="@true"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
/>
|
||||||
|
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataDescription"
|
||||||
|
Label="Retrieval Process Description"
|
||||||
|
HelperText="A short description of the retrieval process."
|
||||||
|
Lines="3"
|
||||||
|
AutoGrow="@true"
|
||||||
|
MaxLines="6"
|
||||||
|
Immediate="@true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Class="mb-3"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Extension"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Validation="@this.ValidateDescription"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
/>
|
||||||
|
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataLink"
|
||||||
|
Label="Retrieval Process Link"
|
||||||
|
HelperText="A link to the retrieval process, e.g., the source code, the paper, it's Wikipedia page, etc. Make sense for common retrieval processes. Leave empty if not applicable."
|
||||||
|
Class="mb-6"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Link"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
|
Retrieval Process Parameters
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
|
You may want to parameterize your retrieval process. However, this is optional. You can specify any
|
||||||
|
parameters that can be set by the user or the system during the call. Nevertheless, you should use
|
||||||
|
sensible default values in your code so that users are not forced to set the parameters manually.
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudStack Row="@true" Spacing="6" AlignItems="AlignItems.Start" StretchItems="StretchItems.None">
|
||||||
|
@* The left side of the stack is another stack to show the list *@
|
||||||
|
<MudStack Row="@false" AlignItems="AlignItems.Start" StretchItems="StretchItems.None">
|
||||||
|
@if (this.retrievalParameters.Count > 0)
|
||||||
|
{
|
||||||
|
<MudList T="RetrievalParameter" Class="mb-1" @bind-SelectedValue="@this.selectedParameter">
|
||||||
|
@foreach (var parameter in this.retrievalParameters)
|
||||||
|
{
|
||||||
|
<MudListItem T="RetrievalParameter" Icon="@Icons.Material.Filled.Tune" Value="@parameter">
|
||||||
|
@parameter.Name
|
||||||
|
</MudListItem>
|
||||||
|
}
|
||||||
|
</MudList>
|
||||||
|
}
|
||||||
|
<MudButton OnClick="@this.AddRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Primary" Class="mt-1">
|
||||||
|
Add Parameter
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
@* The right side of the stack is another stack to display the parameter's data *@
|
||||||
|
<MudStack Row="@false" AlignItems="AlignItems.Stretch" StretchItems="StretchItems.End" Class="pa-3 mb-8 border-solid border rounded-lg">
|
||||||
|
@if (this.selectedParameter is null)
|
||||||
|
{
|
||||||
|
@if(this.retrievalParameters.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText>
|
||||||
|
Add a parameter first, then select it to edit.
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudText>
|
||||||
|
Select a parameter to show and edit it.
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.selectedParameter.Name"
|
||||||
|
Label="Parameter Name"
|
||||||
|
HelperText="The parameter name. It must be unique within the retrieval process."
|
||||||
|
Class="mb-3"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Label"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Counter="26"
|
||||||
|
MaxLength="26"
|
||||||
|
Validation="@this.ValidateParameterName"
|
||||||
|
Immediate="@true"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
|
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.selectedParameter.Description"
|
||||||
|
Label="Parameter Description"
|
||||||
|
HelperText="A short description of the parameter. What data type is it? What is it used for? What are the possible values?"
|
||||||
|
Lines="3"
|
||||||
|
AutoGrow="@true"
|
||||||
|
MaxLines="6"
|
||||||
|
Immediate="@true"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Class="mb-3"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Extension"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Validation="@this.ValidateParameterDescription"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"/>
|
||||||
|
|
||||||
|
<MudStack Row="@true">
|
||||||
|
<MudButton OnClick="@this.RemoveRetrievalProcessParameter" Variant="Variant.Filled" Color="Color.Secondary">
|
||||||
|
Delete this parameter
|
||||||
|
</MudButton>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
}
|
||||||
|
</MudStack>
|
||||||
|
</MudStack>
|
||||||
|
|
||||||
|
<MudText Typo="Typo.h5" Class="mb-3">
|
||||||
|
Embeddings
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
@if(this.AvailableEmbeddings.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
|
Currently, you have not defined any embedding methods. If your retrieval process does not require embedding, you can ignore this part.
|
||||||
|
Otherwise, you can define one or more embedding methods in the previous view to assign them to your retrieval process here.
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.body1" Class="mb-3">
|
||||||
|
Here you can select which embedding methods are used for this retrieval process. Embeddings are optional;
|
||||||
|
if your retrieval process works without embedding, you can ignore this part. You can only choose the embedding
|
||||||
|
methods you have previously defined.
|
||||||
|
</MudText>
|
||||||
|
|
||||||
|
<MudSelectExtended
|
||||||
|
T="EmbeddingInfo"
|
||||||
|
MultiSelection="@true"
|
||||||
|
MultiSelectionTextFunc="@this.GetMultiSelectionText"
|
||||||
|
SelectedValues="@this.DataEmbeddings"
|
||||||
|
SelectedValuesChanged="@this.EmbeddingsChanged"
|
||||||
|
Strict="@true"
|
||||||
|
Margin="Margin.Dense"
|
||||||
|
Label="Embeddings methods"
|
||||||
|
ShrinkLabel="@true"
|
||||||
|
Class="mb-3"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
HelperText="Optional. Select the embedding methods that are used for this retrieval process.">
|
||||||
|
@foreach (var embedding in this.AvailableEmbeddings)
|
||||||
|
{
|
||||||
|
<MudSelectItemExtended Value="@embedding">
|
||||||
|
@embedding.EmbeddingName
|
||||||
|
</MudSelectItemExtended>
|
||||||
|
}
|
||||||
|
</MudSelectExtended>
|
||||||
|
}
|
||||||
|
</MudForm>
|
||||||
|
<Issues IssuesData="@this.dataIssues"/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
|
||||||
|
<MudButton OnClick="@this.Store" Variant="Variant.Filled" Color="Color.Primary">
|
||||||
|
@if(this.IsEditing)
|
||||||
|
{
|
||||||
|
@:Update
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@:Add
|
||||||
|
}
|
||||||
|
</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
204
app/MindWork AI Studio/Dialogs/RetrievalProcessDialog.razor.cs
Normal file
204
app/MindWork AI Studio/Dialogs/RetrievalProcessDialog.razor.cs
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
using AIStudio.Assistants.ERI;
|
||||||
|
using AIStudio.Settings;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
|
public partial class RetrievalProcessDialog : ComponentBase
|
||||||
|
{
|
||||||
|
[CascadingParameter]
|
||||||
|
private MudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user chosen retrieval process name.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The retrieval process description.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataDescription { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A link to the retrieval process documentation, paper, Wikipedia article, or the source code.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataLink { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A dictionary that describes the parameters of the retrieval process. The key is the parameter name,
|
||||||
|
/// and the value is a description of the parameter. Although each parameter will be sent as a string,
|
||||||
|
/// the description should indicate the expected type and range, e.g., 0.0 to 1.0 for a float parameter.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public Dictionary<string, string> DataParametersDescription { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of embeddings used in this retrieval process. It might be empty in case no embedding is used.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public HashSet<EmbeddingInfo> DataEmbeddings { get; set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The available embeddings for the user to choose from.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public IReadOnlyList<EmbeddingInfo> AvailableEmbeddings { get; set; } = new List<EmbeddingInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the dialog be in editing mode?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private SettingsManager SettingsManager { get; init; } = null!;
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
|
private bool dataIsValid;
|
||||||
|
private string[] dataIssues = [];
|
||||||
|
private List<RetrievalParameter> retrievalParameters = new();
|
||||||
|
private RetrievalParameter? selectedParameter;
|
||||||
|
private uint nextParameterId = 1;
|
||||||
|
|
||||||
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
|
private MudForm form = null!;
|
||||||
|
|
||||||
|
private RetrievalInfo CreateRetrievalInfo() => new(this.DataName, this.DataDescription, this.DataLink, this.retrievalParameters.ToDictionary(parameter => parameter.Name, parameter => parameter.Description), this.DataEmbeddings.ToList());
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
// Configure the spellchecking for the instance name input:
|
||||||
|
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
||||||
|
|
||||||
|
// Convert the parameters:
|
||||||
|
this.retrievalParameters = this.DataParametersDescription.Select(pair => new RetrievalParameter { Name = pair.Key, Description = pair.Value }).ToList();
|
||||||
|
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
// Reset the validation when not editing and on the first render.
|
||||||
|
// We don't want to show validation errors when the user opens the dialog.
|
||||||
|
if(!this.IsEditing && firstRender)
|
||||||
|
this.form.ResetValidation();
|
||||||
|
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private string? ValidateName(string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
return "The retrieval process name must not be empty. Please name your retrieval process.";
|
||||||
|
|
||||||
|
if (name.Length > 26)
|
||||||
|
return "The retrieval process name must not be longer than 26 characters.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateDescription(string description)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(description))
|
||||||
|
return "The description must not be empty. Please describe the retrieval process.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddRetrievalProcessParameter()
|
||||||
|
{
|
||||||
|
this.retrievalParameters.Add(new() { Name = $"New Parameter {this.nextParameterId++}", Description = string.Empty });
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateParameterName(string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
return "The parameter name must not be empty. Please name the parameter.";
|
||||||
|
|
||||||
|
if(name.Length > 26)
|
||||||
|
return "The parameter name must not be longer than 26 characters.";
|
||||||
|
|
||||||
|
if (this.retrievalParameters.Count(parameter => parameter.Name == name) > 1)
|
||||||
|
return $"The parameter name '{name}' must be unique. Please choose a different name.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateParameterDescription(string description)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(description))
|
||||||
|
return $"The parameter description must not be empty. Please describe the parameter '{this.selectedParameter?.Name}'. What data type is it? What is it used for? What are the possible values?";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateParameter(RetrievalParameter parameter)
|
||||||
|
{
|
||||||
|
if(this.ValidateParameterName(parameter.Name) is { } nameIssue)
|
||||||
|
return nameIssue;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(parameter.Description))
|
||||||
|
return $"The parameter description must not be empty. Please describe the parameter '{parameter.Name}'. What data type is it? What is it used for? What are the possible values?";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveRetrievalProcessParameter()
|
||||||
|
{
|
||||||
|
if (this.selectedParameter is not null)
|
||||||
|
this.retrievalParameters.Remove(this.selectedParameter);
|
||||||
|
|
||||||
|
this.selectedParameter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetMultiSelectionText(List<EmbeddingInfo> selectedEmbeddings)
|
||||||
|
{
|
||||||
|
if(selectedEmbeddings.Count == 0)
|
||||||
|
return "No embedding methods selected.";
|
||||||
|
|
||||||
|
if(selectedEmbeddings.Count == 1)
|
||||||
|
return "You have selected 1 embedding method.";
|
||||||
|
|
||||||
|
return $"You have selected {selectedEmbeddings.Count} embedding methods.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EmbeddingsChanged(IEnumerable<EmbeddingInfo>? updatedEmbeddings)
|
||||||
|
{
|
||||||
|
if(updatedEmbeddings is null)
|
||||||
|
this.DataEmbeddings = new();
|
||||||
|
else
|
||||||
|
this.DataEmbeddings = updatedEmbeddings.ToHashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Store()
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
foreach (var parameter in this.retrievalParameters)
|
||||||
|
{
|
||||||
|
if (this.ValidateParameter(parameter) is { } issue)
|
||||||
|
{
|
||||||
|
this.dataIsValid = false;
|
||||||
|
Array.Resize(ref this.dataIssues, this.dataIssues.Length + 1);
|
||||||
|
this.dataIssues[^1] = issue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the data is not valid, we don't store it:
|
||||||
|
if (!this.dataIsValid || this.dataIssues.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var retrievalInfo = this.CreateRetrievalInfo();
|
||||||
|
this.MudDialog.Close(DialogResult.Ok(retrievalInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel() => this.MudDialog.Cancel();
|
||||||
|
}
|
@ -98,7 +98,10 @@ public sealed class DataERI
|
|||||||
public List<EmbeddingInfo> PreselectedEmbeddingInfos { get; set; } = new();
|
public List<EmbeddingInfo> PreselectedEmbeddingInfos { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Do you want to predefine any retrieval information?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
public List<RetrievalInfo> PreselectedRetrievalInfos { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Do you want to preselect any additional libraries?
|
/// Do you want to preselect any additional libraries?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user