diff --git a/app/MindWork AI Studio/Settings/SettingsManager.cs b/app/MindWork AI Studio/Settings/SettingsManager.cs index 09081ff0..2c82b24e 100644 --- a/app/MindWork AI Studio/Settings/SettingsManager.cs +++ b/app/MindWork AI Studio/Settings/SettingsManager.cs @@ -491,10 +491,23 @@ public sealed class SettingsManager { var minimumLevel = this.GetMinimumConfidenceLevel(Tools.Components.CHAT); - bool IsSelectableProvider(Provider provider) => - provider != Provider.NONE - && provider.UsedLLMProvider != LLMProviders.NONE - && provider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel; + var chatProvider = FindProviderById(chatProviderId); + if (chatProvider is not null) + return chatProvider; + + var defaultChatProvider = this.ConfigurationData.Chat.PreselectOptions + ? FindProviderById(this.ConfigurationData.Chat.PreselectedProvider) + : null; + + if (defaultChatProvider is not null) + return defaultChatProvider; + + var defaultAppProvider = FindProviderById(this.ConfigurationData.App.PreselectedProvider); + if (defaultAppProvider is not null) + return defaultAppProvider; + + var selectableProviders = this.ConfigurationData.Providers.Where(IsSelectableProvider).ToList(); + return selectableProviders.Count == 1 ? selectableProviders[0] : Provider.NONE; Provider? FindProviderById(string? providerId) { @@ -505,22 +518,106 @@ public sealed class SettingsManager return provider is not null && IsSelectableProvider(provider) ? provider : null; } - var chatProvider = FindProviderById(chatProviderId); - if (chatProvider is not null) - return chatProvider; + bool IsSelectableProvider(Provider provider) => + provider != Provider.NONE + && provider.UsedLLMProvider != LLMProviders.NONE + && provider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel; + } - var defaultChatProvider = this.ConfigurationData.Chat.PreselectOptions - ? FindProviderById(this.ConfigurationData.Chat.PreselectedProvider) - : null; - if (defaultChatProvider is not null) - return defaultChatProvider; + /// + /// Returns all configured providers without applying any confidence filtering. + /// + /// + /// + /// This method applies neither the global minimum confidence level (see + /// with EnforceGlobalMinimumConfidence) nor any + /// component-specific minimum. Even when the user enforces a global minimum of, say, + /// , this method still returns every configured provider. + /// That is intentional: this method serves the provider management UI, duplicate-name checks, + /// and the raw select data of provider dropdowns. The dropdowns are filtered afterward by + /// ConfigurationProviderSelection, which calls IsProviderConfident. + /// + /// + /// Whenever a provider is about to be used for an LLM request, do not use this method. Use + /// GetConfidentProviders, GetPreselectedProvider, or GetChatProviderForLoadedChat instead, + /// since they honor the confidence levels. + /// + /// + /// The returned list is the live provider list. It is read-only for callers: adding, editing, + /// or removing providers stays inside the settings UI. + /// + /// + /// All configured providers, unfiltered. + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + public IReadOnlyList GetAllProviders() => this.ConfigurationData.Providers; - var defaultAppProvider = FindProviderById(this.ConfigurationData.App.PreselectedProvider); - if (defaultAppProvider is not null) - return defaultAppProvider; + /// + /// Returns the provider with the given id, without applying any confidence filtering. + /// + /// + /// This method resolves a stored provider reference by its id. It applies neither the global + /// minimum confidence level nor any component-specific minimum, so it returns the requested + /// provider even when the user enforces a higher global minimum. Callers that intend to use the + /// returned provider for an LLM request must check it themselves through + /// IsProviderConfident or fall back to GetPreselectedProvider. + /// + /// The id of the provider to look up. + /// The provider, or when no provider with that id exists. + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + public Provider GetProviderById(string? providerId) + { + if (string.IsNullOrWhiteSpace(providerId)) + return Provider.NONE; - var selectableProviders = this.ConfigurationData.Providers.Where(IsSelectableProvider).ToList(); - return selectableProviders.Count == 1 ? selectableProviders[0] : Provider.NONE; + if (string.Equals(providerId, Provider.NONE.Id, StringComparison.OrdinalIgnoreCase)) + return Provider.NONE; + + return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id.Equals(providerId, StringComparison.OrdinalIgnoreCase)) ?? Provider.NONE; + } + + /// + /// Determines the minimum confidence level a provider must have for the given component. + /// + /// The component for which the providers get filtered. + /// An explicit minimum level, which is applied when it is higher than the component's minimum. + /// The effective minimum confidence level. + public ConfidenceLevel GetEffectiveMinimumConfidenceLevel(Tools.Components component, ConfidenceLevel explicitMinimum = ConfidenceLevel.UNKNOWN) + { + var minimumLevel = this.GetMinimumConfidenceLevel(component); + if (explicitMinimum is not ConfidenceLevel.UNKNOWN && explicitMinimum > minimumLevel) + return explicitMinimum; + + return minimumLevel; + } + + /// + /// Checks whether the given provider satisfies the minimum confidence level of the given component. + /// + /// The provider to check. + /// The component for which the provider gets checked. + /// An explicit minimum level, which is applied when it is higher than the component's minimum. + /// True, when the provider may be used by the component, false otherwise. + public bool IsProviderConfident(Provider provider, Tools.Components component, ConfidenceLevel explicitMinimum = ConfidenceLevel.UNKNOWN) + { + if (provider.UsedLLMProvider is LLMProviders.NONE) + return false; + + return provider.UsedLLMProvider.GetConfidence(this).Level >= this.GetEffectiveMinimumConfidenceLevel(component, explicitMinimum); + } + + /// + /// Returns all providers that satisfy the minimum confidence level of the given component. + /// + /// The component for which the providers get filtered. + /// An explicit minimum level, which is applied when it is higher than the component's minimum. + /// All providers the component may use. + [SuppressMessage("Usage", "MWAIS0001:Direct access to `Providers` is not allowed")] + public IEnumerable GetConfidentProviders(Tools.Components component, ConfidenceLevel explicitMinimum = ConfidenceLevel.UNKNOWN) + { + var minimumLevel = this.GetEffectiveMinimumConfidenceLevel(component, explicitMinimum); + foreach (var provider in this.ConfigurationData.Providers) + if (provider.UsedLLMProvider is not LLMProviders.NONE && provider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel) + yield return provider; } public Profile GetPreselectedProfile(Tools.Components component)