mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-13 06:53:48 +00:00
Added settings & features for administrators in organizations (#653)
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
This commit is contained in:
1 parent
5af6a8db3e
commit
4cf62672de
38 files changed
+1330
-90
No files matched your search
@@ -93,9 +93,14 @@ 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>
|
||||
/// Should administration settings be visible in the UI?
|
||||
/// </summary>
|
||||
public bool ShowAdminSettings { get; set; } = ManagedConfiguration.Register(configSelection, n => n.ShowAdminSettings, false);
|
||||
|
||||
/// <summary>
|
||||
/// List of assistants that should be hidden from the UI.
|
||||
/// </summary>
|
||||
public HashSet<ConfigurableAssistant> HiddenAssistants { get; set; } = ManagedConfiguration.Register(configSelection, n => n.HiddenAssistants, []);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public sealed record EmbeddingProvider(
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public string SecretId => this.Id;
|
||||
public string SecretId => this.IsEnterpriseConfiguration ? $"{ISecretId.ENTERPRISE_KEY_PREFIX}::{this.UsedLLMProvider.ToName()}" : this.UsedLLMProvider.ToName();
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
@@ -110,6 +110,34 @@ public sealed record EmbeddingProvider(
|
||||
Host = host,
|
||||
};
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured embedding provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported.");
|
||||
else
|
||||
{
|
||||
var encryption = PluginFactory.EnterpriseEncryption;
|
||||
if (encryption?.IsAvailable == true)
|
||||
{
|
||||
if (encryption.TryDecrypt(apiKeyText, out var decryptedApiKey))
|
||||
{
|
||||
// Queue the API key for storage in the OS keyring:
|
||||
PendingEnterpriseApiKeys.Add(new(
|
||||
$"{ISecretId.ENTERPRISE_KEY_PREFIX}::{usedLLMProvider.ToName()}",
|
||||
name,
|
||||
decryptedApiKey,
|
||||
SecretStoreType.EMBEDDING_PROVIDER));
|
||||
LOGGER.LogDebug($"Successfully decrypted API key for embedding provider {idx}. It will be stored in the OS keyring.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"Failed to decrypt API key for embedding provider {idx}. The encryption secret may be incorrect.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"The configured embedding provider {idx} contains an encrypted API key, but no encryption secret is configured.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -131,4 +159,36 @@ public sealed record EmbeddingProvider(
|
||||
model = new(id, displayName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports the embedding provider configuration as a Lua configuration section.
|
||||
/// </summary>
|
||||
/// <param name="encryptedApiKey">Optional encrypted API key to include in the export.</param>
|
||||
/// <returns>A Lua configuration section string.</returns>
|
||||
public string ExportAsConfigurationSection(string? encryptedApiKey = null)
|
||||
{
|
||||
var apiKeyLine = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(encryptedApiKey))
|
||||
{
|
||||
apiKeyLine = $"""
|
||||
["APIKey"] = "{LuaTools.EscapeLuaString(encryptedApiKey)}",
|
||||
""";
|
||||
}
|
||||
|
||||
return $$"""
|
||||
CONFIG["EMBEDDING_PROVIDERS"][#CONFIG["EMBEDDING_PROVIDERS"]+1] = {
|
||||
["Id"] = "{{Guid.NewGuid().ToString()}}",
|
||||
["Name"] = "{{LuaTools.EscapeLuaString(this.Name)}}",
|
||||
["UsedLLMProvider"] = "{{this.UsedLLMProvider}}",
|
||||
|
||||
["Host"] = "{{this.Host}}",
|
||||
["Hostname"] = "{{LuaTools.EscapeLuaString(this.Hostname)}}",
|
||||
{{apiKeyLine}}
|
||||
["Model"] = {
|
||||
["Id"] = "{{LuaTools.EscapeLuaString(this.Model.Id)}}",
|
||||
["DisplayName"] = "{{LuaTools.EscapeLuaString(this.Model.DisplayName ?? string.Empty)}}",
|
||||
},
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public sealed record Provider(
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public string SecretId => this.Id;
|
||||
public string SecretId => this.IsEnterpriseConfiguration ? $"{ISecretId.ENTERPRISE_KEY_PREFIX}::{this.UsedLLMProvider.ToName()}" : this.UsedLLMProvider.ToName();
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
@@ -121,6 +121,16 @@ public sealed record Provider(
|
||||
LOGGER.LogWarning($"The configured provider {idx} does not contain a valid hostname.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var hfInferenceProvider = HFInferenceProvider.NONE;
|
||||
if (table.TryGetValue("HFInferenceProvider", out var hfInferenceProviderValue) && hfInferenceProviderValue.TryRead<string>(out var hfInferenceProviderText))
|
||||
{
|
||||
if (!Enum.TryParse(hfInferenceProviderText, true, out hfInferenceProvider))
|
||||
{
|
||||
LOGGER.LogWarning($"The configured provider {idx} does not contain a valid Hugging Face inference provider enum value.");
|
||||
hfInferenceProvider = HFInferenceProvider.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!table.TryGetValue("Model", out var modelValue) || !modelValue.TryRead<LuaTable>(out var modelTable))
|
||||
{
|
||||
@@ -153,9 +163,38 @@ public sealed record Provider(
|
||||
EnterpriseConfigurationPluginId = configPluginId,
|
||||
Hostname = hostname,
|
||||
Host = host,
|
||||
HFInferenceProvider = hfInferenceProvider,
|
||||
AdditionalJsonApiParameters = additionalJsonApiParameters,
|
||||
};
|
||||
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported.");
|
||||
else
|
||||
{
|
||||
var encryption = PluginFactory.EnterpriseEncryption;
|
||||
if (encryption?.IsAvailable == true)
|
||||
{
|
||||
if (encryption.TryDecrypt(apiKeyText, out var decryptedApiKey))
|
||||
{
|
||||
// Queue the API key for storage in the OS keyring:
|
||||
PendingEnterpriseApiKeys.Add(new(
|
||||
$"{ISecretId.ENTERPRISE_KEY_PREFIX}::{usedLLMProvider.ToName()}",
|
||||
instanceName,
|
||||
decryptedApiKey,
|
||||
SecretStoreType.LLM_PROVIDER));
|
||||
LOGGER.LogDebug($"Successfully decrypted API key for provider {idx}. It will be stored in the OS keyring.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"Failed to decrypt API key for provider {idx}. The encryption secret may be incorrect.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"The configured provider {idx} contains an encrypted API key, but no encryption secret is configured.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -177,4 +216,46 @@ public sealed record Provider(
|
||||
model = new(id, displayName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports the provider configuration as a Lua configuration section.
|
||||
/// </summary>
|
||||
/// <param name="encryptedApiKey">Optional encrypted API key to include in the export.</param>
|
||||
/// <returns>A Lua configuration section string.</returns>
|
||||
public string ExportAsConfigurationSection(string? encryptedApiKey = null)
|
||||
{
|
||||
var hfInferenceProviderLine = string.Empty;
|
||||
if (this.HFInferenceProvider is not HFInferenceProvider.NONE)
|
||||
{
|
||||
hfInferenceProviderLine = $"""
|
||||
["HFInferenceProvider"] = "{this.HFInferenceProvider}",
|
||||
""";
|
||||
}
|
||||
|
||||
var apiKeyLine = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(encryptedApiKey))
|
||||
{
|
||||
apiKeyLine = $"""
|
||||
["APIKey"] = "{LuaTools.EscapeLuaString(encryptedApiKey)}",
|
||||
""";
|
||||
}
|
||||
|
||||
return $$"""
|
||||
CONFIG["LLM_PROVIDERS"][#CONFIG["LLM_PROVIDERS"]+1] = {
|
||||
["Id"] = "{{Guid.NewGuid().ToString()}}",
|
||||
["InstanceName"] = "{{LuaTools.EscapeLuaString(this.InstanceName)}}",
|
||||
["UsedLLMProvider"] = "{{this.UsedLLMProvider}}",
|
||||
|
||||
["Host"] = "{{this.Host}}",
|
||||
["Hostname"] = "{{LuaTools.EscapeLuaString(this.Hostname)}}",
|
||||
{{hfInferenceProviderLine}}
|
||||
{{apiKeyLine}}
|
||||
["AdditionalJsonApiParameters"] = "{{LuaTools.EscapeLuaString(this.AdditionalJsonApiParameters)}}",
|
||||
["Model"] = {
|
||||
["Id"] = "{{LuaTools.EscapeLuaString(this.Model.Id)}}",
|
||||
["DisplayName"] = "{{LuaTools.EscapeLuaString(this.Model.DisplayName ?? string.Empty)}}",
|
||||
},
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public sealed record TranscriptionProvider(
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
public string SecretId => this.Id;
|
||||
public string SecretId => this.IsEnterpriseConfiguration ? $"{ISecretId.ENTERPRISE_KEY_PREFIX}::{this.UsedLLMProvider.ToName()}" : this.UsedLLMProvider.ToName();
|
||||
|
||||
/// <inheritdoc />
|
||||
[JsonIgnore]
|
||||
@@ -110,6 +110,34 @@ public sealed record TranscriptionProvider(
|
||||
Host = host,
|
||||
};
|
||||
|
||||
// Handle encrypted API key if present:
|
||||
if (table.TryGetValue("APIKey", out var apiKeyValue) && apiKeyValue.TryRead<string>(out var apiKeyText) && !string.IsNullOrWhiteSpace(apiKeyText))
|
||||
{
|
||||
if (!EnterpriseEncryption.IsEncrypted(apiKeyText))
|
||||
LOGGER.LogWarning($"The configured transcription provider {idx} contains a plaintext API key. Only encrypted API keys (starting with 'ENC:v1:') are supported.");
|
||||
else
|
||||
{
|
||||
var encryption = PluginFactory.EnterpriseEncryption;
|
||||
if (encryption?.IsAvailable == true)
|
||||
{
|
||||
if (encryption.TryDecrypt(apiKeyText, out var decryptedApiKey))
|
||||
{
|
||||
// Queue the API key for storage in the OS keyring:
|
||||
PendingEnterpriseApiKeys.Add(new(
|
||||
$"{ISecretId.ENTERPRISE_KEY_PREFIX}::{usedLLMProvider.ToName()}",
|
||||
name,
|
||||
decryptedApiKey,
|
||||
SecretStoreType.TRANSCRIPTION_PROVIDER));
|
||||
LOGGER.LogDebug($"Successfully decrypted API key for transcription provider {idx}. It will be stored in the OS keyring.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"Failed to decrypt API key for transcription provider {idx}. The encryption secret may be incorrect.");
|
||||
}
|
||||
else
|
||||
LOGGER.LogWarning($"The configured transcription provider {idx} contains an encrypted API key, but no encryption secret is configured.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -131,4 +159,36 @@ public sealed record TranscriptionProvider(
|
||||
model = new(id, displayName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports the transcription provider configuration as a Lua configuration section.
|
||||
/// </summary>
|
||||
/// <param name="encryptedApiKey">Optional encrypted API key to include in the export.</param>
|
||||
/// <returns>A Lua configuration section string.</returns>
|
||||
public string ExportAsConfigurationSection(string? encryptedApiKey = null)
|
||||
{
|
||||
var apiKeyLine = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(encryptedApiKey))
|
||||
{
|
||||
apiKeyLine = $"""
|
||||
["APIKey"] = "{LuaTools.EscapeLuaString(encryptedApiKey)}",
|
||||
""";
|
||||
}
|
||||
|
||||
return $$"""
|
||||
CONFIG["TRANSCRIPTION_PROVIDERS"][#CONFIG["TRANSCRIPTION_PROVIDERS"]+1] = {
|
||||
["Id"] = "{{Guid.NewGuid().ToString()}}",
|
||||
["Name"] = "{{LuaTools.EscapeLuaString(this.Name)}}",
|
||||
["UsedLLMProvider"] = "{{this.UsedLLMProvider}}",
|
||||
|
||||
["Host"] = "{{this.Host}}",
|
||||
["Hostname"] = "{{LuaTools.EscapeLuaString(this.Hostname)}}",
|
||||
{{apiKeyLine}}
|
||||
["Model"] = {
|
||||
["Id"] = "{{LuaTools.EscapeLuaString(this.Model.Id)}}",
|
||||
["DisplayName"] = "{{LuaTools.EscapeLuaString(this.Model.DisplayName ?? string.Empty)}}",
|
||||
},
|
||||
}
|
||||
""";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user