mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-07-04 04:02:56 +00:00
Improved enterprise IT (#497)
This commit is contained in:
parent
7a498d524e
commit
32e1ab977d
@ -34,7 +34,7 @@ Things we are currently working on:
|
||||
- [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))~~
|
||||
- [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))~~
|
||||
- [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))~~
|
||||
- [x] ~~Add configuration plugins, which allow pre-defining some LLM providers in organizations ([PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491), [PR #493](https://github.com/MindWorkAI/AI-Studio/pull/493), [PR #494](https://github.com/MindWorkAI/AI-Studio/pull/494))~~
|
||||
- [x] ~~Add configuration plugins, which allow pre-defining some LLM providers in organizations ([PR #491](https://github.com/MindWorkAI/AI-Studio/pull/491), [PR #493](https://github.com/MindWorkAI/AI-Studio/pull/493), [PR #494](https://github.com/MindWorkAI/AI-Studio/pull/494), [PR #497](https://github.com/MindWorkAI/AI-Studio/pull/497))~~
|
||||
- [ ] 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.
|
||||
- [ ] Add assistant plugins
|
||||
|
||||
@ -123,6 +123,9 @@ Stay tuned for more updates and enhancements to make MindWork AI Studio even mor
|
||||
## Building
|
||||
You want to know how to build MindWork AI Studio from source? [Check out the instructions here](documentation/Build.md).
|
||||
|
||||
## Enterprise IT
|
||||
Do you want to manage AI Studio centrally from your IT department? Yes, that’s possible. [Here’s how it works.](documentation/Enterprise%20IT.md)
|
||||
|
||||
## License
|
||||
MindWork AI Studio is licensed under the `FSL-1.1-MIT` license (functional source license). Here’s a simple rundown of what that means for you:
|
||||
- **Permitted Use**: Feel free to use, copy, modify, and share the software for your own projects, educational purposes, research, or even in professional services. The key is to use it in a way that doesn't compete with our offerings.
|
||||
|
@ -1129,7 +1129,7 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3032662264"] = "Benutzerdefinierte Sprache"
|
||||
|
||||
-- Your input to improve
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Vorschlag zur Verbesserung"
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3037449423"] = "Ihr Text, der verbessert werden soll"
|
||||
|
||||
-- Writing style
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::REWRITEIMPROVE::ASSISTANTREWRITEIMPROVE::T3754048862"] = "Schreibstil"
|
||||
@ -4213,7 +4213,7 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "Diese Bibliothek wird
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2174764529"] = "Für die sichere Kommunikation zwischen der Benutzeroberfläche und der Laufzeit müssen wir Zertifikate erstellen. Diese Rust-Bibliothek eignet sich hervorragend dafür."
|
||||
|
||||
-- AI Studio runs without an enterprise configuration.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio läuft ohne eine Konfiguration ihrer Organisation."
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "Dies ist eine private AI Studio-Installation. Es wird keine Konfiguration einer Organisation verwendet."
|
||||
|
||||
-- OK
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
|
||||
|
@ -4213,7 +4213,7 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2173617769"] = "This library is used t
|
||||
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."
|
||||
|
||||
-- AI Studio runs without an enterprise configuration.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "AI Studio runs without an enterprise configuration."
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2244723851"] = "This is a private AI Studio installation. It runs without an enterprise configuration."
|
||||
|
||||
-- OK
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::ABOUT::T2246359087"] = "OK"
|
||||
|
@ -42,6 +42,7 @@ public static partial class PluginFactory
|
||||
var tempDownloadFile = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
await LockHotReloadAsync();
|
||||
using var httpClient = new HttpClient();
|
||||
var response = await httpClient.GetAsync(downloadUrl, cancellationToken);
|
||||
if (response.IsSuccessStatusCode)
|
||||
@ -80,6 +81,8 @@ public static partial class PluginFactory
|
||||
LOG.LogError(e, "Failed to delete the temporary download file.");
|
||||
}
|
||||
}
|
||||
|
||||
UnlockHotReload();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -46,12 +46,41 @@ public static partial class PluginFactory
|
||||
try
|
||||
{
|
||||
LOG.LogInformation($"File changed ({changeType}): {args.FullPath}. Reloading plugins...");
|
||||
if (File.Exists(HOT_RELOAD_LOCK_FILE))
|
||||
{
|
||||
LOG.LogInformation("Hot reload lock file exists. Waiting for it to be released before proceeding with the reload.");
|
||||
|
||||
var lockFileCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
var token = lockFileCancellationTokenSource.Token;
|
||||
var waitTime = TimeSpan.FromSeconds(1);
|
||||
while (File.Exists(HOT_RELOAD_LOCK_FILE) && !token.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
LOG.LogDebug("Waiting for hot reload lock to be released...");
|
||||
await Task.Delay(waitTime, token);
|
||||
waitTime = TimeSpan.FromSeconds(Math.Min(waitTime.TotalSeconds * 2, 120)); // Exponential backoff with a cap
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// Case: The cancellation token was triggered, meaning the lock file is still present.
|
||||
// We expect that something goes wrong. So, we try to delete the lock file:
|
||||
LOG.LogWarning("Hot reload lock file still exists after 30 seconds. Attempting to delete it...");
|
||||
UnlockHotReload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOG.LogInformation("Hot reload lock file released. Proceeding with plugin reload.");
|
||||
}
|
||||
|
||||
// Wait for parallel writes to finish:
|
||||
await Task.Delay(TimeSpan.FromSeconds(3));
|
||||
await LoadAll();
|
||||
await MessageBus.INSTANCE.SendMessage<bool>(null, Event.PLUGINS_RELOADED);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.LogError(e, $"Error while reloading plugins after change in file '{args.FullPath}' with change type '{changeType}'.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
HOT_RELOAD_SEMAPHORE.Release();
|
||||
|
@ -13,6 +13,7 @@ public static partial class PluginFactory
|
||||
private static string PLUGINS_ROOT = string.Empty;
|
||||
private static string INTERNAL_PLUGINS_ROOT = string.Empty;
|
||||
private static string CONFIGURATION_PLUGINS_ROOT = string.Empty;
|
||||
private static string HOT_RELOAD_LOCK_FILE = string.Empty;
|
||||
private static FileSystemWatcher HOT_RELOAD_WATCHER = null!;
|
||||
private static ILanguagePlugin BASE_LANGUAGE_PLUGIN = NoPluginLanguage.INSTANCE;
|
||||
|
||||
@ -30,6 +31,7 @@ public static partial class PluginFactory
|
||||
LOG.LogInformation("Initializing plugin factory...");
|
||||
DATA_DIR = SettingsManager.DataDirectory!;
|
||||
PLUGINS_ROOT = Path.Join(DATA_DIR, "plugins");
|
||||
HOT_RELOAD_LOCK_FILE = Path.Join(PLUGINS_ROOT, ".lock");
|
||||
INTERNAL_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".internal");
|
||||
CONFIGURATION_PLUGINS_ROOT = Path.Join(PLUGINS_ROOT, ".config");
|
||||
|
||||
@ -42,6 +44,51 @@ public static partial class PluginFactory
|
||||
return true;
|
||||
}
|
||||
|
||||
private static async Task LockHotReloadAsync()
|
||||
{
|
||||
if (!IS_INITIALIZED)
|
||||
{
|
||||
LOG.LogError("PluginFactory is not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(HOT_RELOAD_LOCK_FILE))
|
||||
{
|
||||
LOG.LogWarning("Hot reload lock file already exists.");
|
||||
return;
|
||||
}
|
||||
|
||||
await File.WriteAllTextAsync(HOT_RELOAD_LOCK_FILE, DateTime.UtcNow.ToString("o"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.LogError(e, "An error occurred while trying to lock hot reloading.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnlockHotReload()
|
||||
{
|
||||
if (!IS_INITIALIZED)
|
||||
{
|
||||
LOG.LogError("PluginFactory is not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if(File.Exists(HOT_RELOAD_LOCK_FILE))
|
||||
File.Delete(HOT_RELOAD_LOCK_FILE);
|
||||
else
|
||||
LOG.LogWarning("Hot reload lock file does not exist. Nothing to unlock.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.LogError(e, "An error occurred while trying to unlock hot reloading.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
if(!IS_INITIALIZED)
|
||||
|
@ -1 +1,3 @@
|
||||
# v0.9.48, build 223 (2025-06-xx xx:xx UTC)
|
||||
- Improved German translation.
|
||||
- Improved how configurations are applied in organizations and made the process more robust.
|
95
documentation/Enterprise IT.md
Normal file
95
documentation/Enterprise IT.md
Normal file
@ -0,0 +1,95 @@
|
||||
# Enterprise IT
|
||||
|
||||
## Overview
|
||||
Do you want to manage MindWork AI Studio in a corporate environment or within an organization? This documentation explains what you need to do and how it works. First, here's an overview of the entire process:
|
||||
|
||||
- You can distribute MindWork AI Studio to employees' devices using tools like Microsoft System Center Configuration Manager (SCCM).
|
||||
- Employees can get updates through the built-in update feature. If you want, you can disable automatic updates and control which version gets distributed.
|
||||
- AI Studio checks about every 16 minutes to see where and which configuration it should load. This information is loaded from the local system. On Windows, you might use the registry, for example.
|
||||
- If it finds the necessary metadata, AI Studio downloads the configuration as a ZIP file from the specified server.
|
||||
- The configuration is an AI Studio plugin written in Lua.
|
||||
- Any changes to the configuration apply live while the software is running, so employees don’t need to restart it.
|
||||
|
||||
AI Studio checks about every 16 minutes to see if the configuration ID, the server for the configuration, or the configuration itself has changed. If it finds any changes, it loads the updated configuration from the server and applies it right away.
|
||||
|
||||
## Configure the devices
|
||||
So that MindWork AI Studio knows where to load which configuration, this information must be provided as metadata on employees’ devices. Currently, the following options are available:
|
||||
|
||||
- **Registry** (only available for Microsoft Windows): On Windows devices, AI Studio first tries to read the information from the registry. The registry information can be managed and distributed centrally as a so-called Group Policy Object (GPO).
|
||||
|
||||
- **Environment variables**: On all operating systems (on Windows as a fallback after the registry), AI Studio tries to read the configuration metadata from environment variables.
|
||||
|
||||
The following keys and values (registry) and variables are checked and read:
|
||||
|
||||
- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_id` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID`: This must be a valid [GUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Globally_unique_identifier). It uniquely identifies the configuration. You can use an ID per department, institute, or even per person.
|
||||
|
||||
- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `delete_config_id` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_DELETE_CONFIG_ID`: This is a configuration ID that should be removed. This is helpful if an employee moves to a different department or leaves the organization.
|
||||
|
||||
- Key `HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT`, value `config_server_url` or variable `MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL`: An HTTP or HTTPS address using an IP address or DNS name. This is the web server from which AI Studio attempts to load the specified configuration as a ZIP file.
|
||||
|
||||
Let's assume as example that `https://intranet.my-company.com:30100/ai-studio/configuration` is the server address and `9072b77d-ca81-40da-be6a-861da525ef7b` is the configuration ID. AI Studio will derive the following address from this information: `https://intranet.my-company.com:30100/ai-studio/configuration/9072b77d-ca81-40da-be6a-861da525ef7b.zip`. Important: The configuration ID will always be written in lowercase, even if it is configured in uppercase. If `9072B77D-CA81-40DA-BE6A-861DA525EF7B` is configured, the same address will be derived. Your web server must be configured accordingly.
|
||||
|
||||
Finally, AI Studio will send a GET request and download the ZIP file. The ZIP file only contains the files necessary for the configuration. It's normal to include a file for an icon along with the actual configuration plugin.
|
||||
|
||||
Approximately every 16 minutes, AI Studio checks the metadata of the ZIP file by reading the [ETag](https://en.wikipedia.org/wiki/HTTP_ETag). When the ETag was not changed, no download will be performed. Make sure that your web server supports this.
|
||||
|
||||
## Configure the configuration web server
|
||||
|
||||
In principle, you can use any web server that can serve ZIP files from a folder. However, keep in mind that AI Studio queries the file's metadata using [ETag](https://en.wikipedia.org/wiki/HTTP_ETag). Your web server must support this feature. For security reasons, you should also make sure that users cannot list the contents of the directory. This is important because the different configurations may contain confidential information such as API keys. Each user should only know their own configuration ID. Otherwise, a user might try to use someone else’s ID to gain access to exclusive resources.
|
||||
|
||||
The ZIP file names for the configurations must be in lowercase on the server, or your web server needs to ignore the spelling in requests. Also, make sure the web server is only accessible within your organization’s intranet. You don’t want the server open to everyone worldwide.
|
||||
|
||||
You can use the open source web server [Caddy](https://caddyserver.com/). The project is openly developed on [GitHub](https://github.com/caddyserver/caddy). Below you’ll find an example configuration, a so-called `Caddyfile`, for serving configurations from the folder `/localdata1/ai-studio/config` to AI Studio. The TLS certificates are loaded from the folder `/localdata1/tls-certificate`.
|
||||
|
||||
```
|
||||
{
|
||||
# Disable logging:
|
||||
log {
|
||||
output discard
|
||||
}
|
||||
|
||||
# Disable automatic HTTPS redirection:
|
||||
auto_https off
|
||||
}
|
||||
|
||||
intranet.my-company.com:30100 {
|
||||
# Load TLS certificates:
|
||||
tls /localdata1/tls-certificate/cert_webserver.pem /localdata1/tls-certificate/key_webserver.pem
|
||||
|
||||
# Serve the configuration files:
|
||||
handle_path /ai-studio/configuration/* {
|
||||
file_server {
|
||||
root /localdata1/ai-studio/config
|
||||
|
||||
# Disable directory browsing:
|
||||
browse false
|
||||
}
|
||||
}
|
||||
|
||||
# All other requests will receive a 404 Not Found response:
|
||||
handle {
|
||||
respond "Not Found" 404
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example AI Studio configuration
|
||||
The latest example of an AI Studio configuration via configuration plugin can always be found in the repository in the `app/MindWork AI Studio/Plugins/configuration` folder. Here are the links to the files:
|
||||
|
||||
- [The icon](../app/MindWork%20AI%20Studio/Plugins/configuration/icon.lua)
|
||||
- [The configuration with explanations](../app/MindWork%20AI%20Studio/Plugins/configuration/plugin.lua)
|
||||
|
||||
Please note that the icon must be an SVG vector graphic. Raster graphics like PNGs, GIFs, and others aren’t supported. You can use the sample icon, which looks like a gear.
|
||||
|
||||
Currently, you can configure the following things:
|
||||
- Any number of self-hosted LLM providers (a combination of server and model), but currently only without API keys
|
||||
- The update behavior of AI Studio
|
||||
|
||||
All other settings can be made by the user themselves. If you need additional settings, feel free to create an issue in our planning repository: https://github.com/MindWorkAI/Planning/issues
|
||||
|
||||
In the coming months, we will allow more settings, such as:
|
||||
- Using API keys for providers
|
||||
- Configuration of embedding providers for RAG
|
||||
- Configuration of data sources for RAG
|
||||
- Configuration of chat templates
|
||||
- Configuration of assistant plugins (for example, your own assistants for your company or specific departments)
|
@ -1,6 +1,6 @@
|
||||
use std::env;
|
||||
use std::sync::OnceLock;
|
||||
use log::info;
|
||||
use log::{debug, warn};
|
||||
use rocket::{delete, get};
|
||||
use sys_locale::get_locale;
|
||||
use crate::api_token::APIToken;
|
||||
@ -42,7 +42,7 @@ pub fn is_prod() -> bool {
|
||||
#[get("/system/language")]
|
||||
pub fn read_user_language(_token: APIToken) -> String {
|
||||
get_locale().unwrap_or_else(|| {
|
||||
log::warn!("Could not determine the system language. Use default 'en-US'.");
|
||||
warn!("Could not determine the system language. Use default 'en-US'.");
|
||||
String::from("en-US")
|
||||
})
|
||||
}
|
||||
@ -64,7 +64,7 @@ pub fn read_enterprise_env_config_id(_token: APIToken) -> String {
|
||||
// The environment variable is:
|
||||
// MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID
|
||||
//
|
||||
info!("Trying to read the enterprise environment for some config ID.");
|
||||
debug!("Trying to read the enterprise environment for some config ID.");
|
||||
get_enterprise_configuration(
|
||||
"config_id",
|
||||
"MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID",
|
||||
@ -88,7 +88,7 @@ pub fn delete_enterprise_env_config_id(_token: APIToken) -> String {
|
||||
// The environment variable is:
|
||||
// MINDWORK_AI_STUDIO_ENTERPRISE_DELETE_CONFIG_ID
|
||||
//
|
||||
info!("Trying to read the enterprise environment for some config ID, which should be deleted.");
|
||||
debug!("Trying to read the enterprise environment for some config ID, which should be deleted.");
|
||||
get_enterprise_configuration(
|
||||
"delete_config_id",
|
||||
"MINDWORK_AI_STUDIO_ENTERPRISE_DELETE_CONFIG_ID",
|
||||
@ -112,7 +112,7 @@ pub fn read_enterprise_env_config_server_url(_token: APIToken) -> String {
|
||||
// The environment variable is:
|
||||
// MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL
|
||||
//
|
||||
info!("Trying to read the enterprise environment for the config server URL.");
|
||||
debug!("Trying to read the enterprise environment for the config server URL.");
|
||||
get_enterprise_configuration(
|
||||
"config_server_url",
|
||||
"MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL",
|
||||
@ -122,20 +122,20 @@ pub fn read_enterprise_env_config_server_url(_token: APIToken) -> String {
|
||||
fn get_enterprise_configuration(_reg_value: &str, env_name: &str) -> String {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "windows")] {
|
||||
info!(r"Detected a Windows machine, trying to read the registry key 'HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT' or environment variables.");
|
||||
debug!(r"Detected a Windows machine, trying to read the registry key 'HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT' or environment variables.");
|
||||
use windows_registry::*;
|
||||
let key_path = r"Software\github\MindWork AI Studio\Enterprise IT";
|
||||
let key = match CURRENT_USER.open(key_path) {
|
||||
Ok(key) => key,
|
||||
Err(_) => {
|
||||
info!(r"Could not read the registry key HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT. Falling back to environment variables.");
|
||||
debug!(r"Could not read the registry key HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT. Falling back to environment variables.");
|
||||
return match env::var(env_name) {
|
||||
Ok(val) => {
|
||||
info!("Falling back to the environment variable '{}' was successful.", env_name);
|
||||
debug!("Falling back to the environment variable '{}' was successful.", env_name);
|
||||
val
|
||||
},
|
||||
Err(_) => {
|
||||
info!("Falling back to the environment variable '{}' was not successful.", env_name);
|
||||
debug!("Falling back to the environment variable '{}' was not successful.", env_name);
|
||||
"".to_string()
|
||||
},
|
||||
}
|
||||
@ -145,14 +145,14 @@ fn get_enterprise_configuration(_reg_value: &str, env_name: &str) -> String {
|
||||
match key.get_string(_reg_value) {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
info!(r"We could read the registry key 'HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT', but the value '{}' could not be read. Falling back to environment variables.", _reg_value);
|
||||
debug!(r"We could read the registry key 'HKEY_CURRENT_USER\Software\github\MindWork AI Studio\Enterprise IT', but the value '{}' could not be read. Falling back to environment variables.", _reg_value);
|
||||
match env::var(env_name) {
|
||||
Ok(val) => {
|
||||
info!("Falling back to the environment variable '{}' was successful.", env_name);
|
||||
debug!("Falling back to the environment variable '{}' was successful.", env_name);
|
||||
val
|
||||
},
|
||||
Err(_) => {
|
||||
info!("Falling back to the environment variable '{}' was not successful.", env_name);
|
||||
debug!("Falling back to the environment variable '{}' was not successful.", env_name);
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
@ -160,11 +160,11 @@ fn get_enterprise_configuration(_reg_value: &str, env_name: &str) -> String {
|
||||
}
|
||||
} else {
|
||||
// In the case of macOS or Linux, we just read the environment variable:
|
||||
info!(r"Detected a Unix machine, trying to read the environment variable '{}'.", env_name);
|
||||
debug!(r"Detected a Unix machine, trying to read the environment variable '{}'.", env_name);
|
||||
match env::var(env_name) {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
info!("The environment variable '{}' was not found.", env_name);
|
||||
debug!("The environment variable '{}' was not found.", env_name);
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user