From d25bdb35b707050d4291362201b9d8c74820fb00 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 14 Sep 2026 09:20:55 +0200 Subject: [PATCH] Make the workspace optional when building a chat launcher --- .../Assistants/Builder/AssistantBuilder.razor | 5 ++--- .../Assistants/Builder/AssistantBuilder.razor.cs | 16 +++++----------- .../Components/DirectChatLauncherForm.razor | 10 +++++++++- .../Components/DirectChatLauncherForm.razor.cs | 14 +++++++------- .../DirectChatLauncherSettingsDialog.razor | 3 +-- .../DirectChatLauncherSettingsDialog.razor.cs | 6 +++--- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor b/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor index 4b7f965e..dbde56e0 100644 --- a/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor +++ b/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor @@ -23,7 +23,7 @@ @(this.createChatLauncher - ? T("The direct chat launcher tile has no input form of its own. It opens a new chat right away, in the workspace you name below and with the provider, profile, chat template, and data sources you select there.") + ? T("The direct chat launcher tile has no input form of its own. It opens a new chat right away, with the provider, profile, chat template, and data sources you select below. Name a workspace for that chat, or leave the workspace empty to open a disappearing chat.") : T("The assistant asks users for input through a form and builds its own prompt from it.")) @if (this.createChatLauncher) @@ -39,8 +39,7 @@ @bind-ProfileId="@this.launcherProfileId" @bind-ChatTemplateId="@this.launcherChatTemplateId" @bind-DataSourceIds="@this.launcherDataSourceIds" - @bind-ToolIds="@this.launcherToolIds" - ValidateWorkspaceName="@this.ValidateLauncherWorkspaceName"/> + @bind-ToolIds="@this.launcherToolIds"/> } diff --git a/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor.cs b/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor.cs index e17d75cb..f129d464 100644 --- a/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor.cs +++ b/app/MindWork AI Studio/Assistants/Builder/AssistantBuilder.razor.cs @@ -375,14 +375,6 @@ public partial class AssistantBuilder : AssistantBaseCore return null; } - private string? ValidateLauncherWorkspaceName(string workspaceName) - { - if (this.createChatLauncher && string.IsNullOrWhiteSpace(workspaceName)) - return T("Please select or enter a workspace name for the chat launcher."); - - return null; - } - private async Task GenerateAssistantSpec() { await this.Form!.Validate(); @@ -589,7 +581,8 @@ public partial class AssistantBuilder : AssistantBaseCore // The description stays required for both kinds of assistant. Users who only want a tile // usually flip the switch before typing anything, so the Builder offers a starting point they // can edit or replace. The workspace is picked after that, hence the suggestion is refreshed - // whenever the workspace changes: + // whenever the workspace changes — including when it is cleared again, which turns the tile + // into one that opens a disappearing chat: // private void SuggestLauncherDescription() { @@ -597,8 +590,9 @@ public partial class AssistantBuilder : AssistantBaseCore return; var suggestion = T("Create a tile that opens a preconfigured chat directly, without an input form of its own."); - if (!string.IsNullOrWhiteSpace(this.launcherWorkspaceName)) - suggestion = $"{suggestion} {string.Format(T("Workspace: {0}"), this.launcherWorkspaceName.Trim())}"; + suggestion = string.IsNullOrWhiteSpace(this.launcherWorkspaceName) + ? $"{suggestion} {T("The chat belongs to no workspace and disappears again.")}" + : $"{suggestion} {string.Format(T("Workspace: {0}"), this.launcherWorkspaceName.Trim())}"; this.assistantDescription = suggestion; this.descriptionSuggestion = suggestion; diff --git a/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor b/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor index e1c432cf..af72de38 100644 --- a/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor +++ b/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor @@ -10,7 +10,15 @@ } - + + +@* The tile behaves differently with and without a workspace, so the form says which of the two is + chosen right now instead of only explaining that both are possible. *@ + + @(this.OpensTemporaryChat + ? T("Without a workspace, the tile opens a disappearing chat: it belongs to no workspace and is deleted according to your workspace maintenance settings.") + : T("The tile opens its chat in this workspace and creates the workspace when it does not exist yet.")) + @T("Use chat default") @foreach (var provider in this.SettingsManager.GetConfidentProviders(Components.CHAT)) diff --git a/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor.cs b/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor.cs index e9c91f0a..bdd363ac 100644 --- a/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor.cs +++ b/app/MindWork AI Studio/Components/DirectChatLauncherForm.razor.cs @@ -3,8 +3,9 @@ using Microsoft.AspNetCore.Components; namespace AIStudio.Components; /// -/// The selection a direct chat launcher needs: the workspace its chat is created in, and the -/// provider, profile, chat template, and data sources that chat starts with. +/// The selection a direct chat launcher needs: the workspace its chat is created in — or no +/// workspace, for a disappearing chat — and the provider, profile, chat template, and data sources +/// that chat starts with. /// /// /// The Assistant Builder uses this form to describe a launcher it is about to generate, while the @@ -15,7 +16,8 @@ public partial class DirectChatLauncherForm : MSGComponentBase { /// /// The name of the workspace the launcher opens its chat in. The workspace is created when it - /// does not exist yet, hence this is a free-text field and not a workspace ID. + /// does not exist yet, hence this is a free-text field and not a workspace ID. An empty name is + /// a choice of its own: the launcher then opens a disappearing chat. /// [Parameter] public string WorkspaceName { get; set; } = string.Empty; @@ -75,11 +77,9 @@ public partial class DirectChatLauncherForm : MSGComponentBase public EventCallback> ToolIdsChanged { get; set; } /// - /// Validates the workspace name. The hosts differ here: the Builder requires a name only while - /// its launcher switch is on, whereas the settings dialog always requires one. + /// Whether the launcher currently describes a chat without a workspace. /// - [Parameter] - public Func? ValidateWorkspaceName { get; set; } + private bool OpensTemporaryChat => string.IsNullOrWhiteSpace(this.WorkspaceName); private IReadOnlyList availableWorkspaces = []; diff --git a/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor b/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor index a7a82d72..1402f470 100644 --- a/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor +++ b/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor @@ -32,8 +32,7 @@ @bind-ProfileId="@this.profileId" @bind-ChatTemplateId="@this.chatTemplateId" @bind-DataSourceIds="@this.dataSourceIds" - @bind-ToolIds="@this.toolIds" - ValidateWorkspaceName="@this.ValidateWorkspaceName"/> + @bind-ToolIds="@this.toolIds"/> diff --git a/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor.cs b/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor.cs index ef5ac332..3a7cb0ea 100644 --- a/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor.cs +++ b/app/MindWork AI Studio/Dialogs/DirectChatLauncherSettingsDialog.razor.cs @@ -152,7 +152,9 @@ public partial class DirectChatLauncherSettingsDialog : MSGComponentBase // // An empty selection means "use the chat defaults" and is left out of the plugin, whereas - // the empty GUID explicitly selects no profile or no chat template: + // the empty GUID explicitly selects no profile or no chat template. Clearing the workspace + // name is a change of its own: the tile then opens a disappearing chat, and the writer + // switches the launch behavior accordingly. // return new( this.workspaceName.Trim(), @@ -248,8 +250,6 @@ public partial class DirectChatLauncherSettingsDialog : MSGComponentBase private string? ValidateDescription(string value) => string.IsNullOrWhiteSpace(value) ? T("Please provide a description for this tile.") : null; - private string? ValidateWorkspaceName(string value) => string.IsNullOrWhiteSpace(value) ? T("Please select or enter a workspace name for this tile.") : null; - private void Cancel() => this.MudDialog.Cancel(); private static Guid? ParseOptionalGuid(string value) => Guid.TryParse(value, out var parsed) ? parsed : null;