Added profiles to chat & assistants

This commit is contained in:
Thorsten Sommer 2024-09-08 19:17:18 +02:00
parent de4a944c85
commit f5b3f3b484
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
14 changed files with 145 additions and 3 deletions

View File

@ -93,6 +93,11 @@
<MudButton Variant="Variant.Filled" Color="Color.Warning" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()"> <MudButton Variant="Variant.Filled" Color="Color.Warning" StartIcon="@Icons.Material.Filled.Refresh" OnClick="() => this.InnerResetForm()">
Reset Reset
</MudButton> </MudButton>
@if (this.AllowProfiles)
{
<ProfileSelection MarginLeft="" @bind-CurrentProfile="@this.currentProfile"/>
}
</MudStack> </MudStack>
</FooterContent> </FooterContent>
</InnerScrolling> </InnerScrolling>

View File

@ -55,6 +55,8 @@ public abstract partial class AssistantBase : ComponentBase
private protected virtual RenderFragment? Body => null; private protected virtual RenderFragment? Body => null;
protected virtual bool ShowResult => true; protected virtual bool ShowResult => true;
protected virtual bool AllowProfiles => true;
protected virtual bool ShowDedicatedProgress => false; protected virtual bool ShowDedicatedProgress => false;
@ -72,6 +74,7 @@ public abstract partial class AssistantBase : ComponentBase
private ContentBlock? resultingContentBlock; private ContentBlock? resultingContentBlock;
private string[] inputIssues = []; private string[] inputIssues = [];
private bool isProcessing; private bool isProcessing;
private Profile currentProfile = Profile.NO_PROFILE;
#region Overrides of ComponentBase #region Overrides of ComponentBase
@ -118,7 +121,12 @@ public abstract partial class AssistantBase : ComponentBase
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = this.RNG.Next(), Seed = this.RNG.Next(),
SystemPrompt = this.SystemPrompt, SystemPrompt = !this.AllowProfiles ? this.SystemPrompt :
$"""
{this.SystemPrompt}
{this.currentProfile.ToSystemPrompt()}
""",
Blocks = [], Blocks = [],
}; };
} }

View File

@ -22,6 +22,8 @@ public partial class AssistantGrammarSpelling : AssistantBaseCore
Your response includes only the corrected text. Do not explain your changes. If no changes are needed, Your response includes only the corrected text. Do not explain your changes. If no changes are needed,
you return the text unchanged. you return the text unchanged.
"""; """;
protected override bool AllowProfiles => false;
protected override bool ShowResult => false; protected override bool ShowResult => false;

View File

@ -24,6 +24,8 @@ public partial class AssistantIconFinder : AssistantBaseCore
related to the keyword "buildings" might be the best match. Provide your keywords in a Markdown list without related to the keyword "buildings" might be the best match. Provide your keywords in a Markdown list without
quotation marks. quotation marks.
"""; """;
protected override bool AllowProfiles => false;
protected override IReadOnlyList<IButtonData> FooterButtons => []; protected override IReadOnlyList<IButtonData> FooterButtons => [];

View File

@ -24,6 +24,8 @@ public partial class AssistantRewriteImprove : AssistantBaseCore
You follow the rules according to {this.SystemPromptLanguage()} in all your changes. You follow the rules according to {this.SystemPromptLanguage()} in all your changes.
"""; """;
protected override bool AllowProfiles => false;
protected override bool ShowResult => false; protected override bool ShowResult => false;
protected override bool ShowDedicatedProgress => true; protected override bool ShowDedicatedProgress => true;

View File

@ -47,6 +47,8 @@ public partial class AssistantSynonyms : AssistantBaseCore
the {this.SystemPromptLanguage()} language. the {this.SystemPromptLanguage()} language.
"""; """;
protected override bool AllowProfiles => false;
protected override IReadOnlyList<IButtonData> FooterButtons => []; protected override IReadOnlyList<IButtonData> FooterButtons => [];
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with

View File

@ -25,6 +25,8 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
a summary with the requested complexity. In any case, do not add any information. a summary with the requested complexity. In any case, do not add any information.
"""; """;
protected override bool AllowProfiles => false;
protected override IReadOnlyList<IButtonData> FooterButtons => []; protected override IReadOnlyList<IButtonData> FooterButtons => [];
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with

View File

@ -21,6 +21,8 @@ public partial class AssistantTranslation : AssistantBaseCore
language requires, e.g., shorter sentences, you should split the text into shorter sentences. language requires, e.g., shorter sentences, you should split the text into shorter sentences.
"""; """;
protected override bool AllowProfiles => false;
protected override IReadOnlyList<IButtonData> FooterButtons => []; protected override IReadOnlyList<IButtonData> FooterButtons => [];
protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with

View File

@ -0,0 +1,8 @@
<MudMenu StartIcon="@Icons.Material.Filled.Person4" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@this.CurrentProfile.Name" Variant="Variant.Filled" Color="Color.Default" Class="@this.MarginClass">
@foreach (var profile in this.Profiles())
{
<MudMenuItem OnClick="() => this.SelectionChanged(profile)">
@profile.Name
</MudMenuItem>
}
</MudMenu>

View File

@ -0,0 +1,35 @@
using AIStudio.Settings;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class ProfileSelection : ComponentBase
{
[Parameter]
public Profile CurrentProfile { get; set; } = Profile.NO_PROFILE;
[Parameter]
public EventCallback<Profile> CurrentProfileChanged { get; set; }
[Parameter]
public string MarginLeft { get; set; } = "ml-3";
[Inject]
private SettingsManager SettingsManager { get; init; } = null!;
private string MarginClass => $"{this.MarginLeft}";
private async Task SelectionChanged(Profile profile)
{
this.CurrentProfile = profile;
await this.CurrentProfileChanged.InvokeAsync(profile);
}
private IEnumerable<Profile> Profiles()
{
yield return Profile.NO_PROFILE;
foreach (var profile in this.SettingsManager.ConfigurationData.Profiles)
yield return profile;
}
}

View File

@ -69,6 +69,8 @@
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/> <MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/>
</MudTooltip> </MudTooltip>
} }
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" />
</MudToolBar> </MudToolBar>
</FooterContent> </FooterContent>
</InnerScrolling> </InnerScrolling>

View File

@ -35,6 +35,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
private AIStudio.Settings.Provider providerSettings; private AIStudio.Settings.Provider providerSettings;
private Profile currentProfile = Profile.NO_PROFILE;
private ChatThread? chatThread; private ChatThread? chatThread;
private bool hasUnsavedChanges; private bool hasUnsavedChanges;
private bool isStreaming; private bool isStreaming;
@ -118,6 +119,22 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
private bool CanThreadBeSaved => this.chatThread is not null && this.chatThread.Blocks.Count > 0; private bool CanThreadBeSaved => this.chatThread is not null && this.chatThread.Blocks.Count > 0;
private string TooltipAddChatToWorkspace => $"Start new chat in workspace \"{this.currentWorkspaceName}\""; private string TooltipAddChatToWorkspace => $"Start new chat in workspace \"{this.currentWorkspaceName}\"";
private void ProfileWasChanged(Profile profile)
{
this.currentProfile = profile;
if(this.chatThread is null)
return;
this.chatThread = this.chatThread with
{
SystemPrompt = $"""
{SystemPrompts.DEFAULT}
{this.currentProfile.ToSystemPrompt()}
"""
};
}
private async Task SendMessage() private async Task SendMessage()
{ {
@ -135,7 +152,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = threadName, Name = threadName,
Seed = this.RNG.Next(), Seed = this.RNG.Next(),
SystemPrompt = SystemPrompts.DEFAULT, SystemPrompt = $"""
{SystemPrompts.DEFAULT}
{this.currentProfile.ToSystemPrompt()}
""",
Blocks = [], Blocks = [],
}; };
} }
@ -320,7 +341,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
ChatId = Guid.NewGuid(), ChatId = Guid.NewGuid(),
Name = string.Empty, Name = string.Empty,
Seed = this.RNG.Next(), Seed = this.RNG.Next(),
SystemPrompt = "You are a helpful assistant!", SystemPrompt = $"""
{SystemPrompts.DEFAULT}
{this.currentProfile.ToSystemPrompt()}
""",
Blocks = [], Blocks = [],
}; };
} }

View File

@ -2,6 +2,15 @@ namespace AIStudio.Settings;
public readonly record struct Profile(uint Num, string Id, string Name, string NeedToKnow, string Actions) public readonly record struct Profile(uint Num, string Id, string Name, string NeedToKnow, string Actions)
{ {
public static readonly Profile NO_PROFILE = new()
{
Name = "Use no profile",
NeedToKnow = string.Empty,
Actions = string.Empty,
Id = Guid.Empty.ToString(),
Num = uint.MaxValue,
};
#region Overrides of ValueType #region Overrides of ValueType
/// <summary> /// <summary>
@ -11,4 +20,40 @@ public readonly record struct Profile(uint Num, string Id, string Name, string N
public override string ToString() => this.Name; public override string ToString() => this.Name;
#endregion #endregion
public string ToSystemPrompt()
{
if(this.Num == uint.MaxValue)
return string.Empty;
var needToKnow =
$"""
What should you know about the user?
```
{this.NeedToKnow}
```
""";
var actions =
$"""
The user wants you to consider the following things.
```
{this.Actions}
```
""";
if (string.IsNullOrWhiteSpace(this.NeedToKnow))
return actions;
if (string.IsNullOrWhiteSpace(this.Actions))
return needToKnow;
return $"""
{needToKnow}
{actions}
""";
}
} }

View File

@ -1,5 +1,7 @@
# 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 the possibility to define multiple profiles in the settings. Use profiles to share some information about you with the AI.
- Added profiles to the chat interface. You can now select a profile for each chat or even change the profile during a chat.
- Added profiles to some assistants. It makes no sense to have profiles for, e.g., translation, etc.
- 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.