mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-29 01:39:46 +00:00
Implemented profiles
This commit is contained in:
parent
ffaffb50db
commit
de4a944c85
93
app/MindWork AI Studio/Dialogs/ProfileDialog.razor
Normal file
93
app/MindWork AI Studio/Dialogs/ProfileDialog.razor
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<MudDialog>
|
||||||
|
<DialogContent>
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
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.
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
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.
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
The name of the profile is mandatory. Each profile must have a unique name. Whether you provide
|
||||||
|
information about yourself or only fill out the actions is up to you. Only one of these pieces
|
||||||
|
is required.
|
||||||
|
</MudJustifiedText>
|
||||||
|
<MudForm @ref="@this.form" @bind-IsValid="@this.dataIsValid" @bind-Errors="@this.dataIssues">
|
||||||
|
@* ReSharper disable once CSharpWarnings::CS8974 *@
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataName"
|
||||||
|
Label="Profile Name"
|
||||||
|
Class="mb-3"
|
||||||
|
Immediate="@true"
|
||||||
|
MaxLength="40"
|
||||||
|
Counter="40"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.Badge"
|
||||||
|
AdornmentColor="Color.Info"
|
||||||
|
Validation="@this.ValidateName"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataNeedToKnow"
|
||||||
|
Validation="@this.ValidateNeedToKnow"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.ListAlt"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
Immediate="@true"
|
||||||
|
Label="What should the AI know about you?"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Lines="6"
|
||||||
|
AutoGrow="@true"
|
||||||
|
MaxLines="12"
|
||||||
|
MaxLength="444"
|
||||||
|
Counter="444"
|
||||||
|
Class="mb-3"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
HelperText="Tell the AI something about yourself. What is your profession? How experienced are you in this profession? Which technologies do you like?"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MudTextField
|
||||||
|
T="string"
|
||||||
|
@bind-Text="@this.DataActions"
|
||||||
|
Validation="@this.ValidateActions"
|
||||||
|
AdornmentIcon="@Icons.Material.Filled.ListAlt"
|
||||||
|
Adornment="Adornment.Start"
|
||||||
|
Immediate="@true"
|
||||||
|
Label="What should the AI do for you?"
|
||||||
|
Variant="Variant.Outlined"
|
||||||
|
Lines="6"
|
||||||
|
AutoGrow="@true"
|
||||||
|
MaxLines="12"
|
||||||
|
MaxLength="256"
|
||||||
|
Counter="256"
|
||||||
|
Class="mb-3"
|
||||||
|
UserAttributes="@SPELLCHECK_ATTRIBUTES"
|
||||||
|
HelperText="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."
|
||||||
|
/>
|
||||||
|
|
||||||
|
</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>
|
168
app/MindWork AI Studio/Dialogs/ProfileDialog.razor.cs
Normal file
168
app/MindWork AI Studio/Dialogs/ProfileDialog.razor.cs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
using AIStudio.Settings;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Dialogs;
|
||||||
|
|
||||||
|
public partial class ProfileDialog : ComponentBase
|
||||||
|
{
|
||||||
|
[CascadingParameter]
|
||||||
|
private MudDialogInstance MudDialog { get; set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The profile's number in the list.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public uint DataNum { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The profile's ID.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataId { get; set; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The profile name chosen by the user.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What should the LLM know about you?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataNeedToKnow { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What actions should the LLM take?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string DataActions { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the dialog be in editing mode?
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool IsEditing { get; init; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private SettingsManager SettingsManager { get; init; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private ILogger<ProviderDialog> Logger { get; init; } = null!;
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of used profile names. We need this to check for uniqueness.
|
||||||
|
/// </summary>
|
||||||
|
private List<string> UsedNames { get; set; } = [];
|
||||||
|
|
||||||
|
private bool dataIsValid;
|
||||||
|
private string[] dataIssues = [];
|
||||||
|
private string dataEditingPreviousName = string.Empty;
|
||||||
|
|
||||||
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
|
private MudForm form = null!;
|
||||||
|
|
||||||
|
private Profile CreateProfileSettings() => new()
|
||||||
|
{
|
||||||
|
Num = this.DataNum,
|
||||||
|
Id = this.DataId,
|
||||||
|
|
||||||
|
Name = this.DataName,
|
||||||
|
NeedToKnow = this.DataNeedToKnow,
|
||||||
|
Actions = this.DataActions,
|
||||||
|
};
|
||||||
|
|
||||||
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
// Configure the spellchecking for the instance name input:
|
||||||
|
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
|
||||||
|
|
||||||
|
// Load the used instance names:
|
||||||
|
this.UsedNames = this.SettingsManager.ConfigurationData.Profiles.Select(x => x.Name.ToLowerInvariant()).ToList();
|
||||||
|
|
||||||
|
// When editing, we need to load the data:
|
||||||
|
if(this.IsEditing)
|
||||||
|
{
|
||||||
|
this.dataEditingPreviousName = this.DataName.ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 async Task Store()
|
||||||
|
{
|
||||||
|
await this.form.Validate();
|
||||||
|
|
||||||
|
// When the data is not valid, we don't store it:
|
||||||
|
if (!this.dataIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Use the data model to store the profile.
|
||||||
|
// We just return this data to the parent component:
|
||||||
|
var addedProfileSettings = this.CreateProfileSettings();
|
||||||
|
|
||||||
|
if(this.IsEditing)
|
||||||
|
this.Logger.LogInformation($"Edited profile '{addedProfileSettings.Name}'.");
|
||||||
|
else
|
||||||
|
this.Logger.LogInformation($"Created profile '{addedProfileSettings.Name}'.");
|
||||||
|
|
||||||
|
this.MudDialog.Close(DialogResult.Ok(addedProfileSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateNeedToKnow(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(this.DataNeedToKnow) && string.IsNullOrWhiteSpace(this.DataActions))
|
||||||
|
return "Please enter what the LLM should know about you and/or what actions it should take.";
|
||||||
|
|
||||||
|
if(text.Length > 444)
|
||||||
|
return "The text must not exceed 444 characters.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateActions(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(this.DataNeedToKnow) && string.IsNullOrWhiteSpace(this.DataActions))
|
||||||
|
return "Please enter what the LLM should know about you and/or what actions it should take.";
|
||||||
|
|
||||||
|
if(text.Length > 256)
|
||||||
|
return "The text must not exceed 256 characters.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? ValidateName(string name)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
return "Please enter a profile name.";
|
||||||
|
|
||||||
|
if (name.Length > 40)
|
||||||
|
return "The profile name must not exceed 40 characters.";
|
||||||
|
|
||||||
|
// The instance name must be unique:
|
||||||
|
var lowerName = name.ToLowerInvariant();
|
||||||
|
if (lowerName != this.dataEditingPreviousName && this.UsedNames.Contains(lowerName))
|
||||||
|
return "The profile name must be unique; the chosen name is already in use.";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cancel() => this.MudDialog.Cancel();
|
||||||
|
}
|
@ -74,6 +74,55 @@
|
|||||||
</MudButton>
|
</MudButton>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
|
|
||||||
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Person4" HeaderText="Configure Profiles">
|
||||||
|
<MudText Typo="Typo.h4" Class="mb-3">Your Profiles</MudText>
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
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.
|
||||||
|
</MudJustifiedText>
|
||||||
|
|
||||||
|
<MudJustifiedText Typo="Typo.body1" Class="mb-3">
|
||||||
|
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.
|
||||||
|
</MudJustifiedText>
|
||||||
|
<MudTable Items="@this.SettingsManager.ConfigurationData.Profiles" Class="border-dashed border rounded-lg">
|
||||||
|
<ColGroup>
|
||||||
|
<col style="width: 3em;"/>
|
||||||
|
<col/>
|
||||||
|
<col style="width: 40em;"/>
|
||||||
|
</ColGroup>
|
||||||
|
<HeaderContent>
|
||||||
|
<MudTh>#</MudTh>
|
||||||
|
<MudTh>Profile Name</MudTh>
|
||||||
|
<MudTh Style="text-align: left;">Actions</MudTh>
|
||||||
|
</HeaderContent>
|
||||||
|
<RowTemplate>
|
||||||
|
<MudTd>@context.Num</MudTd>
|
||||||
|
<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.EditProfile(context)">
|
||||||
|
Edit
|
||||||
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" Class="ma-2" OnClick="() => this.DeleteProfile(context)">
|
||||||
|
Delete
|
||||||
|
</MudButton>
|
||||||
|
</MudTd>
|
||||||
|
</RowTemplate>
|
||||||
|
</MudTable>
|
||||||
|
|
||||||
|
@if(this.SettingsManager.ConfigurationData.Profiles.Count == 0)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h6" Class="mt-3">No profiles configured yet.</MudText>
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddProfile">
|
||||||
|
Add Profile
|
||||||
|
</MudButton>
|
||||||
|
</ExpansionPanel>
|
||||||
|
|
||||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="App Options">
|
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Apps" HeaderText="App Options">
|
||||||
<ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/>
|
<ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/>
|
||||||
<ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." />
|
<ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." />
|
||||||
|
@ -162,6 +162,73 @@ public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Profile related
|
||||||
|
|
||||||
|
private async Task AddProfile()
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<ProfileDialog>
|
||||||
|
{
|
||||||
|
{ x => x.IsEditing, false },
|
||||||
|
};
|
||||||
|
|
||||||
|
var dialogReference = await this.DialogService.ShowAsync<ProfileDialog>("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<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EditProfile(Profile profile)
|
||||||
|
{
|
||||||
|
var dialogParameters = new DialogParameters<ProfileDialog>
|
||||||
|
{
|
||||||
|
{ 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<ProfileDialog>("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<bool>(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<ConfirmDialog>("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<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Implementation of IMessageBusReceiver
|
#region Implementation of IMessageBusReceiver
|
||||||
|
|
||||||
public Task ProcessMessage<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
|
public Task ProcessMessage<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
|
||||||
|
@ -16,11 +16,21 @@ public sealed class Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Provider> Providers { get; init; } = [];
|
public List<Provider> Providers { get; init; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of configured profiles.
|
||||||
|
/// </summary>
|
||||||
|
public List<Profile> Profiles { get; init; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The next provider number to use.
|
/// The next provider number to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint NextProviderNum { get; set; } = 1;
|
public uint NextProviderNum { get; set; } = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The next profile number to use.
|
||||||
|
/// </summary>
|
||||||
|
public uint NextProfileNum { get; set; } = 1;
|
||||||
|
|
||||||
public DataApp App { get; init; } = new();
|
public DataApp App { get; init; } = new();
|
||||||
|
|
||||||
public DataChat Chat { get; init; } = new();
|
public DataChat Chat { get; init; } = new();
|
||||||
|
14
app/MindWork AI Studio/Settings/Profile.cs
Normal file
14
app/MindWork AI Studio/Settings/Profile.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace AIStudio.Settings;
|
||||||
|
|
||||||
|
public readonly record struct Profile(uint Num, string Id, string Name, string NeedToKnow, string Actions)
|
||||||
|
{
|
||||||
|
#region Overrides of ValueType
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a string that represents the profile in a human-readable format.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A string that represents the profile in a human-readable format.</returns>
|
||||||
|
public override string ToString() => this.Name;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
# v0.9.7, build 182 (2024-09-09 xx:xx UTC)
|
# v0.9.7, build 182 (2024-09-09 xx:xx UTC)
|
||||||
|
- Added the possibility to define multiple profiles in the settings. Use profiles to share some information about you with the AI.
|
||||||
- Added an introductory description to the provider settings.
|
- Added an introductory description to the provider settings.
|
||||||
- Added an indicator for the current and maximal length of the provider instance name.
|
- Added an indicator for the current and maximal length of the provider instance name.
|
||||||
- Fixed the bug that the model name for Fireworks was not loaded when editing the provider settings.
|
- Fixed the bug that the model name for Fireworks was not loaded when editing the provider settings.
|
||||||
|
Loading…
Reference in New Issue
Block a user