diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor b/app/MindWork AI Studio/Assistants/AssistantBase.razor index 9d7673ef..ba18f75f 100644 --- a/app/MindWork AI Studio/Assistants/AssistantBase.razor +++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor @@ -93,6 +93,11 @@ Reset + + @if (this.AllowProfiles) + { + + } \ No newline at end of file diff --git a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs index 9608b1cc..6bc70335 100644 --- a/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs +++ b/app/MindWork AI Studio/Assistants/AssistantBase.razor.cs @@ -55,6 +55,8 @@ public abstract partial class AssistantBase : ComponentBase private protected virtual RenderFragment? Body => null; protected virtual bool ShowResult => true; + + protected virtual bool AllowProfiles => true; protected virtual bool ShowDedicatedProgress => false; @@ -72,6 +74,7 @@ public abstract partial class AssistantBase : ComponentBase private ContentBlock? resultingContentBlock; private string[] inputIssues = []; private bool isProcessing; + private Profile currentProfile = Profile.NO_PROFILE; #region Overrides of ComponentBase @@ -118,7 +121,12 @@ public abstract partial class AssistantBase : ComponentBase ChatId = Guid.NewGuid(), Name = string.Empty, Seed = this.RNG.Next(), - SystemPrompt = this.SystemPrompt, + SystemPrompt = !this.AllowProfiles ? this.SystemPrompt : + $""" + {this.SystemPrompt} + + {this.currentProfile.ToSystemPrompt()} + """, Blocks = [], }; } diff --git a/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs b/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs index f0dd044f..21227dfb 100644 --- a/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs +++ b/app/MindWork AI Studio/Assistants/GrammarSpelling/AssistantGrammarSpelling.razor.cs @@ -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, you return the text unchanged. """; + + protected override bool AllowProfiles => false; protected override bool ShowResult => false; diff --git a/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs b/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs index f23f7109..e239c8f6 100644 --- a/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs +++ b/app/MindWork AI Studio/Assistants/IconFinder/AssistantIconFinder.razor.cs @@ -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 quotation marks. """; + + protected override bool AllowProfiles => false; protected override IReadOnlyList FooterButtons => []; diff --git a/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs b/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs index a7ada742..6d8aef6e 100644 --- a/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs +++ b/app/MindWork AI Studio/Assistants/RewriteImprove/AssistantRewriteImprove.razor.cs @@ -24,6 +24,8 @@ public partial class AssistantRewriteImprove : AssistantBaseCore 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 ShowDedicatedProgress => true; diff --git a/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs b/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs index 032a50af..c238aacf 100644 --- a/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs +++ b/app/MindWork AI Studio/Assistants/Synonym/AssistantSynonyms.razor.cs @@ -47,6 +47,8 @@ public partial class AssistantSynonyms : AssistantBaseCore the {this.SystemPromptLanguage()} language. """; + protected override bool AllowProfiles => false; + protected override IReadOnlyList FooterButtons => []; protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with diff --git a/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs b/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs index c8461e23..20c03006 100644 --- a/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs +++ b/app/MindWork AI Studio/Assistants/TextSummarizer/AssistantTextSummarizer.razor.cs @@ -25,6 +25,8 @@ public partial class AssistantTextSummarizer : AssistantBaseCore a summary with the requested complexity. In any case, do not add any information. """; + protected override bool AllowProfiles => false; + protected override IReadOnlyList FooterButtons => []; protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with diff --git a/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs b/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs index 8485b16e..29cc0ef4 100644 --- a/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs +++ b/app/MindWork AI Studio/Assistants/Translation/AssistantTranslation.razor.cs @@ -21,6 +21,8 @@ public partial class AssistantTranslation : AssistantBaseCore language requires, e.g., shorter sentences, you should split the text into shorter sentences. """; + protected override bool AllowProfiles => false; + protected override IReadOnlyList FooterButtons => []; protected override ChatThread ConvertToChatThread => (this.chatThread ?? new()) with diff --git a/app/MindWork AI Studio/Components/ProfileSelection.razor b/app/MindWork AI Studio/Components/ProfileSelection.razor new file mode 100644 index 00000000..48f93a68 --- /dev/null +++ b/app/MindWork AI Studio/Components/ProfileSelection.razor @@ -0,0 +1,8 @@ + + @foreach (var profile in this.Profiles()) + { + + @profile.Name + + } + \ No newline at end of file diff --git a/app/MindWork AI Studio/Components/ProfileSelection.razor.cs b/app/MindWork AI Studio/Components/ProfileSelection.razor.cs new file mode 100644 index 00000000..d7403020 --- /dev/null +++ b/app/MindWork AI Studio/Components/ProfileSelection.razor.cs @@ -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 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 Profiles() + { + yield return Profile.NO_PROFILE; + foreach (var profile in this.SettingsManager.ConfigurationData.Profiles) + yield return profile; + } +} \ No newline at end of file diff --git a/app/MindWork AI Studio/Pages/Chat.razor b/app/MindWork AI Studio/Pages/Chat.razor index f87bdde4..3d5d3b73 100644 --- a/app/MindWork AI Studio/Pages/Chat.razor +++ b/app/MindWork AI Studio/Pages/Chat.razor @@ -69,6 +69,8 @@ } + + diff --git a/app/MindWork AI Studio/Pages/Chat.razor.cs b/app/MindWork AI Studio/Pages/Chat.razor.cs index e3ff30e6..1dbecd0c 100644 --- a/app/MindWork AI Studio/Pages/Chat.razor.cs +++ b/app/MindWork AI Studio/Pages/Chat.razor.cs @@ -35,6 +35,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable private static readonly Dictionary USER_INPUT_ATTRIBUTES = new(); private AIStudio.Settings.Provider providerSettings; + private Profile currentProfile = Profile.NO_PROFILE; private ChatThread? chatThread; private bool hasUnsavedChanges; 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 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() { @@ -135,7 +152,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable ChatId = Guid.NewGuid(), Name = threadName, Seed = this.RNG.Next(), - SystemPrompt = SystemPrompts.DEFAULT, + SystemPrompt = $""" + {SystemPrompts.DEFAULT} + + {this.currentProfile.ToSystemPrompt()} + """, Blocks = [], }; } @@ -320,7 +341,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable ChatId = Guid.NewGuid(), Name = string.Empty, Seed = this.RNG.Next(), - SystemPrompt = "You are a helpful assistant!", + SystemPrompt = $""" + {SystemPrompts.DEFAULT} + + {this.currentProfile.ToSystemPrompt()} + """, Blocks = [], }; } diff --git a/app/MindWork AI Studio/Settings/Profile.cs b/app/MindWork AI Studio/Settings/Profile.cs index cbcdc5c3..fd1da079 100644 --- a/app/MindWork AI Studio/Settings/Profile.cs +++ b/app/MindWork AI Studio/Settings/Profile.cs @@ -2,6 +2,15 @@ namespace AIStudio.Settings; 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 /// @@ -11,4 +20,40 @@ public readonly record struct Profile(uint Num, string Id, string Name, string N public override string ToString() => this.Name; #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} + """; + } } \ No newline at end of file diff --git a/app/MindWork AI Studio/wwwroot/changelog/v0.9.7.md b/app/MindWork AI Studio/wwwroot/changelog/v0.9.7.md index 4cc05a15..79a4ae85 100644 --- a/app/MindWork AI Studio/wwwroot/changelog/v0.9.7.md +++ b/app/MindWork AI Studio/wwwroot/changelog/v0.9.7.md @@ -1,5 +1,7 @@ # 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 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 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.