This commit is contained in:
Sabrina-devops 2026-05-12 18:23:53 +02:00 committed by GitHub
commit 6b4f750e9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 82 additions and 5 deletions

View File

@ -417,6 +417,13 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
} }
// Try to apply the policy preselection: // Try to apply the policy preselection:
if (Settings.Provider.IsNoProviderPreselection(this.selectedPolicy.PreselectedProvider))
{
this.ProviderSettings = Settings.Provider.NONE;
this.CurrentProfile = this.ResolveProfileSelection();
return;
}
var policyProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.selectedPolicy.PreselectedProvider); var policyProvider = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.selectedPolicy.PreselectedProvider);
if (policyProvider is not null && policyProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel) if (policyProvider is not null && policyProvider.UsedLLMProvider.GetConfidence(this.SettingsManager).Level >= minimumLevel)
{ {
@ -763,7 +770,9 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
["MinimumProviderConfidence"] = "{{this.selectedPolicy.MinimumProviderConfidence}}", ["MinimumProviderConfidence"] = "{{this.selectedPolicy.MinimumProviderConfidence}}",
-- Optional: preselect a provider or profile by ID. -- Optional: preselect a provider or profile by ID.
-- The IDs must exist in CONFIG["LLM_PROVIDERS"] or CONFIG["PROFILES"]. -- Use an empty provider ID to fall back to the app default provider.
-- Use "{{Settings.Provider.NO_PROVIDER_PRESELECTION_ID}}" to explicitly preselect no provider.
-- Any other IDs must exist in CONFIG["LLM_PROVIDERS"] or CONFIG["PROFILES"].
["PreselectedProvider"] = "{{preselectedProvider}}", ["PreselectedProvider"] = "{{preselectedProvider}}",
["PreselectedProfile"] = "{{preselectedProfile}}", ["PreselectedProfile"] = "{{preselectedProfile}}",

View File

@ -2191,6 +2191,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T20906218
-- Use app default -- Use app default
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "Use app default" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "Use app default"
-- No provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3740605451"] = "No provider"
-- No shortcut configured -- No shortcut configured
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "No shortcut configured" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "No shortcut configured"

View File

@ -4,6 +4,7 @@ using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Tools.PluginSystem; using AIStudio.Tools.PluginSystem;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using SettingsProvider = AIStudio.Settings.Provider;
namespace AIStudio.Components; namespace AIStudio.Components;
@ -38,8 +39,11 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
private IEnumerable<ConfigurationSelectData<string>> FilteredData() private IEnumerable<ConfigurationSelectData<string>> FilteredData()
{ {
if(this.Component is not Tools.Components.NONE and not Tools.Components.APP_SETTINGS) if(this.Component.SupportsAppDefaultProviderSelection())
{
yield return new(T("Use app default"), string.Empty); yield return new(T("Use app default"), string.Empty);
yield return new(T("No provider"), SettingsProvider.NO_PROVIDER_PRESELECTION_ID);
}
// Get the minimum confidence level for this component, and/or the enforced global minimum confidence level: // Get the minimum confidence level for this component, and/or the enforced global minimum confidence level:
var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.Component); var minimumLevel = this.SettingsManager.GetMinimumConfidenceLevel(this.Component);
@ -68,11 +72,11 @@ public partial class ConfigurationProviderSelection : MSGComponentBase
{ {
case Event.CONFIGURATION_CHANGED: case Event.CONFIGURATION_CHANGED:
if(string.IsNullOrWhiteSpace(this.SelectedValue())) if(string.IsNullOrWhiteSpace(this.SelectedValue()) || SettingsProvider.IsNoProviderPreselection(this.SelectedValue()))
break; break;
// Check if the selected value is still valid: // Check if the selected value is still valid:
if (this.Data.All(x => x.Value != this.SelectedValue())) if (this.FilteredData().All(x => x.Value != this.SelectedValue()))
{ {
this.SelectedValue = () => string.Empty; this.SelectedValue = () => string.Empty;
this.SelectionUpdate(string.Empty); this.SelectionUpdate(string.Empty);

View File

@ -2193,6 +2193,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T20906218
-- Use app default -- Use app default
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "App-Standard verwenden" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "App-Standard verwenden"
-- No provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3740605451"] = "Kein Anbieter"
-- No shortcut configured -- No shortcut configured
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "Keinen Tastaturkurzbefehl konfiguriert" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "Keinen Tastaturkurzbefehl konfiguriert"

View File

@ -2193,6 +2193,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T20906218
-- Use app default -- Use app default
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "Use app default" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3672477670"] = "Use app default"
-- No provider
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONPROVIDERSELECTION::T3740605451"] = "No provider"
-- No shortcut configured -- No shortcut configured
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "No shortcut configured" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CONFIGURATIONSHORTCUT::T3099115336"] = "No shortcut configured"

View File

@ -36,6 +36,8 @@ public sealed record Provider(
{ {
private static readonly ILogger<Provider> LOGGER = Program.LOGGER_FACTORY.CreateLogger<Provider>(); private static readonly ILogger<Provider> LOGGER = Program.LOGGER_FACTORY.CreateLogger<Provider>();
public const string NO_PROVIDER_PRESELECTION_ID = "__NO_PROVIDER__";
public static readonly Provider NONE = new(); public static readonly Provider NONE = new();
public Provider() : this( public Provider() : this(
@ -67,6 +69,8 @@ public sealed record Provider(
#endregion #endregion
public static bool IsNoProviderPreselection(string? providerId) => providerId == NO_PROVIDER_PRESELECTION_ID;
#region Implementation of ISecretId #region Implementation of ISecretId
/// <inheritdoc /> /// <inheritdoc />

View File

@ -256,9 +256,10 @@ public sealed class SettingsManager
public Provider GetPreselectedProvider(Tools.Components component, string? currentProviderId = null, bool usePreselectionBeforeCurrentProvider = false) public Provider GetPreselectedProvider(Tools.Components component, string? currentProviderId = null, bool usePreselectionBeforeCurrentProvider = false)
{ {
var minimumLevel = this.GetMinimumConfidenceLevel(component); var minimumLevel = this.GetMinimumConfidenceLevel(component);
var hasExplicitNoProviderPreselection = component.HasExplicitNoProviderPreselection(this);
// When there is only one provider, and it has a confidence level that is high enough, we return it: // When there is only one provider, and it has a confidence level that is high enough, we return it:
if (this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel) if (!hasExplicitNoProviderPreselection && this.ConfigurationData.Providers.Count == 1 && this.ConfigurationData.Providers[0].UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
return this.ConfigurationData.Providers[0]; return this.ConfigurationData.Providers[0];
// Is there a current provider with a sufficiently high confidence level? // Is there a current provider with a sufficiently high confidence level?
@ -291,6 +292,9 @@ public sealed class SettingsManager
if(currentProvider != Provider.NONE) if(currentProvider != Provider.NONE)
return currentProvider; return currentProvider;
if (hasExplicitNoProviderPreselection)
return Provider.NONE;
// //
// Case: The current provider should be used before the preselected provider, // Case: The current provider should be used before the preselected provider,
// but the current provider is not available or does not have a confidence // but the current provider is not available or does not have a confidence
@ -308,6 +312,7 @@ public sealed class SettingsManager
public Provider GetChatProviderForLoadedChat(string? chatProviderId = null) public Provider GetChatProviderForLoadedChat(string? chatProviderId = null)
{ {
var minimumLevel = this.GetMinimumConfidenceLevel(Tools.Components.CHAT); var minimumLevel = this.GetMinimumConfidenceLevel(Tools.Components.CHAT);
var hasExplicitNoChatProviderPreselection = Tools.Components.CHAT.HasExplicitNoProviderPreselection(this);
bool IsSelectableProvider(Provider provider) => bool IsSelectableProvider(Provider provider) =>
provider != Provider.NONE provider != Provider.NONE
@ -333,6 +338,9 @@ public sealed class SettingsManager
if (defaultChatProvider is not null) if (defaultChatProvider is not null)
return defaultChatProvider; return defaultChatProvider;
if (hasExplicitNoChatProviderPreselection)
return Provider.NONE;
var defaultAppProvider = FindProviderById(this.ConfigurationData.App.PreselectedProvider); var defaultAppProvider = FindProviderById(this.ConfigurationData.App.PreselectedProvider);
if (defaultAppProvider is not null) if (defaultAppProvider is not null)
return defaultAppProvider; return defaultAppProvider;

View File

@ -9,6 +9,17 @@ public static class ComponentsExtensions
{ {
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ComponentsExtensions).Namespace, nameof(ComponentsExtensions)); private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(ComponentsExtensions).Namespace, nameof(ComponentsExtensions));
public static bool SupportsAppDefaultProviderSelection(this Components component) => component switch
{
Components.NONE => false,
Components.APP_SETTINGS => false,
Components.AGENT_TEXT_CONTENT_CLEANER => false,
Components.AGENT_DATA_SOURCE_SELECTION => false,
Components.AGENT_RETRIEVAL_CONTEXT_VALIDATION => false,
Components.AGENT_ASSISTANT_PLUGIN_AUDIT => false,
_ => true,
};
public static bool AllowSendTo(this Components component) => component switch public static bool AllowSendTo(this Components component) => component switch
{ {
Components.NONE => false, Components.NONE => false,
@ -103,9 +114,40 @@ public static class ComponentsExtensions
_ => default, _ => default,
}; };
public static bool HasExplicitNoProviderPreselection(this Components component, SettingsManager settingsManager)
{
var preselectedProviderId = component switch
{
Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider : string.Empty,
Components.ICON_FINDER_ASSISTANT => settingsManager.ConfigurationData.IconFinder.PreselectOptions ? settingsManager.ConfigurationData.IconFinder.PreselectedProvider : string.Empty,
Components.REWRITE_ASSISTANT => settingsManager.ConfigurationData.RewriteImprove.PreselectOptions ? settingsManager.ConfigurationData.RewriteImprove.PreselectedProvider : string.Empty,
Components.PROMPT_OPTIMIZER_ASSISTANT => settingsManager.ConfigurationData.PromptOptimizer.PreselectOptions ? settingsManager.ConfigurationData.PromptOptimizer.PreselectedProvider : string.Empty,
Components.TRANSLATION_ASSISTANT => settingsManager.ConfigurationData.Translation.PreselectOptions ? settingsManager.ConfigurationData.Translation.PreselectedProvider : string.Empty,
Components.AGENDA_ASSISTANT => settingsManager.ConfigurationData.Agenda.PreselectOptions ? settingsManager.ConfigurationData.Agenda.PreselectedProvider : string.Empty,
Components.CODING_ASSISTANT => settingsManager.ConfigurationData.Coding.PreselectOptions ? settingsManager.ConfigurationData.Coding.PreselectedProvider : string.Empty,
Components.TEXT_SUMMARIZER_ASSISTANT => settingsManager.ConfigurationData.TextSummarizer.PreselectOptions ? settingsManager.ConfigurationData.TextSummarizer.PreselectedProvider : string.Empty,
Components.EMAIL_ASSISTANT => settingsManager.ConfigurationData.EMail.PreselectOptions ? settingsManager.ConfigurationData.EMail.PreselectedProvider : string.Empty,
Components.LEGAL_CHECK_ASSISTANT => settingsManager.ConfigurationData.LegalCheck.PreselectOptions ? settingsManager.ConfigurationData.LegalCheck.PreselectedProvider : string.Empty,
Components.SYNONYMS_ASSISTANT => settingsManager.ConfigurationData.Synonyms.PreselectOptions ? settingsManager.ConfigurationData.Synonyms.PreselectedProvider : string.Empty,
Components.MY_TASKS_ASSISTANT => settingsManager.ConfigurationData.MyTasks.PreselectOptions ? settingsManager.ConfigurationData.MyTasks.PreselectedProvider : string.Empty,
Components.JOB_POSTING_ASSISTANT => settingsManager.ConfigurationData.JobPostings.PreselectOptions ? settingsManager.ConfigurationData.JobPostings.PreselectedProvider : string.Empty,
Components.BIAS_DAY_ASSISTANT => settingsManager.ConfigurationData.BiasOfTheDay.PreselectOptions ? settingsManager.ConfigurationData.BiasOfTheDay.PreselectedProvider : string.Empty,
Components.ERI_ASSISTANT => settingsManager.ConfigurationData.ERI.PreselectOptions ? settingsManager.ConfigurationData.ERI.PreselectedProvider : string.Empty,
Components.I18N_ASSISTANT => settingsManager.ConfigurationData.I18N.PreselectOptions ? settingsManager.ConfigurationData.I18N.PreselectedProvider : string.Empty,
Components.SLIDE_BUILDER_ASSISTANT => settingsManager.ConfigurationData.SlideBuilder.PreselectOptions ? settingsManager.ConfigurationData.SlideBuilder.PreselectedProvider : string.Empty,
Components.CHAT => settingsManager.ConfigurationData.Chat.PreselectOptions ? settingsManager.ConfigurationData.Chat.PreselectedProvider : string.Empty,
_ => string.Empty,
};
return Settings.Provider.IsNoProviderPreselection(preselectedProviderId);
}
[SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")]
public static AIStudio.Settings.Provider PreselectedProvider(this Components component, SettingsManager settingsManager) public static AIStudio.Settings.Provider PreselectedProvider(this Components component, SettingsManager settingsManager)
{ {
if (component.HasExplicitNoProviderPreselection(settingsManager))
return Settings.Provider.NONE;
var preselectedProvider = component switch var preselectedProvider = component switch
{ {
Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider) : null, Components.GRAMMAR_SPELLING_ASSISTANT => settingsManager.ConfigurationData.GrammarSpelling.PreselectOptions ? settingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == settingsManager.ConfigurationData.GrammarSpelling.PreselectedProvider) : null,

View File

@ -10,6 +10,7 @@
- Added pre-call validation to check if the selected model exists for the provider before making the request. - Added pre-call validation to check if the selected model exists for the provider before making the request.
- Added math rendering in chats for LaTeX display formulas, including block formats such as `$$ ... $$` and `\[ ... \]`. - Added math rendering in chats for LaTeX display formulas, including block formats such as `$$ ... $$` and `\[ ... \]`.
- Added support for mandatory information notices in configuration plugins. Organizations can now require users to read and confirm important information before continuing in AI Studio. - Added support for mandatory information notices in configuration plugins. Organizations can now require users to read and confirm important information before continuing in AI Studio.
- Added "No provider" option in the internal settings of chat and assistants
- Released the document analysis assistant after an intense testing phase. - Released the document analysis assistant after an intense testing phase.
- Improved enterprise deployment for organizations: administrators can now provide up to 10 centrally managed enterprise configuration slots, use policy files on Linux and macOS, and continue using older configuration formats as a fallback during migration. - Improved enterprise deployment for organizations: administrators can now provide up to 10 centrally managed enterprise configuration slots, use policy files on Linux and macOS, and continue using older configuration formats as a fallback during migration.
- Improved transparency on the information page by showing configured mandatory notices together with their source and confirmation status. - Improved transparency on the information page by showing configured mandatory notices together with their source and confirmation status.