From 7e29999bfb9115d327a887c15ee4e57b2f9f5f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peer=20Sch=C3=BCtt?= <20603780+peerschuett@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:17:17 +0200 Subject: [PATCH] The template can now be created from an existing thread --- app/MindWork AI Studio/Chat/ChatThread.cs | 6 +++- app/MindWork AI Studio/Chat/ContentBlock.cs | 2 +- .../Components/ChatComponent.razor | 3 +- .../Components/ChatTemplateSelection.razor | 2 ++ .../Components/ChatTemplateSelection.razor.cs | 17 +++++++++++ .../Dialogs/ChatTemplateDialog.razor.cs | 20 +++++++++++++ .../SettingsDialogChatTemplate.razor.cs | 29 ++++++++++++++++++- 7 files changed, 75 insertions(+), 4 deletions(-) diff --git a/app/MindWork AI Studio/Chat/ChatThread.cs b/app/MindWork AI Studio/Chat/ChatThread.cs index c57e5160..c04e729f 100644 --- a/app/MindWork AI Studio/Chat/ChatThread.cs +++ b/app/MindWork AI Studio/Chat/ChatThread.cs @@ -68,7 +68,7 @@ public sealed record ChatThread /// /// The current system prompt for the chat thread. /// - public string SystemPrompt { get; init; } = string.Empty; + public string SystemPrompt { get; set; } = string.Empty; /// /// The content blocks of the chat thread. @@ -121,6 +121,10 @@ public sealed record ChatThread } } + // We need a way to save the changed system prompt in our chatThread. + // Otherwise, the chatThread will always tell us that it is using the default system prompt. + chatThread.SystemPrompt = systemPromptTextWithChatTemplate; + logger.LogInformation(logMessage); // diff --git a/app/MindWork AI Studio/Chat/ContentBlock.cs b/app/MindWork AI Studio/Chat/ContentBlock.cs index a069c3d8..841cad69 100644 --- a/app/MindWork AI Studio/Chat/ContentBlock.cs +++ b/app/MindWork AI Studio/Chat/ContentBlock.cs @@ -28,7 +28,7 @@ public class ContentBlock /// /// Should the content block be hidden from the user? /// - public bool HideFromUser { get; init; } + public bool HideFromUser { get; set; } public ContentBlock DeepClone() => new() { diff --git a/app/MindWork AI Studio/Components/ChatComponent.razor b/app/MindWork AI Studio/Components/ChatComponent.razor index 66538eda..48420522 100644 --- a/app/MindWork AI Studio/Components/ChatComponent.razor +++ b/app/MindWork AI Studio/Components/ChatComponent.razor @@ -81,7 +81,8 @@ } - + + @if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY) { diff --git a/app/MindWork AI Studio/Components/ChatTemplateSelection.razor b/app/MindWork AI Studio/Components/ChatTemplateSelection.razor index 7f9f09cf..624520de 100644 --- a/app/MindWork AI Studio/Components/ChatTemplateSelection.razor +++ b/app/MindWork AI Studio/Components/ChatTemplateSelection.razor @@ -18,6 +18,8 @@ + + @foreach (var chatTemplate in this.SettingsManager.ConfigurationData.ChatTemplates.GetAllChatTemplates()) { diff --git a/app/MindWork AI Studio/Components/ChatTemplateSelection.razor.cs b/app/MindWork AI Studio/Components/ChatTemplateSelection.razor.cs index e624884c..25b72e11 100644 --- a/app/MindWork AI Studio/Components/ChatTemplateSelection.razor.cs +++ b/app/MindWork AI Studio/Components/ChatTemplateSelection.razor.cs @@ -1,3 +1,4 @@ +using AIStudio.Chat; using AIStudio.Dialogs.Settings; using AIStudio.Settings; @@ -11,6 +12,12 @@ public partial class ChatTemplateSelection : MSGComponentBase [Parameter] public ChatTemplate CurrentChatTemplate { get; set; } = ChatTemplate.NO_CHAT_TEMPLATE; + [Parameter] + public bool CanChatThreadBeUsedForTemplate { get; set; } + + [Parameter] + public ChatThread? CurrentChatThread { get; set; } + [Parameter] public EventCallback CurrentChatTemplateChanged { get; set; } @@ -36,4 +43,14 @@ public partial class ChatTemplateSelection : MSGComponentBase var dialogParameters = new DialogParameters(); await this.DialogService.ShowAsync(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN); } + + private async Task CreateNewChatTemplateFromChat() + { + var dialogParameters = new DialogParameters + { + { x => x.CreateTemplateFromExistingChatThread, true }, + { x => x.ExistingChatThread, this.CurrentChatThread } + }; + await this.DialogService.ShowAsync(T("Open Chat Template Options"), dialogParameters, DialogOptions.FULLSCREEN); + } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs b/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs index 7a8b6765..9fb9b52a 100644 --- a/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/ChatTemplateDialog.razor.cs @@ -53,6 +53,12 @@ public partial class ChatTemplateDialog : MSGComponentBase [Parameter] public bool AllowProfileUsage { get; set; } = true; + [Parameter] + public bool CreateFromExistingChatThread { get; set; } + + [Parameter] + public ChatThread? ExistingChatThread { get; set; } + [Inject] private ILogger Logger { get; init; } = null!; @@ -90,6 +96,20 @@ public partial class ChatTemplateDialog : MSGComponentBase this.dataEditingPreviousName = this.DataName.ToLowerInvariant(); this.dataExampleConversation = this.ExampleConversation.Select(n => n.DeepClone()).ToList(); } + + if (this.CreateFromExistingChatThread) + { + this.DataSystemPrompt = this.ExistingChatThread!.SystemPrompt; + this.dataExampleConversation = this.ExistingChatThread!.Blocks.Select(n => n.DeepClone()).ToList(); + this.DataName = this.ExistingChatThread!.Name; + + // the contentblocks that we copy are visible to the user, and we don't want to show them while using the template + foreach (var item in this.dataExampleConversation) + { + item.HideFromUser = true; + } + + } await base.OnInitializedAsync(); } diff --git a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs index 8ca3118a..ac8e10e3 100644 --- a/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs +++ b/app/MindWork AI Studio/Dialogs/Settings/SettingsDialogChatTemplate.razor.cs @@ -1,16 +1,43 @@ +using AIStudio.Chat; using AIStudio.Settings; +using Microsoft.AspNetCore.Components; namespace AIStudio.Dialogs.Settings; public partial class SettingsDialogChatTemplate : SettingsDialogBase { + + [Parameter] + public bool CreateTemplateFromExistingChatThread { get; set; } + + [Parameter] + public ChatThread? ExistingChatThread { get; set; } + + #region Overrides of ComponentBase + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + if (this.CreateTemplateFromExistingChatThread) + await this.AddChatTemplate(); + } + + #endregion + private async Task AddChatTemplate() { var dialogParameters = new DialogParameters { { x => x.IsEditing, false }, }; - + + if (this.CreateTemplateFromExistingChatThread) + { + dialogParameters.Add(x => x.CreateFromExistingChatThread, this.CreateTemplateFromExistingChatThread); + dialogParameters.Add(x => x.ExistingChatThread, this.ExistingChatThread); + } + var dialogReference = await this.DialogService.ShowAsync(T("Add Chat Template"), dialogParameters, DialogOptions.FULLSCREEN); var dialogResult = await dialogReference.Result; if (dialogResult is null || dialogResult.Canceled)