Skip to content

Commit e8cfce0

Browse files
Add enterprise config support via env vars & Windows registry (#491)
1 parent b88b78a commit e8cfce0

33 files changed

+1060
-97
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ Things we are currently working on:
3131
- [x] ~~Plan & implement the base plugin system ([PR #322](https://github.com/MindWorkAI/AI-Studio/pull/322))~~
3232
- [x] ~~Start the plugin system ([PR #372](https://github.com/MindWorkAI/AI-Studio/pull/372))~~
3333
- [x] ~~Added hot-reload support for plugins ([PR #377](https://github.com/MindWorkAI/AI-Studio/pull/377), [PR #391](https://github.com/MindWorkAI/AI-Studio/pull/391))~~
34-
- [x] Add support for other languages (I18N) to AI Studio (~~[PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
34+
- [x] ~~Add support for other languages (I18N) to AI Studio ([PR #381](https://github.com/MindWorkAI/AI-Studio/pull/381), [PR #400](https://github.com/MindWorkAI/AI-Studio/pull/400), [PR #404](https://github.com/MindWorkAI/AI-Studio/pull/404), [PR #429](https://github.com/MindWorkAI/AI-Studio/pull/429), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486))~~
3535
- [x] ~~Add an I18N assistant to translate all AI Studio texts to a certain language & culture ([PR #422](https://github.com/MindWorkAI/AI-Studio/pull/422))~~
36-
- [x] Provide MindWork AI Studio in German (~~[PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486)~~)
37-
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations
36+
- [x] ~~Provide MindWork AI Studio in German ([PR #430](https://github.com/MindWorkAI/AI-Studio/pull/430), [PR #446](https://github.com/MindWorkAI/AI-Studio/pull/446), [PR #451](https://github.com/MindWorkAI/AI-Studio/pull/451), [PR #455](https://github.com/MindWorkAI/AI-Studio/pull/455), [PR #458](https://github.com/MindWorkAI/AI-Studio/pull/458), [PR #462](https://github.com/MindWorkAI/AI-Studio/pull/462), [PR #469](https://github.com/MindWorkAI/AI-Studio/pull/469), [PR #486](https://github.com/MindWorkAI/AI-Studio/pull/486)~~)
37+
- [ ] Add configuration plugins, which allow pre-defining some LLM providers in organizations (~~[PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491)~~)
3838
- [ ] Add an app store for plugins, showcasing community-contributed plugins from public GitHub and GitLab repositories. This will enable AI Studio users to discover, install, and update plugins directly within the platform.
3939
- [ ] Add assistant plugins
4040

app/MindWork AI Studio/Assistants/I18N/allTexts.lua

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,6 +1972,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T331371
19721972
-- Add LLM Provider
19731973
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T3346433704"] = "Add LLM Provider"
19741974

1975+
-- This provider is managed by your organization.
1976+
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T3415927576"] = "This provider is managed by your organization."
1977+
19751978
-- LLM Provider
19761979
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::SETTINGS::SETTINGSPANELPROVIDERS::T3612415205"] = "LLM Provider"
19771980

@@ -4153,12 +4156,21 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1020427799"] = "About MindWork AI Stud
41534156
-- Browse AI Studio's source code on GitHub — we welcome your contributions.
41544157
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1107156991"] = "Browse AI Studio's source code on GitHub — we welcome your contributions."
41554158

4159+
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available.
4160+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1297057566"] = "AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available."
4161+
41564162
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
41574163
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat."
41584164

41594165
-- This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library.
41604166
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1421513382"] = "This library is used to extend the MudBlazor library. It provides additional components that are not part of the MudBlazor library."
41614167

4168+
-- AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active.
4169+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1454889560"] = "AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active."
4170+
4171+
-- AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management.
4172+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1530477579"] = "AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management."
4173+
41624174
-- We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library.
41634175
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T162898512"] = "We use Lua as the language for plugins. Lua-CSharp lets Lua scripts communicate with AI Studio and vice versa. Thank you, Yusuke Nakada, for this great library."
41644176

@@ -4183,6 +4195,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1890416390"] = "Check for updates"
41834195
-- Vision
41844196
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1892426825"] = "Vision"
41854197

4198+
-- In order to use any LLM, each user must store their so-called API key for each LLM provider. This key must be kept secure, similar to a password. The safest way to do this is offered by operating systems like macOS, Windows, and Linux: They have mechanisms to store such data, if available, on special security hardware. Since this is currently not possible in .NET, we use this Rust library.
4199+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1915240766"] = "In order to use any LLM, each user must store their so-called API key for each LLM provider. This key must be kept secure, similar to a password. The safest way to do this is offered by operating systems like macOS, Windows, and Linux: They have mechanisms to store such data, if available, on special security hardware. Since this is currently not possible in .NET, we use this Rust library."
4200+
41864201
-- This library is used to convert HTML to Markdown. This is necessary, e.g., when you provide a URL as input for an assistant.
41874202
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T1924365263"] = "This library is used to convert HTML to Markdown. This is necessary, e.g., when you provide a URL as input for an assistant."
41884203

@@ -4195,15 +4210,15 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "This library is used t
41954210
-- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.
41964211
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose."
41974212

4213+
-- AI Studio runs without an enterprise configuration.
4214+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio runs without an enterprise configuration."
4215+
41984216
-- OK
41994217
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
42004218

42014219
-- We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.
42024220
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2273492381"] = "We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose."
42034221

4204-
-- In order to use any LLM, each user must store their so-called token for each LLM provider. This token must be kept secure, similar to a password. The safest way to do this is offered by operating systems like macOS, Windows, and Linux: They have mechanisms to store such data, if available, on special security hardware. Since this is currently not possible in .NET, we use this Rust library.
4205-
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T228561878"] = "In order to use any LLM, each user must store their so-called token for each LLM provider. This token must be kept secure, similar to a password. The safest way to do this is offered by operating systems like macOS, Windows, and Linux: They have mechanisms to store such data, if available, on special security hardware. Since this is currently not possible in .NET, we use this Rust library."
4206-
42074222
-- The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK.
42084223
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2329884315"] = "The C# language is used for the implementation of the user interface and the backend. To implement the user interface with C#, the Blazor technology from ASP.NET Core is used. All these technologies are integrated into the .NET SDK."
42094224

@@ -4291,6 +4306,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3722989559"] = "This library is used t
42914306
-- this version does not met the requirements
42924307
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3813932670"] = "this version does not met the requirements"
42934308

4309+
-- This library is used to access the Windows registry. We use this for Windows enterprise environments to read the desired configuration.
4310+
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3874337003"] = "This library is used to access the Windows registry. We use this for Windows enterprise environments to read the desired configuration."
4311+
42944312
-- Now we have multiple systems, some developed in .NET and others in Rust. The data format JSON is responsible for translating data between both worlds (called data serialization and deserialization). Serde takes on this task in the Rust world. The counterpart in the .NET world is an integral part of .NET and is located in System.Text.Json.
42954313
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T3908558992"] = "Now we have multiple systems, some developed in .NET and others in Rust. The data format JSON is responsible for translating data between both worlds (called data serialization and deserialization). Serde takes on this task in the Rust world. The counterpart in the .NET world is an integral part of .NET and is located in System.Text.Json."
42964314

@@ -5359,6 +5377,15 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCATEGORYEXTENSIONS::T90450
53595377
-- Content Creation
53605378
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCATEGORYEXTENSIONS::T914642375"] = "Content Creation"
53615379

5380+
-- The SETTINGS table does not exist or is not a valid table.
5381+
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T1148682011"] = "The SETTINGS table does not exist or is not a valid table."
5382+
5383+
-- The CONFIG table does not exist or is not a valid table.
5384+
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T3331620576"] = "The CONFIG table does not exist or is not a valid table."
5385+
5386+
-- The LLM_PROVIDERS table does not exist or is not a valid table.
5387+
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINCONFIGURATION::T806592324"] = "The LLM_PROVIDERS table does not exist or is not a valid table."
5388+
53625389
-- The field IETF_TAG does not exist or is not a valid string.
53635390
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::PLUGINLANGUAGE::T1796010240"] = "The field IETF_TAG does not exist or is not a valid string."
53645391

app/MindWork AI Studio/Components/Settings/SettingsPanelApp.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<ConfigurationSelect OptionDescription="@T("Color theme")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreferredTheme)" Data="@ConfigurationSelectDataFactory.GetThemesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.PreferredTheme = selectedValue)" OptionHelp="@T("Choose the color theme that best suits for you.")"/>
1414
<ConfigurationOption OptionDescription="@T("Save energy?")" LabelOn="@T("Energy saving is enabled")" LabelOff="@T("Energy saving is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.IsSavingEnergy = updatedState)" OptionHelp="@T("When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available.")"/>
1515
<ConfigurationOption OptionDescription="@T("Enable spellchecking?")" LabelOn="@T("Spellchecking is enabled")" LabelOff="@T("Spellchecking is disabled")" State="@(() => this.SettingsManager.ConfigurationData.App.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.App.EnableSpellchecking = updatedState)" OptionHelp="@T("When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections.")"/>
16-
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")"/>
16+
<ConfigurationSelect OptionDescription="@T("Check for updates")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.UpdateBehavior = selectedValue)" OptionHelp="@T("How often should we check for app updates?")" Disabled="() => this.SettingsLocker.IsLocked<DataApp>(x => x.UpdateBehavior)"/>
1717
<ConfigurationSelect OptionDescription="@T("Navigation bar behavior")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.App.NavigationBehavior = selectedValue)" OptionHelp="@T("Select the desired behavior for the navigation bar.")"/>
1818
<ConfigurationSelect OptionDescription="@T("Preview feature visibility")" SelectedValue="@(() => this.SettingsManager.ConfigurationData.App.PreviewVisibility)" Data="@ConfigurationSelectDataFactory.GetPreviewVisibility()" SelectionUpdate="@this.UpdatePreviewFeatures" OptionHelp="@T("Do you want to show preview features in the app?")"/>
1919

app/MindWork AI Studio/Components/Settings/SettingsPanelBase.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ public abstract class SettingsPanelBase : MSGComponentBase
1515

1616
[Inject]
1717
protected RustService RustService { get; init; } = null!;
18+
19+
[Inject]
20+
protected SettingsLocker SettingsLocker { get; init; } = null!;
1821
}

app/MindWork AI Studio/Components/Settings/SettingsPanelProviders.razor

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,24 @@
4545
</MudTd>
4646
<MudTd>
4747
<MudStack Row="true" Class="mb-2 mt-2" Spacing="1" Wrap="Wrap.Wrap">
48-
<MudTooltip Text="@T("Open Dashboard")">
49-
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())"/>
50-
</MudTooltip>
51-
<MudTooltip Text="@T("Edit")">
52-
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditLLMProvider(context)"/>
53-
</MudTooltip>
54-
<MudTooltip Text="@T("Delete")">
55-
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteLLMProvider(context)"/>
56-
</MudTooltip>
48+
@if (context.IsEnterpriseConfiguration)
49+
{
50+
<MudTooltip Text="@T("This provider is managed by your organization.")">
51+
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Business" Disabled="true"/>
52+
</MudTooltip>
53+
}
54+
else
55+
{
56+
<MudTooltip Text="@T("Open Dashboard")">
57+
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.OpenInBrowser" Href="@context.UsedLLMProvider.GetDashboardURL()" Target="_blank" Disabled="@(!context.UsedLLMProvider.HasDashboard())"/>
58+
</MudTooltip>
59+
<MudTooltip Text="@T("Edit")">
60+
<MudIconButton Color="Color.Info" Icon="@Icons.Material.Filled.Edit" OnClick="() => this.EditLLMProvider(context)"/>
61+
</MudTooltip>
62+
<MudTooltip Text="@T("Delete")">
63+
<MudIconButton Color="Color.Error" Icon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteLLMProvider(context)"/>
64+
</MudTooltip>
65+
}
5766
</MudStack>
5867
</MudTd>
5968
</RowTemplate>

app/MindWork AI Studio/Dialogs/ProviderDialog.razor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ private AIStudio.Settings.Provider CreateProviderSettings()
133133
_ => this.DataModel
134134
},
135135
IsSelfHosted = this.DataLLMProvider is LLMProviders.SELF_HOSTED,
136+
IsEnterpriseConfiguration = false,
136137
Hostname = cleanedHostname.EndsWith('/') ? cleanedHostname[..^1] : cleanedHostname,
137138
Host = this.DataHost,
138139
HFInferenceProvider = this.HFInferenceProviderId,

0 commit comments

Comments
 (0)