Add config plugin support to hide individual assistants

This change enables enterprise IT departments to hide specific assistants
via configuration plugins, providing better control over which features
are available to end users.

Changes:
- Created ConfigurableAssistant enum listing all hideable assistants
- Added HiddenAssistants property to DataApp settings (HashSet<ConfigurableAssistant>)
- Added IsAssistantVisible() method in Assistants.razor.cs to check visibility
- Updated Assistants.razor to conditionally render assistants based on configuration
- Extended plugin.lua template with HiddenAssistants configuration example

Example usage in configuration plugin:
CONFIG["SETTINGS"]["DataApp.HiddenAssistants"] = { "GRAMMAR_SPELLING_ASSISTANT", "SYNONYMS_ASSISTANT" }

The setting integrates with the existing ManagedConfiguration system and
is locked when managed by a config plugin, preventing user override.
This commit is contained in:
Claude 2026-01-11 22:18:26 +00:00
parent ab7618097d
commit 509d57f69a
No known key found for this signature in database
5 changed files with 144 additions and 21 deletions

View File

@ -14,54 +14,96 @@
@T("General")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogTextSummarizer" Name="@T("Text Summarizer")" Description="@T("Use an LLM to summarize a given text.")" Icon="@Icons.Material.Filled.TextSnippet" Link="@Routes.ASSISTANT_SUMMARIZER"/>
<AssistantBlock TSettings="SettingsDialogTranslation" Name="@T("Translation")" Description="@T("Translate text into another language.")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_TRANSLATION"/>
<AssistantBlock TSettings="SettingsDialogGrammarSpelling" Name="@T("Grammar & Spelling")" Description="@T("Check grammar and spelling of a given text.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_GRAMMAR_SPELLING"/>
<AssistantBlock TSettings="SettingsDialogRewrite" Name="@T("Rewrite & Improve")" Description="@T("Rewrite and improve a given text for a chosen style.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_REWRITE"/>
<AssistantBlock TSettings="SettingsDialogSynonyms" Name="@T("Synonyms")" Description="@T("Find synonyms for a given word or phrase.")" Icon="@Icons.Material.Filled.Spellcheck" Link="@Routes.ASSISTANT_SYNONYMS"/>
@if (IsAssistantVisible(Components.TEXT_SUMMARIZER_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogTextSummarizer" Name="@T("Text Summarizer")" Description="@T("Use an LLM to summarize a given text.")" Icon="@Icons.Material.Filled.TextSnippet" Link="@Routes.ASSISTANT_SUMMARIZER"/>
}
@if (IsAssistantVisible(Components.TRANSLATION_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogTranslation" Name="@T("Translation")" Description="@T("Translate text into another language.")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_TRANSLATION"/>
}
@if (IsAssistantVisible(Components.GRAMMAR_SPELLING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogGrammarSpelling" Name="@T("Grammar & Spelling")" Description="@T("Check grammar and spelling of a given text.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_GRAMMAR_SPELLING"/>
}
@if (IsAssistantVisible(Components.REWRITE_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogRewrite" Name="@T("Rewrite & Improve")" Description="@T("Rewrite and improve a given text for a chosen style.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_REWRITE"/>
}
@if (IsAssistantVisible(Components.SYNONYMS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogSynonyms" Name="@T("Synonyms")" Description="@T("Find synonyms for a given word or phrase.")" Icon="@Icons.Material.Filled.Spellcheck" Link="@Routes.ASSISTANT_SYNONYMS"/>
}
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Business")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogWritingEMails" Name="@T("E-Mail")" Description="@T("Generate an e-mail for a given context.")" Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
@if (PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025.IsEnabled(this.SettingsManager))
@if (IsAssistantVisible(Components.EMAIL_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogWritingEMails" Name="@T("E-Mail")" Description="@T("Generate an e-mail for a given context.")" Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
}
@if (PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025.IsEnabled(this.SettingsManager) && IsAssistantVisible(Components.DOCUMENT_ANALYSIS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogDocumentAnalysis" Name="@T("Document Analysis")" Description="@T("Analyze a document regarding defined rules and extract key information.")" Icon="@Icons.Material.Filled.DocumentScanner" Link="@Routes.ASSISTANT_DOCUMENT_ANALYSIS"/>
}
<AssistantBlock TSettings="SettingsDialogMyTasks" Name="@T("My Tasks")" Description="@T("Analyze a text or an email for tasks you need to complete.")" Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
<AssistantBlock TSettings="SettingsDialogAgenda" Name="@T("Agenda Planner")" Description="@T("Generate an agenda for a given meeting, seminar, etc.")" Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
<AssistantBlock TSettings="SettingsDialogJobPostings" Name="@T("Job Posting")" Description="@T("Generate a job posting for a given job description.")" Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>
<AssistantBlock TSettings="SettingsDialogLegalCheck" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
<AssistantBlock TSettings="SettingsDialogIconFinder" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
@if (IsAssistantVisible(Components.MY_TASKS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogMyTasks" Name="@T("My Tasks")" Description="@T("Analyze a text or an email for tasks you need to complete.")" Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
}
@if (IsAssistantVisible(Components.AGENDA_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogAgenda" Name="@T("Agenda Planner")" Description="@T("Generate an agenda for a given meeting, seminar, etc.")" Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
}
@if (IsAssistantVisible(Components.JOB_POSTING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogJobPostings" Name="@T("Job Posting")" Description="@T("Generate a job posting for a given job description.")" Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>
}
@if (IsAssistantVisible(Components.LEGAL_CHECK_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogLegalCheck" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
}
@if (IsAssistantVisible(Components.ICON_FINDER_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogIconFinder" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
}
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Learning")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogAssistantBias" Name="@T("Bias of the Day")" Description="@T("Learn about one cognitive bias every day.")" Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
@if (IsAssistantVisible(Components.BIAS_DAY_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogAssistantBias" Name="@T("Bias of the Day")" Description="@T("Learn about one cognitive bias every day.")" Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
}
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Software Engineering")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogCoding" Name="@T("Coding")" Description="@T("Get coding and debugging support from an LLM.")" Icon="@Icons.Material.Filled.Code" Link="@Routes.ASSISTANT_CODING"/>
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
@if (IsAssistantVisible(Components.CODING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogCoding" Name="@T("Coding")" Description="@T("Get coding and debugging support from an LLM.")" Icon="@Icons.Material.Filled.Code" Link="@Routes.ASSISTANT_CODING"/>
}
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager) && IsAssistantVisible(Components.ERI_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogERIServer" Name="@T("ERI Server")" Description="@T("Generate an ERI server to integrate business systems.")" Icon="@Icons.Material.Filled.PrivateConnectivity" Link="@Routes.ASSISTANT_ERI"/>
}
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("AI Studio Development")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
<AssistantBlock TSettings="SettingsDialogI18N" Name="@T("Localization")" Description="@T("Translate AI Studio text content into other languages")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_AI_STUDIO_I18N"/>
@if (IsAssistantVisible(Components.I18N_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogI18N" Name="@T("Localization")" Description="@T("Translate AI Studio text content into other languages")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_AI_STUDIO_I18N"/>
}
</MudStack>
</InnerScrolling>

View File

@ -1,5 +1,45 @@
using AIStudio.Components;
using AIStudio.Settings;
using AIStudio.Tools;
namespace AIStudio.Pages;
public partial class Assistants : MSGComponentBase;
public partial class Assistants : MSGComponentBase
{
/// <summary>
/// Checks if an assistant should be visible based on configuration.
/// </summary>
/// <param name="component">The assistant component to check.</param>
/// <returns>True if the assistant should be visible, false otherwise.</returns>
private bool IsAssistantVisible(Components component)
{
// Map Components enum to ConfigurableAssistant enum
var configurableAssistant = component switch
{
Components.GRAMMAR_SPELLING_ASSISTANT => ConfigurableAssistant.GRAMMAR_SPELLING_ASSISTANT,
Components.ICON_FINDER_ASSISTANT => ConfigurableAssistant.ICON_FINDER_ASSISTANT,
Components.REWRITE_ASSISTANT => ConfigurableAssistant.REWRITE_ASSISTANT,
Components.TRANSLATION_ASSISTANT => ConfigurableAssistant.TRANSLATION_ASSISTANT,
Components.AGENDA_ASSISTANT => ConfigurableAssistant.AGENDA_ASSISTANT,
Components.CODING_ASSISTANT => ConfigurableAssistant.CODING_ASSISTANT,
Components.TEXT_SUMMARIZER_ASSISTANT => ConfigurableAssistant.TEXT_SUMMARIZER_ASSISTANT,
Components.EMAIL_ASSISTANT => ConfigurableAssistant.EMAIL_ASSISTANT,
Components.LEGAL_CHECK_ASSISTANT => ConfigurableAssistant.LEGAL_CHECK_ASSISTANT,
Components.SYNONYMS_ASSISTANT => ConfigurableAssistant.SYNONYMS_ASSISTANT,
Components.MY_TASKS_ASSISTANT => ConfigurableAssistant.MY_TASKS_ASSISTANT,
Components.JOB_POSTING_ASSISTANT => ConfigurableAssistant.JOB_POSTING_ASSISTANT,
Components.BIAS_DAY_ASSISTANT => ConfigurableAssistant.BIAS_DAY_ASSISTANT,
Components.ERI_ASSISTANT => ConfigurableAssistant.ERI_ASSISTANT,
Components.DOCUMENT_ANALYSIS_ASSISTANT => ConfigurableAssistant.DOCUMENT_ANALYSIS_ASSISTANT,
Components.I18N_ASSISTANT => ConfigurableAssistant.I18N_ASSISTANT,
_ => (ConfigurableAssistant?)null,
};
// If the component doesn't map to a configurable assistant, it's always visible
if (configurableAssistant is null)
return true;
// Check if the assistant is hidden in configuration
return !this.SettingsManager.ConfigurationData.App.HiddenAssistants.Contains(configurableAssistant.Value);
}
}

View File

@ -143,6 +143,15 @@ CONFIG["SETTINGS"] = {}
-- Please note: using an empty string ("") will lock the selection and disable dictation/transcription.
-- CONFIG["SETTINGS"]["DataApp.UseTranscriptionProvider"] = "00000000-0000-0000-0000-000000000000"
-- Configure which assistants should be hidden from the UI.
-- Allowed values can be found in ConfigurableAssistant enum.
-- Examples: GRAMMAR_SPELLING_ASSISTANT, ICON_FINDER_ASSISTANT, REWRITE_ASSISTANT,
-- TRANSLATION_ASSISTANT, AGENDA_ASSISTANT, CODING_ASSISTANT,
-- TEXT_SUMMARIZER_ASSISTANT, EMAIL_ASSISTANT, LEGAL_CHECK_ASSISTANT,
-- SYNONYMS_ASSISTANT, MY_TASKS_ASSISTANT, JOB_POSTING_ASSISTANT,
-- BIAS_DAY_ASSISTANT, ERI_ASSISTANT, DOCUMENT_ANALYSIS_ASSISTANT, I18N_ASSISTANT
-- CONFIG["SETTINGS"]["DataApp.HiddenAssistants"] = { "GRAMMAR_SPELLING_ASSISTANT", "SYNONYMS_ASSISTANT" }
-- Example chat templates for this configuration:
CONFIG["CHAT_TEMPLATES"] = {}

View File

@ -0,0 +1,27 @@
namespace AIStudio.Settings;
/// <summary>
/// Enum representing assistants that can be hidden via configuration plugin.
/// </summary>
public enum ConfigurableAssistant
{
GRAMMAR_SPELLING_ASSISTANT,
ICON_FINDER_ASSISTANT,
REWRITE_ASSISTANT,
TRANSLATION_ASSISTANT,
AGENDA_ASSISTANT,
CODING_ASSISTANT,
TEXT_SUMMARIZER_ASSISTANT,
EMAIL_ASSISTANT,
LEGAL_CHECK_ASSISTANT,
SYNONYMS_ASSISTANT,
MY_TASKS_ASSISTANT,
JOB_POSTING_ASSISTANT,
BIAS_DAY_ASSISTANT,
ERI_ASSISTANT,
DOCUMENT_ANALYSIS_ASSISTANT,
// ReSharper disable InconsistentNaming
I18N_ASSISTANT,
// ReSharper restore InconsistentNaming
}

View File

@ -86,4 +86,9 @@ public sealed class DataApp(Expression<Func<Data, DataApp>>? configSelection = n
/// Should the user be allowed to add providers?
/// </summary>
public bool AllowUserToAddProvider { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AllowUserToAddProvider, true);
/// <summary>
/// List of assistants that should be hidden from the UI.
/// </summary>
public HashSet<ConfigurableAssistant> HiddenAssistants { get; set; } = ManagedConfiguration.Register(configSelection, n => n.HiddenAssistants, []);
}