Skip to content

Commit d0d2f3c

Browse files
stefansjfwjaimecbernardohtcfreek
authored
[GPO][AdvPaste]Online AI models GPO (#33045)
* [Advanced Paste] AI gpo * address PR comments * XAML format * Fix showing Enable Paste with AI with module disabled * Rename variable in ViewModel for clarity * Update adml revision * Move policy registry key around * Update src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw Co-authored-by: Heiko <[email protected]> --------- Co-authored-by: Jaime Bernardo <[email protected]> Co-authored-by: Heiko <[email protected]>
1 parent 8bb5a33 commit d0d2f3c

File tree

11 files changed

+126
-38
lines changed

11 files changed

+126
-38
lines changed

src/common/GPOWrapper/GPOWrapper.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation
172172
{
173173
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue());
174174
}
175+
GpoRuleConfigured GPOWrapper::GetAllowedAdvancedPasteOnlineAIModelsValue()
176+
{
177+
return static_cast<GpoRuleConfigured>(powertoys_gpo::getAllowedAdvancedPasteOnlineAIModelsValue());
178+
}
175179
}

src/common/GPOWrapper/GPOWrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation
4949
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
5050
static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue();
5151
static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue();
52+
static GpoRuleConfigured GetAllowedAdvancedPasteOnlineAIModelsValue();
5253
};
5354
}
5455

src/common/GPOWrapper/GPOWrapper.idl

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace PowerToys
5353
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
5454
static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue();
5555
static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue();
56+
static GpoRuleConfigured GetAllowedAdvancedPasteOnlineAIModelsValue();
5657
}
5758
}
5859
}

src/common/utils/gpo.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace powertoys_gpo {
7070
// The registry value names for other PowerToys policies.
7171
const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation";
7272
const std::wstring POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS = L"PowerLauncherAllPluginsEnabledState";
73-
73+
const std::wstring POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS = L"AllowPowerToysAdvancedPasteOnlineAIModels";
7474

7575
inline std::optional<std::wstring> readRegistryStringValue(HKEY hRootKey, const std::wstring& subKey, const std::wstring& value_name)
7676
{
@@ -470,4 +470,9 @@ namespace powertoys_gpo {
470470
{
471471
return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_QOI_THUMBNAILS);
472472
}
473+
474+
inline gpo_rule_configured_t getAllowedAdvancedPasteOnlineAIModelsValue()
475+
{
476+
return getUtilityEnabledValue(POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS);
477+
}
473478
}

src/gpo/assets/PowerToys.admx

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<!-- Copyright (c) Microsoft Corporation.
33
Licensed under the MIT License. -->
4-
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.9" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
4+
<policyDefinitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.10" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
55
<policyNamespaces>
66
<target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" />
77
</policyNamespaces>
8-
<resources minRequiredRevision="1.9"/><!-- Last changed with PowerToys v0.81.0 -->
8+
<resources minRequiredRevision="1.10"/><!-- Last changed with PowerToys v0.81.1 -->
99
<supportedOn>
1010
<definitions>
1111
<definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/>
@@ -18,6 +18,7 @@
1818
<definition name="SUPPORTED_POWERTOYS_0_77_0" displayName="$(string.SUPPORTED_POWERTOYS_0_77_0)"/>
1919
<definition name="SUPPORTED_POWERTOYS_0_78_0" displayName="$(string.SUPPORTED_POWERTOYS_0_78_0)"/>
2020
<definition name="SUPPORTED_POWERTOYS_0_81_0" displayName="$(string.SUPPORTED_POWERTOYS_0_81_0)"/>
21+
<definition name="SUPPORTED_POWERTOYS_0_81_1" displayName="$(string.SUPPORTED_POWERTOYS_0_81_1)"/>
2122
</definitions>
2223
</supportedOn>
2324
<categories>
@@ -28,6 +29,9 @@
2829
<category name="PowerToysRun" displayName="$(string.PowerToysRun)">
2930
<parentCategory ref="PowerToys" />
3031
</category>
32+
<category name="AdvancedPaste" displayName="$(string.AdvancedPaste)">
33+
<parentCategory ref="PowerToys" />
34+
</category>
3135
</categories>
3236
<policies>
3337

@@ -489,5 +493,15 @@
489493
<list id="PowerToysRunIndividualPluginEnabledList" explicitValue="true" />
490494
</elements>
491495
</policy>
496+
<policy name="AllowPowerToysAdvancedPasteOnlineAIModels" class="Both" displayName="$(string.AllowPowerToysAdvancedPasteOnlineAIModels)" explainText="$(string.AllowPowerToysAdvancedPasteOnlineAIModelsDescription)" key="Software\Policies\PowerToys" valueName="AllowPowerToysAdvancedPasteOnlineAIModels">
497+
<parentCategory ref="AdvancedPaste" />
498+
<supportedOn ref="SUPPORTED_POWERTOYS_0_81_1" />
499+
<enabledValue>
500+
<decimal value="1" />
501+
</enabledValue>
502+
<disabledValue>
503+
<decimal value="0" />
504+
</disabledValue>
505+
</policy>
492506
</policies>
493507
</policyDefinitions>

src/gpo/assets/en-US/PowerToys.adml

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<!-- Copyright (c) Microsoft Corporation.
33
Licensed under the MIT License. -->
4-
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.9" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
4+
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.10" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
55
<displayName>PowerToys</displayName>
66
<description>PowerToys</description>
77
<resources>
88
<stringTable>
99
<string id="PowerToys">Microsoft PowerToys</string>
1010
<string id="InstallerUpdates">Installer and Updates</string>
1111
<string id="PowerToysRun">PowerToys Run</string>
12+
<string id="AdvancedPaste">Advanced Paste</string>
1213

1314
<string id="SUPPORTED_POWERTOYS_0_64_0">PowerToys version 0.64.0 or later</string>
1415
<string id="SUPPORTED_POWERTOYS_0_68_0">PowerToys version 0.68.0 or later</string>
@@ -20,6 +21,7 @@
2021
<string id="SUPPORTED_POWERTOYS_0_77_0">PowerToys version 0.77.0 or later</string>
2122
<string id="SUPPORTED_POWERTOYS_0_78_0">PowerToys version 0.78.0 or later</string>
2223
<string id="SUPPORTED_POWERTOYS_0_81_0">PowerToys version 0.81.0 or later</string>
24+
<string id="SUPPORTED_POWERTOYS_0_81_1">PowerToys version 0.81.1 or later</string>
2325

2426
<string id="ConfigureGlobalUtilityEnabledStateDescription">This policy configures the enabled state for all PowerToys utilities.
2527

@@ -118,6 +120,12 @@ If you disable or don't configure this policy, either the user or the policy "Co
118120
You can set the enabled state for all plugins not configured by this policy using the policy "Configure enabled state for all plugins".
119121

120122
Note: Changes require a restart of PowerToys Run.
123+
</string>
124+
<string id="AllowPowerToysAdvancedPasteOnlineAIModelsDescription">This policy configures the enabled disable state for using Advanced Paste online AI models.
125+
126+
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.
127+
128+
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.
121129
</string>
122130
<string id="ConfigureGlobalUtilityEnabledState">Configure global utility enabled state</string>
123131
<string id="ConfigureEnabledUtilityAdvancedPaste">Advanced Paste: Configure enabled state</string>
@@ -165,6 +173,7 @@ Note: Changes require a restart of PowerToys Run.
165173
<string id="PowerToysRunIndividualPluginEnabledState">Configure enabled state for individual plugins</string>
166174
<string id="ConfigureEnabledUtilityFileExplorerQOIPreview">QOI file preview: Configure enabled state</string>
167175
<string id="ConfigureEnabledUtilityFileExplorerQOIThumbnails">QOI file thumbnail: Configure enabled state</string>
176+
<string id="AllowPowerToysAdvancedPasteOnlineAIModels">Advanced Paste: Allow using online AI models</string>
168177
</stringTable>
169178

170179
<presentationTable>

src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw

+3
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,7 @@
225225
<data name="TermsLink.Text" xml:space="preserve">
226226
<value>OpenAI Terms</value>
227227
</data>
228+
<data name="OpenAIGpoDisabled" xml:space="preserve">
229+
<value>To custom with AI is disabled by your organization</value>
230+
</data>
228231
</root>

src/modules/AdvancedPaste/AdvancedPaste/ViewModels/OptionsViewModel.cs

+35-24
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using ManagedCommon;
1717
using Microsoft.PowerToys.Settings.UI.Library;
1818
using Microsoft.UI.Dispatching;
19-
using Microsoft.UI.Xaml;
2019
using Microsoft.Win32;
2120
using Windows.ApplicationModel.DataTransfer;
2221
using WinUIEx;
@@ -81,32 +80,40 @@ public void OnShow()
8180
{
8281
GetClipboardData();
8382

84-
var openAIKey = AICompletionsHelper.LoadOpenAIKey();
85-
var currentKey = aiHelper.GetKey();
86-
bool keyChanged = openAIKey != currentKey;
87-
88-
if (keyChanged)
83+
if (PowerToys.GPOWrapper.GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
8984
{
90-
app.GetMainWindow().StartLoading();
91-
92-
Task.Run(() =>
93-
{
94-
aiHelper.SetOpenAIKey(openAIKey);
95-
}).ContinueWith(
96-
(t) =>
97-
{
98-
_dispatcherQueue.TryEnqueue(() =>
99-
{
100-
app.GetMainWindow().FinishLoading(aiHelper.IsAIEnabled);
101-
OnPropertyChanged(nameof(InputTxtBoxPlaceholderText));
102-
IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled;
103-
});
104-
},
105-
TaskScheduler.Default);
85+
IsCustomAIEnabled = false;
86+
OnPropertyChanged(nameof(InputTxtBoxPlaceholderText));
10687
}
10788
else
10889
{
109-
IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled;
90+
var openAIKey = AICompletionsHelper.LoadOpenAIKey();
91+
var currentKey = aiHelper.GetKey();
92+
bool keyChanged = openAIKey != currentKey;
93+
94+
if (keyChanged)
95+
{
96+
app.GetMainWindow().StartLoading();
97+
98+
Task.Run(() =>
99+
{
100+
aiHelper.SetOpenAIKey(openAIKey);
101+
}).ContinueWith(
102+
(t) =>
103+
{
104+
_dispatcherQueue.TryEnqueue(() =>
105+
{
106+
app.GetMainWindow().FinishLoading(aiHelper.IsAIEnabled);
107+
OnPropertyChanged(nameof(InputTxtBoxPlaceholderText));
108+
IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled;
109+
});
110+
},
111+
TaskScheduler.Default);
112+
}
113+
else
114+
{
115+
IsCustomAIEnabled = IsClipboardDataText && aiHelper.IsAIEnabled;
116+
}
110117
}
111118

112119
ClipboardHistoryEnabled = IsClipboardHistoryEnabled();
@@ -146,7 +153,11 @@ public string InputTxtBoxPlaceholderText
146153
{
147154
app.GetMainWindow().ClearInputText();
148155

149-
if (!aiHelper.IsAIEnabled)
156+
if (PowerToys.GPOWrapper.GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
157+
{
158+
return ResourceLoaderInstance.ResourceLoader.GetString("OpenAIGpoDisabled");
159+
}
160+
else if (!aiHelper.IsAIEnabled)
150161
{
151162
return ResourceLoaderInstance.ResourceLoader.GetString("OpenAINotConfigured");
152163
}

src/settings-ui/Settings.UI/SettingsXAML/Views/AdvancedPaste.xaml

+7-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
Severity="Informational" />
4646

4747
<controls:SettingsGroup x:Uid="AdvancedPaste_EnableAISettingsGroup" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
48-
<tkcontrols:SettingsCard x:Uid="AdvancedPaste_EnableAISettingsCard">
48+
<tkcontrols:SettingsCard x:Uid="AdvancedPaste_EnableAISettingsCard" IsEnabled="{x:Bind ViewModel.IsOnlineAIModelsDisallowedByGPO, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
4949
<tkcontrols:SettingsCard.HeaderIcon>
5050
<PathIcon Data="M128 766q0-42 24-77t65-48l178-57q32-11 61-30t52-42q50-50 71-114l58-179q13-40 48-65t78-26q42 0 77 24t50 65l58 177q21 66 72 117 49 50 117 72l176 58q43 14 69 48t26 80q0 41-25 76t-64 49l-178 58q-66 21-117 72-32 32-51 73t-33 84-26 83-30 73-45 51-71 20q-42 0-77-24t-49-65l-58-178q-8-25-19-47t-28-43q-34-43-77-68t-89-41-89-27-78-29-55-45-21-75zm1149 7q-76-29-145-53t-129-60-104-88-73-138l-57-176-67 176q-18 48-42 89t-60 78q-34 34-76 61t-89 43l-177 57q75 29 144 53t127 60 103 89 73 137l57 176 67-176q37-97 103-168t168-103l177-57zm-125 759q0-31 20-57t49-36l99-32q34-11 53-34t30-51 20-59 20-54 33-41 58-16q32 0 59 19t38 50q6 20 11 40t13 40 17 38 25 34q16 17 39 26t48 18 49 16 44 20 31 32 12 50q0 33-18 60t-51 38q-19 6-39 11t-41 13-39 17-34 25q-24 25-35 62t-24 73-35 61-68 25q-32 0-59-19t-38-50q-6-18-11-39t-13-41-17-40-24-33q-18-17-41-27t-47-17-49-15-43-20-30-33-12-54zm583 4q-43-13-74-30t-55-41-40-55-32-74q-12 41-29 72t-42 55-55 42-71 31q81 23 128 71t71 129q15-43 31-74t40-54 53-40 75-32z" />
5151
</tkcontrols:SettingsCard.HeaderIcon>
@@ -73,6 +73,12 @@
7373
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}">
7474
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowCustomPreview, Mode=TwoWay}" />
7575
</tkcontrols:SettingsCard>
76+
<InfoBar
77+
x:Uid="GPO_SettingIsManaged"
78+
IsClosable="False"
79+
IsOpen="{x:Bind ViewModel.ShowOnlineAIModelsGpoConfiguredInfoBar, Mode=OneWay}"
80+
IsTabStop="{x:Bind ViewModel.ShowOnlineAIModelsGpoConfiguredInfoBar, Mode=OneWay}"
81+
Severity="Informational" />
7682
</controls:SettingsGroup>
7783

7884
<controls:SettingsGroup x:Uid="AdvancedPaste_ClipboardHistorySettingsGroup" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">

src/settings-ui/Settings.UI/ViewModels/AdvancedPasteViewModel.cs

+42-9
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public class AdvancedPasteViewModel : Observable, IDisposable
3232

3333
private GpoRuleConfigured _enabledGpoRuleConfiguration;
3434
private bool _enabledStateIsGPOConfigured;
35+
private GpoRuleConfigured _onlineAIModelsGpoRuleConfiguration;
36+
private bool _onlineAIModelsDisallowedByGPO;
3537
private bool _isEnabled;
3638

3739
private Func<string, int> SendConfigMSG { get; }
@@ -80,6 +82,15 @@ private void InitializeEnabledValue()
8082
{
8183
_isEnabled = GeneralSettingsConfig.Enabled.AdvancedPaste;
8284
}
85+
86+
_onlineAIModelsGpoRuleConfiguration = GPOWrapper.GetAllowedAdvancedPasteOnlineAIModelsValue();
87+
if (_onlineAIModelsGpoRuleConfiguration == GpoRuleConfigured.Disabled)
88+
{
89+
_onlineAIModelsDisallowedByGPO = true;
90+
91+
// disable AI if it was enabled
92+
DisableAI();
93+
}
8394
}
8495

8596
public bool IsEnabled
@@ -124,13 +135,23 @@ private bool OpenAIKeyExists()
124135
return cred is not null;
125136
}
126137

127-
public bool IsOpenAIEnabled => OpenAIKeyExists();
138+
public bool IsOpenAIEnabled => OpenAIKeyExists() && !IsOnlineAIModelsDisallowedByGPO;
128139

129140
public bool IsEnabledGpoConfigured
130141
{
131142
get => _enabledStateIsGPOConfigured;
132143
}
133144

145+
public bool IsOnlineAIModelsDisallowedByGPO
146+
{
147+
get => _onlineAIModelsDisallowedByGPO || _enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled;
148+
}
149+
150+
public bool ShowOnlineAIModelsGpoConfiguredInfoBar
151+
{
152+
get => _onlineAIModelsDisallowedByGPO && _enabledGpoRuleConfiguration != GpoRuleConfigured.Disabled;
153+
}
154+
134155
private bool IsClipboardHistoryEnabled()
135156
{
136157
string registryKey = @"HKEY_CURRENT_USER\Software\Microsoft\Clipboard\";
@@ -334,18 +355,30 @@ public void Dispose()
334355

335356
internal void DisableAI()
336357
{
337-
PasswordVault vault = new PasswordVault();
338-
PasswordCredential cred = vault.Retrieve("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey");
339-
vault.Remove(cred);
340-
OnPropertyChanged(nameof(IsOpenAIEnabled));
358+
try
359+
{
360+
PasswordVault vault = new PasswordVault();
361+
PasswordCredential cred = vault.Retrieve("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey");
362+
vault.Remove(cred);
363+
OnPropertyChanged(nameof(IsOpenAIEnabled));
364+
}
365+
catch (Exception)
366+
{
367+
}
341368
}
342369

343370
internal void EnableAI(string password)
344371
{
345-
PasswordVault vault = new PasswordVault();
346-
PasswordCredential cred = new PasswordCredential("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey", password);
347-
vault.Add(cred);
348-
OnPropertyChanged(nameof(IsOpenAIEnabled));
372+
try
373+
{
374+
PasswordVault vault = new PasswordVault();
375+
PasswordCredential cred = new PasswordCredential("https://platform.openai.com/api-keys", "PowerToys_AdvancedPaste_OpenAIKey", password);
376+
vault.Add(cred);
377+
OnPropertyChanged(nameof(IsOpenAIEnabled));
378+
}
379+
catch (Exception)
380+
{
381+
}
349382
}
350383
}
351384
}

tools/BugReportTool/BugReportTool/ReportGPOValues.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ void ReportGPOValues(const std::filesystem::path& tmpDir)
6767
report << "getAllowExperimentationValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowExperimentationValue()) << std::endl;
6868
report << "getConfiguredQoiPreviewEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiPreviewEnabledValue()) << std::endl;
6969
report << "getConfiguredQoiThumbnailsEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue()) << std::endl;
70+
report << "getAllowedAdvancedPasteOnlineAIModelsValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowedAdvancedPasteOnlineAIModelsValue()) << std::endl;
7071
}

0 commit comments

Comments
 (0)