diff --git a/src/common/GPOWrapper/GPOWrapper.cpp b/src/common/GPOWrapper/GPOWrapper.cpp index 61e9bd3e84..ee75ae71f5 100644 --- a/src/common/GPOWrapper/GPOWrapper.cpp +++ b/src/common/GPOWrapper/GPOWrapper.cpp @@ -172,4 +172,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation { return static_cast(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue()); } + GpoRuleConfigured GPOWrapper::GetAllowedAdvancedPasteOnlineAIModelsValue() + { + return static_cast(powertoys_gpo::getAllowedAdvancedPasteOnlineAIModelsValue()); + } } diff --git a/src/common/GPOWrapper/GPOWrapper.h b/src/common/GPOWrapper/GPOWrapper.h index e4d5b8185c..e6e231c3c1 100644 --- a/src/common/GPOWrapper/GPOWrapper.h +++ b/src/common/GPOWrapper/GPOWrapper.h @@ -49,6 +49,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue(); static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue(); static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue(); + static GpoRuleConfigured GetAllowedAdvancedPasteOnlineAIModelsValue(); }; } diff --git a/src/common/GPOWrapper/GPOWrapper.idl b/src/common/GPOWrapper/GPOWrapper.idl index 9b4054dee7..6bd22d8c31 100644 --- a/src/common/GPOWrapper/GPOWrapper.idl +++ b/src/common/GPOWrapper/GPOWrapper.idl @@ -53,6 +53,7 @@ namespace PowerToys static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue(); static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue(); static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue(); + static GpoRuleConfigured GetAllowedAdvancedPasteOnlineAIModelsValue(); } } } diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h index adb8ff57dc..9c852bae58 100644 --- a/src/common/utils/gpo.h +++ b/src/common/utils/gpo.h @@ -70,7 +70,7 @@ namespace powertoys_gpo { // The registry value names for other PowerToys policies. const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation"; const std::wstring POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS = L"PowerLauncherAllPluginsEnabledState"; - + const std::wstring POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS = L"AllowPowerToysAdvancedPasteOnlineAIModels"; inline std::optional readRegistryStringValue(HKEY hRootKey, const std::wstring& subKey, const std::wstring& value_name) { @@ -470,4 +470,9 @@ namespace powertoys_gpo { { return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_QOI_THUMBNAILS); } + + inline gpo_rule_configured_t getAllowedAdvancedPasteOnlineAIModelsValue() + { + return getUtilityEnabledValue(POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS); + } } diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx index c54809c35e..316254ff3e 100644 --- a/src/gpo/assets/PowerToys.admx +++ b/src/gpo/assets/PowerToys.admx @@ -1,11 +1,11 @@ - + - + @@ -18,6 +18,7 @@ + @@ -28,6 +29,9 @@ + + + @@ -489,5 +493,15 @@ + + + + + + + + + + diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml index e917fc1175..9e26fbde74 100644 --- a/src/gpo/assets/en-US/PowerToys.adml +++ b/src/gpo/assets/en-US/PowerToys.adml @@ -1,7 +1,7 @@ - + PowerToys PowerToys @@ -9,6 +9,7 @@ Microsoft PowerToys Installer and Updates PowerToys Run + Advanced Paste PowerToys version 0.64.0 or later PowerToys version 0.68.0 or later @@ -20,6 +21,7 @@ PowerToys version 0.77.0 or later PowerToys version 0.78.0 or later PowerToys version 0.81.0 or later + PowerToys version 0.81.1 or later This policy configures the enabled state for all PowerToys utilities. @@ -118,6 +120,12 @@ If you disable or don't configure this policy, either the user or the policy "Co You can set the enabled state for all plugins not configured by this policy using the policy "Configure enabled state for all plugins". Note: Changes require a restart of PowerToys Run. + + This policy configures the enabled disable state for using Advanced Paste online AI models. + +If you enable or don't configure this policy, the user takes control over the enabled state of the Enable paste with AI Advanced Paste setting. + +If you disable this policy, the user won't be able to enable Enable paste with AI Advanced Paste setting and use Advanced Paste AI prompt nor set up the Open AI key in PowerToys Settings. Configure global utility enabled state Advanced Paste: Configure enabled state @@ -165,6 +173,7 @@ Note: Changes require a restart of PowerToys Run. Configure enabled state for individual plugins QOI file preview: Configure enabled state QOI file thumbnail: Configure enabled state + Advanced Paste: Allow using online AI models diff --git a/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw b/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw index 618a54332c..990310f240 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw +++ b/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw @@ -225,4 +225,7 @@ OpenAI Terms + + To custom with AI is disabled by your organization + \ No newline at end of file diff --git a/src/modules/AdvancedPaste/AdvancedPaste/ViewModels/OptionsViewModel.cs b/src/modules/AdvancedPaste/AdvancedPaste/ViewModels/OptionsViewModel.cs index a3accbe344..1ba2625e79 100644 --- a/src/modules/AdvancedPaste/AdvancedPaste/ViewModels/OptionsViewModel.cs +++ b/src/modules/AdvancedPaste/AdvancedPaste/ViewModels/OptionsViewModel.cs @@ -16,7 +16,6 @@ using CommunityToolkit.Mvvm.Input; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.UI.Dispatching; -using Microsoft.UI.Xaml; using Microsoft.Win32; using Windows.ApplicationModel.DataTransfer; using WinUIEx; @@ -81,32 +80,40 @@ namespace AdvancedPaste.ViewModels { GetClipboardData(); - var openAIKey = AICompletionsHelper.LoadOpenAIKey(); - var currentKey = aiHelper.GetKey(); - bool keyChanged = openAIKey != currentKey; - - if (keyChanged) + if (PowerToys.GPOWrapper.GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) { - app.GetMainWindow().StartLoading(); - - Task.Run(() => - { - aiHelper.SetOpenAIKey(openAIKey); - }).ContinueWith( - (t) => - { - _dispatcherQueue.TryEnqueue(() => - { - app.GetMainWindow().FinishLoading(aiHelper.IsAIEnabled); - OnPropertyChanged(nameof(InputTxtBoxPlaceholderText)); - IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled; - }); - }, - TaskScheduler.Default); + IsCustomAIEnabled = false; + OnPropertyChanged(nameof(InputTxtBoxPlaceholderText)); } else { - IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled; + var openAIKey = AICompletionsHelper.LoadOpenAIKey(); + var currentKey = aiHelper.GetKey(); + bool keyChanged = openAIKey != currentKey; + + if (keyChanged) + { + app.GetMainWindow().StartLoading(); + + Task.Run(() => + { + aiHelper.SetOpenAIKey(openAIKey); + }).ContinueWith( + (t) => + { + _dispatcherQueue.TryEnqueue(() => + { + app.GetMainWindow().FinishLoading(aiHelper.IsAIEnabled); + OnPropertyChanged(nameof(InputTxtBoxPlaceholderText)); + IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled; + }); + }, + TaskScheduler.Default); + } + else + { + IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled; + } } ClipboardHistoryEnabled = IsClipboardHistoryEnabled(); @@ -146,7 +153,11 @@ namespace AdvancedPaste.ViewModels { app.GetMainWindow().ClearInputText(); - if (!aiHelper.IsAIEnabled) + if (PowerToys.GPOWrapper.GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) + { + return ResourceLoaderInstance.ResourceLoader.GetString("OpenAIGpoDisabled"); + } + else if (!aiHelper.IsAIEnabled) { return ResourceLoaderInstance.ResourceLoader.GetString("OpenAINotConfigured"); } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPaste.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPaste.xaml index b483dd9918..b79d6e6e59 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPaste.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPaste.xaml @@ -45,7 +45,7 @@ Severity="Informational" /> - + @@ -73,6 +73,12 @@ IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}"> + diff --git a/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs index fa0288e09b..28b27d95fb 100644 --- a/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs @@ -32,6 +32,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private GpoRuleConfigured _enabledGpoRuleConfiguration; private bool _enabledStateIsGPOConfigured; + private GpoRuleConfigured _onlineAIModelsGpoRuleConfiguration; + private bool _onlineAIModelsDisallowedByGPO; private bool _isEnabled; private Func SendConfigMSG { get; } @@ -80,6 +82,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { _isEnabled = GeneralSettingsConfig.Enabled.AdvancedPaste; } + + _onlineAIModelsGpoRuleConfiguration = GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue(); + if (_onlineAIModelsGpoRuleConfiguration == GpoRuleConfigured.Disabled) + { + _onlineAIModelsDisallowedByGPO = true; + + // disable AI if it was enabled + DisableAI(); + } } public bool IsEnabled @@ -124,13 +135,23 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels return cred is not null; } - public bool IsOpenAIEnabled => OpenAIKeyExists(); + public bool IsOpenAIEnabled => OpenAIKeyExists() && !IsOnlineAIModelsDisallowedByGPO; public bool IsEnabledGpoConfigured { get => _enabledStateIsGPOConfigured; } + public bool IsOnlineAIModelsDisallowedByGPO + { + get => _onlineAIModelsDisallowedByGPO || _enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled; + } + + public bool ShowOnlineAIModelsGpoConfiguredInfoBar + { + get => _onlineAIModelsDisallowedByGPO && _enabledGpoRuleConfiguration != GpoRuleConfigured.Disabled; + } + private bool IsClipboardHistoryEnabled() { string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Clipboard\"; @@ -334,18 +355,30 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels internal void DisableAI() { - PasswordVault vault = new PasswordVault(); - PasswordCredential cred = vault.Retrieve("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey"); - vault.Remove(cred); - OnPropertyChanged(nameof(IsOpenAIEnabled)); + try + { + PasswordVault vault = new PasswordVault(); + PasswordCredential cred = vault.Retrieve("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey"); + vault.Remove(cred); + OnPropertyChanged(nameof(IsOpenAIEnabled)); + } + catch (Exception) + { + } } internal void EnableAI(string password) { - PasswordVault vault = new PasswordVault(); - PasswordCredential cred = new PasswordCredential("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey", password); - vault.Add(cred); - OnPropertyChanged(nameof(IsOpenAIEnabled)); + try + { + PasswordVault vault = new PasswordVault(); + PasswordCredential cred = new PasswordCredential("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey", password); + vault.Add(cred); + OnPropertyChanged(nameof(IsOpenAIEnabled)); + } + catch (Exception) + { + } } } } diff --git a/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp b/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp index b4cf7a0a87..3aa19a80eb 100644 --- a/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp +++ b/tools/BugReportTool/BugReportTool/ReportGPOValues.cpp @@ -67,4 +67,5 @@ void ReportGPOValues(const std::filesystem::path& tmpDir) report << "getAllowExperimentationValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowExperimentationValue()) << std::endl; report << "getConfiguredQoiPreviewEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiPreviewEnabledValue()) << std::endl; report << "getConfiguredQoiThumbnailsEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue()) << std::endl; + report << "getAllowedAdvancedPasteOnlineAIModelsValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowedAdvancedPasteOnlineAIModelsValue()) << std::endl; }