mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-04 18:07:21 +00:00
Added a way for organizations to prohibit providers (#1105)
This commit is contained in:
1 parent
052868b24e
commit
7ba5f01388
38 files changed
+1488
-629
No files matched your search
@@ -1,5 +1,6 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Tools.PluginSystem;
|
||||
|
||||
namespace AIStudio.Settings.DataModel;
|
||||
@@ -192,6 +193,17 @@ public sealed class DataApp(Expression<Func<Data, DataApp>>? configSelection = n
|
||||
/// </summary>
|
||||
public bool AllowUserToAddTranscriptionProvider { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AllowUserToAddTranscriptionProvider, true);
|
||||
|
||||
/// <summary>
|
||||
/// The providers an organization prohibited, for LLMs, embeddings, and transcriptions alike.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A prohibition names the operator of an API, not a family of models: prohibiting the API of a
|
||||
/// model maker leaves its models reachable through a hub or a self-hosted server. Providers the
|
||||
/// user set up before stay in the settings, so they are back once the prohibition ends, but
|
||||
/// AI Studio neither offers nor contacts them, see SettingsManager.IsProviderProhibited.
|
||||
/// </remarks>
|
||||
public HashSet<LLMProviders> ProhibitedProviders { get; set; } = ManagedConfiguration.Register(configSelection, n => n.ProhibitedProviders, []);
|
||||
|
||||
/// <summary>
|
||||
/// Should the user be allowed to add mailboxes?
|
||||
/// </summary>
|
||||
|
||||
@@ -581,6 +581,14 @@ public static partial class ManagedConfiguration
|
||||
// Step 3 -- try to parse the string as the target type:
|
||||
if (EnumNames.TryParse(typeof(TValue), configuredLuaValueText, out var configuredEnum))
|
||||
set.Add((TValue)configuredEnum);
|
||||
|
||||
//
|
||||
// Dropped, but not quietly: such a set may prohibit something, and a typo would
|
||||
// otherwise leave it allowed without anybody noticing. A dry run comes before
|
||||
// the actual one, so only the actual one reports it:
|
||||
//
|
||||
else if (!dryRun)
|
||||
Log.LogWarning($"The configuration plugin '{configPluginId}' names '{configuredLuaValueText}' in the setting '{configMeta.SettingName}', which is no valid value. Ignoring it.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,7 @@ public static partial class ManagedConfiguration
|
||||
/// <summary>
|
||||
/// Determines the configuration plugin which currently manages a setting, if any.
|
||||
/// </summary>
|
||||
private static Guid GetSettingOwner(ConfigMetaBase configMeta)
|
||||
internal static Guid GetSettingOwner(ConfigMetaBase configMeta)
|
||||
{
|
||||
if (configMeta.IsLocked && configMeta.LockedByConfigPluginId != Guid.Empty)
|
||||
return configMeta.LockedByConfigPluginId;
|
||||
|
||||
@@ -585,7 +585,7 @@ public sealed class SettingsManager
|
||||
var minimumLevel = this.GetMinimumConfidenceLevel(component);
|
||||
|
||||
// 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 (this.ConfigurationData.Providers.Count == 1 && this.IsProviderUsable(this.ConfigurationData.Providers[0].UsedLLMProvider, minimumLevel))
|
||||
return this.ConfigurationData.Providers[0];
|
||||
|
||||
// Is there a current provider with a sufficiently high confidence level?
|
||||
@@ -593,14 +593,14 @@ public sealed class SettingsManager
|
||||
if (currentProviderId is not null && !string.IsNullOrWhiteSpace(currentProviderId))
|
||||
{
|
||||
var currentProviderProbe = this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == currentProviderId);
|
||||
if (currentProviderProbe is not null && currentProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
if (currentProviderProbe is not null && this.IsProviderUsable(currentProviderProbe.UsedLLMProvider, minimumLevel))
|
||||
currentProvider = currentProviderProbe;
|
||||
}
|
||||
|
||||
// Is there a component-preselected provider with a sufficiently high confidence level?
|
||||
var preselectedProvider = Provider.NONE;
|
||||
var preselectedProviderProbe = component.PreselectedProvider(this);
|
||||
if(preselectedProviderProbe != Provider.NONE && preselectedProviderProbe.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
if(preselectedProviderProbe != Provider.NONE && this.IsProviderUsable(preselectedProviderProbe.UsedLLMProvider, minimumLevel))
|
||||
preselectedProvider = preselectedProviderProbe;
|
||||
|
||||
//
|
||||
@@ -628,7 +628,7 @@ public sealed class SettingsManager
|
||||
return preselectedProvider;
|
||||
|
||||
// When there is an app-wide preselected provider, and it has a confidence level that is high enough, we return it:
|
||||
return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider && x.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel) ?? Provider.NONE;
|
||||
return this.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.ConfigurationData.App.PreselectedProvider && this.IsProviderUsable(x.UsedLLMProvider, minimumLevel)) ?? Provider.NONE;
|
||||
}
|
||||
|
||||
public Provider GetChatProviderForLoadedChat(string? chatProviderId = null)
|
||||
@@ -665,7 +665,7 @@ public sealed class SettingsManager
|
||||
bool IsSelectableProvider(Provider provider) =>
|
||||
provider != Provider.NONE
|
||||
&& provider.UsedLLMProvider != LLMProviders.NONE
|
||||
&& provider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel;
|
||||
&& this.IsProviderUsable(provider.UsedLLMProvider, minimumLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -684,7 +684,8 @@ public sealed class SettingsManager
|
||||
/// <para>
|
||||
/// 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.
|
||||
/// since they honor the confidence levels and leave out the providers the organization
|
||||
/// prohibited. This method returns those as well, so that the settings can mark them.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The returned list is a sorted copy of the provider list, ordered by the used LLM provider and
|
||||
@@ -706,9 +707,9 @@ public sealed class SettingsManager
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// provider even when the user enforces a higher global minimum or the organization prohibited
|
||||
/// it. Callers that intend to use the returned provider for an LLM request must check it
|
||||
/// themselves through IsProviderConfident or fall back to GetPreselectedProvider.
|
||||
/// </remarks>
|
||||
/// <param name="providerId">The id of the provider to look up.</param>
|
||||
/// <returns>The provider, or <see cref="Provider.NONE"/> when no provider with that id exists.</returns>
|
||||
@@ -741,6 +742,9 @@ public sealed class SettingsManager
|
||||
/// <summary>
|
||||
/// Checks whether the given provider satisfies the minimum confidence level of the given component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A provider the organization prohibited never does, see IsProviderUsable.
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider to check.</param>
|
||||
/// <param name="component">The component for which the provider gets checked.</param>
|
||||
/// <param name="explicitMinimum">An explicit minimum level, which is applied when it is higher than the component's minimum.</param>
|
||||
@@ -750,12 +754,51 @@ public sealed class SettingsManager
|
||||
if (provider.UsedLLMProvider is LLMProviders.NONE)
|
||||
return false;
|
||||
|
||||
return provider.UsedLLMProvider.GetConfidence(this).Level >= this.GetEffectiveMinimumConfidenceLevel(component, explicitMinimum);
|
||||
return this.IsProviderUsable(provider.UsedLLMProvider, this.GetEffectiveMinimumConfidenceLevel(component, explicitMinimum));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the organization prohibited the given provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A prohibition is a rule of its own, next to confidence and data-source security: no confidence
|
||||
/// level and no trust by configuration makes a prohibited provider usable. It also makes the provider
|
||||
/// untrusted, see GetConfiguredConfidenceLevel, but not the other way around. It names the operator
|
||||
/// of an API, so a hub or a self-hosted server which serves the same models stays allowed.
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider to check, for LLMs, embeddings, and transcriptions alike.</param>
|
||||
/// <returns>True, when the organization prohibited the provider. NONE is never prohibited.</returns>
|
||||
public bool IsProviderProhibited(LLMProviders provider) => provider is not LLMProviders.NONE && this.ConfigurationData.App.ProhibitedProviders.Contains(provider);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the given provider may be used where the given minimum confidence level applies.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The one check for every place which picks a provider: the organization did not prohibit it, and
|
||||
/// its confidence level reaches the minimum. A prohibited provider is untrusted, see
|
||||
/// GetConfiguredConfidenceLevel, but comparing the confidence level alone would still let it through
|
||||
/// wherever no minimum is enforced, since even untrusted reaches the minimum NONE.
|
||||
/// </remarks>
|
||||
/// <param name="provider">The provider to check, for LLMs, embeddings, and transcriptions alike.</param>
|
||||
/// <param name="minimumLevel">The minimum confidence level which applies.</param>
|
||||
/// <returns>True, when the provider may be used, false otherwise.</returns>
|
||||
public bool IsProviderUsable(LLMProviders provider, ConfidenceLevel minimumLevel) => !this.IsProviderProhibited(provider) && provider.GetConfidence(this).Level >= minimumLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the prohibited providers which have a level of their own in the custom confidence scheme.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The prohibition outranks these levels, see GetConfiguredConfidenceLevel.
|
||||
/// </remarks>
|
||||
/// <returns>The prohibited providers with a custom confidence level, in no particular order.</returns>
|
||||
public IEnumerable<LLMProviders> GetProhibitedProvidersWithCustomConfidenceLevel() => this.ConfigurationData.Confidence.CustomConfidenceScheme.Keys.Where(this.IsProviderProhibited);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all providers that satisfy the minimum confidence level of the given component.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The providers the organization prohibited are left out, see IsProviderUsable.
|
||||
/// </remarks>
|
||||
/// <param name="component">The component for which the providers get filtered.</param>
|
||||
/// <param name="explicitMinimum">An explicit minimum level, which is applied when it is higher than the component's minimum.</param>
|
||||
/// <returns>All providers the component may use, in the same order as GetAllProviders.</returns>
|
||||
@@ -763,7 +806,7 @@ public sealed class SettingsManager
|
||||
{
|
||||
var minimumLevel = this.GetEffectiveMinimumConfidenceLevel(component, explicitMinimum);
|
||||
foreach (var provider in this.GetAllProviders())
|
||||
if (provider.UsedLLMProvider is not LLMProviders.NONE && provider.UsedLLMProvider.GetConfidence(this).Level >= minimumLevel)
|
||||
if (provider.UsedLLMProvider is not LLMProviders.NONE && this.IsProviderUsable(provider.UsedLLMProvider, minimumLevel))
|
||||
yield return provider;
|
||||
}
|
||||
|
||||
@@ -1153,11 +1196,25 @@ public sealed class SettingsManager
|
||||
this.ConfigurationData.Tools.MinimumProviderConfidenceByToolId[settingsIds[0]] = confidenceLevel.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the confidence level of the given provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A prohibition by the organization comes first: a prohibited provider is always untrusted, no matter
|
||||
/// what the confidence scheme says, and no matter which level the user or a configuration plugin chose
|
||||
/// for it in the custom scheme. Those levels stay stored, so they apply again once the prohibition ends.
|
||||
/// After that, the confidence scheme decides, and in the custom scheme, the level chosen for the provider.
|
||||
/// </remarks>
|
||||
/// <param name="llmProvider">The provider, for LLMs, embeddings, and transcriptions alike.</param>
|
||||
/// <returns>The confidence level of the provider.</returns>
|
||||
public ConfidenceLevel GetConfiguredConfidenceLevel(LLMProviders llmProvider)
|
||||
{
|
||||
if(llmProvider is LLMProviders.NONE)
|
||||
return ConfidenceLevel.NONE;
|
||||
|
||||
|
||||
if (this.IsProviderProhibited(llmProvider))
|
||||
return ConfidenceLevel.UNTRUSTED;
|
||||
|
||||
switch (this.ConfigurationData.Confidence.ConfidenceScheme)
|
||||
{
|
||||
case ConfidenceSchemes.TRUST_ALL:
|
||||
|
||||
Reference in new issue
Block a user