mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
Advanced Paste: AI pasting enhancement (#42374)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request * Add multiple endpoint support for paste with AI * Add Local AI support for paste AI * Advanced AI implementation <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #32960 - [x] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [x] **New binaries:** Added on the required places - [x] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [x] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [x] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [x] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed ### GPO - [x] Paste with AI should not be available if the original GPO for paste AI is set to false - [x] Paste with AI should be controlled within endpoint granularity - [x] Advanced Paste UI should disable AI ability if GPO is set to disable for any llm ### Paste AI - [x] Every AI endpoint should work as expected - [x] Default prompt should be able to give a reasonable result - [x] Local AI should work as expected ### Advanced AI - [x] Open AI and Azure OPENAI should be able to configure as advanced AI endpoint - [x] Advanced AI should be able to pick up functions correctly to do the transformation and give reasonable result --------- Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com> Signed-off-by: Shuai Yuan <shuai.yuan.zju@gmail.com> Signed-off-by: Shawn Yuan (from Dev Box) <shuaiyuan@microsoft.com> Co-authored-by: Leilei Zhang <leilzh@microsoft.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Kai Tao <kaitao@microsoft.com> Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com> Co-authored-by: vanzue <vanzue@outlook.com> Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="Microsoft.PowerToys.Settings.UI.Controls.FoundryLocalModelPicker"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="using:LanguageModelProvider"
|
||||
xmlns:tkconverters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
|
||||
x:Name="Root"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<tkconverters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<Style x:Key="TagBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="{ThemeResource LayerFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ControlStrongStrokeColorDefaultBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="8" />
|
||||
<Setter Property="Padding" Value="8,2" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="TagTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource TextFillColorPrimaryBrush}" />
|
||||
<Setter Property="TextWrapping" Value="NoWrap" />
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<StackPanel
|
||||
x:Name="LoadingPanel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="12">
|
||||
<ProgressRing
|
||||
x:Name="LoadingIndicator"
|
||||
Width="36"
|
||||
Height="36"
|
||||
HorizontalAlignment="Center" />
|
||||
<TextBlock
|
||||
x:Name="LoadingStatusTextBlock"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="Loading Foundry Local status..."
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer x:Name="ModelsView" Visibility="Collapsed">
|
||||
<Grid Padding="0,12,0,16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel
|
||||
x:Name="NoModelsPanel"
|
||||
Grid.Row="0"
|
||||
Margin="0,0,0,16"
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Vertical"
|
||||
Spacing="4">
|
||||
<FontIcon FontSize="24" Glyph="" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="No models downloaded"
|
||||
TextAlignment="Center" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="Run Foundry Local to download or add a local model below."
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="LaunchFoundryModelListButton"
|
||||
HorizontalAlignment="Center"
|
||||
Click="LaunchFoundryModelListButton_Click"
|
||||
Content="Open Foundry model list"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Spacing="12">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox
|
||||
x:Name="CachedModelsComboBox"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{x:Bind CachedModels, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind SelectedModel, Mode=TwoWay}"
|
||||
SelectionChanged="CachedModelsComboBox_SelectionChanged">
|
||||
<ComboBox.Header>
|
||||
<TextBlock>
|
||||
<Run Text="Foundry Local model" /><LineBreak /><Run
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="Use the Foundry Local CLI to download models that run locally on-device. They'll appear here." />
|
||||
</TextBlock>
|
||||
</ComboBox.Header>
|
||||
</ComboBox>
|
||||
<Button
|
||||
x:Name="RefreshModelsButton"
|
||||
Grid.Column="1"
|
||||
MinHeight="32"
|
||||
VerticalAlignment="Bottom"
|
||||
Click="RefreshModelsButton_Click"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
ToolTipService.ToolTip="Refresh model list">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
</Button>
|
||||
</Grid>
|
||||
<StackPanel
|
||||
x:Name="SelectedModelDetailsPanel"
|
||||
Spacing="8"
|
||||
Visibility="Collapsed">
|
||||
<TextBlock
|
||||
x:Name="SelectedModelDescriptionText"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap" />
|
||||
<toolkit:WrapPanel
|
||||
x:Name="SelectedModelTagsPanel"
|
||||
HorizontalSpacing="4"
|
||||
VerticalSpacing="4"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
<Grid x:Name="NotAvailableGrid" Visibility="Collapsed">
|
||||
<StackPanel
|
||||
Margin="48,0,48,48"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Vertical"
|
||||
Spacing="8">
|
||||
<Image Width="36" Source="ms-appx:///Assets/Settings/Icons/Models/FoundryLocal.svg" />
|
||||
<TextBlock
|
||||
FontWeight="SemiBold"
|
||||
Text="Foundry Local is not available on this device yet."
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
IsTextSelectionEnabled="True"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap">
|
||||
<Run Text="Start the Foundry Local service before returning to PowerToys." />
|
||||
</TextBlock>
|
||||
<HyperlinkButton Content="Follow the Foundry Local CLI guide" NavigateUri="https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-local/get-started" />
|
||||
<TextBlock
|
||||
x:Uid="FoundryLocal_RestartRequiredNote"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="Note: After installing the Foundry Local CLI, restart PowerToys to use it."
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="StateGroup">
|
||||
<VisualState x:Name="ShowLoading" />
|
||||
<VisualState x:Name="ShowModels">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="LoadingPanel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="NotAvailableGrid.Visibility" Value="Collapsed" />
|
||||
<Setter Target="ModelsView.Visibility" Value="Visible" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="ShowNotAvailable">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="LoadingPanel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="NotAvailableGrid.Visibility" Value="Visible" />
|
||||
<Setter Target="ModelsView.Visibility" Value="Collapsed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,457 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using LanguageModelProvider;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Controls;
|
||||
|
||||
public sealed partial class FoundryLocalModelPicker : UserControl
|
||||
{
|
||||
private INotifyCollectionChanged _cachedModelsSubscription;
|
||||
private INotifyCollectionChanged _downloadableModelsSubscription;
|
||||
private bool _suppressSelection;
|
||||
|
||||
public FoundryLocalModelPicker()
|
||||
{
|
||||
InitializeComponent();
|
||||
Loaded += (_, _) => UpdateVisualStates();
|
||||
}
|
||||
|
||||
public delegate void ModelSelectionChangedEventHandler(object sender, ModelDetails model);
|
||||
|
||||
public delegate void DownloadRequestedEventHandler(object sender, object payload);
|
||||
|
||||
public delegate void LoadRequestedEventHandler(object sender, FoundryLoadRequestedEventArgs args);
|
||||
|
||||
public event ModelSelectionChangedEventHandler SelectionChanged;
|
||||
|
||||
public event LoadRequestedEventHandler LoadRequested;
|
||||
|
||||
public IEnumerable<ModelDetails> CachedModels
|
||||
{
|
||||
get => (IEnumerable<ModelDetails>)GetValue(CachedModelsProperty);
|
||||
set => SetValue(CachedModelsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CachedModelsProperty =
|
||||
DependencyProperty.Register(nameof(CachedModels), typeof(IEnumerable<ModelDetails>), typeof(FoundryLocalModelPicker), new PropertyMetadata(null, OnCachedModelsChanged));
|
||||
|
||||
public IEnumerable DownloadableModels
|
||||
{
|
||||
get => (IEnumerable)GetValue(DownloadableModelsProperty);
|
||||
set => SetValue(DownloadableModelsProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DownloadableModelsProperty =
|
||||
DependencyProperty.Register(nameof(DownloadableModels), typeof(IEnumerable), typeof(FoundryLocalModelPicker), new PropertyMetadata(null, OnDownloadableModelsChanged));
|
||||
|
||||
public ModelDetails SelectedModel
|
||||
{
|
||||
get => (ModelDetails)GetValue(SelectedModelProperty);
|
||||
set => SetValue(SelectedModelProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedModelProperty =
|
||||
DependencyProperty.Register(nameof(SelectedModel), typeof(ModelDetails), typeof(FoundryLocalModelPicker), new PropertyMetadata(null, OnSelectedModelChanged));
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => (bool)GetValue(IsLoadingProperty);
|
||||
set => SetValue(IsLoadingProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsLoadingProperty =
|
||||
DependencyProperty.Register(nameof(IsLoading), typeof(bool), typeof(FoundryLocalModelPicker), new PropertyMetadata(false, OnStatePropertyChanged));
|
||||
|
||||
public bool IsAvailable
|
||||
{
|
||||
get => (bool)GetValue(IsAvailableProperty);
|
||||
set => SetValue(IsAvailableProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsAvailableProperty =
|
||||
DependencyProperty.Register(nameof(IsAvailable), typeof(bool), typeof(FoundryLocalModelPicker), new PropertyMetadata(false, OnStatePropertyChanged));
|
||||
|
||||
public string StatusText
|
||||
{
|
||||
get => (string)GetValue(StatusTextProperty);
|
||||
set => SetValue(StatusTextProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty StatusTextProperty =
|
||||
DependencyProperty.Register(nameof(StatusText), typeof(string), typeof(FoundryLocalModelPicker), new PropertyMetadata(string.Empty, OnStatePropertyChanged));
|
||||
|
||||
public bool HasCachedModels => CachedModels?.Any() ?? false;
|
||||
|
||||
public bool HasDownloadableModels => DownloadableModels?.Cast<object>().Any() ?? false;
|
||||
|
||||
public void RequestLoad(bool refresh)
|
||||
{
|
||||
if (IsLoading)
|
||||
{
|
||||
// Allow refresh requests to continue even if already loading by cancelling via host.
|
||||
}
|
||||
else
|
||||
{
|
||||
IsLoading = true;
|
||||
}
|
||||
|
||||
IsAvailable = false;
|
||||
StatusText = "Loading Foundry Local status...";
|
||||
LoadRequested?.Invoke(this, new FoundryLoadRequestedEventArgs(refresh));
|
||||
}
|
||||
|
||||
private static void OnCachedModelsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var control = (FoundryLocalModelPicker)d;
|
||||
control.SubscribeToCachedModels(e.OldValue as IEnumerable<ModelDetails>, e.NewValue as IEnumerable<ModelDetails>);
|
||||
control.UpdateVisualStates();
|
||||
}
|
||||
|
||||
private static void OnDownloadableModelsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var control = (FoundryLocalModelPicker)d;
|
||||
control.SubscribeToDownloadableModels(e.OldValue as IEnumerable, e.NewValue as IEnumerable);
|
||||
control.UpdateVisualStates();
|
||||
}
|
||||
|
||||
private static void OnSelectedModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var control = (FoundryLocalModelPicker)d;
|
||||
if (control._suppressSelection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
control._suppressSelection = true;
|
||||
if (control.CachedModelsComboBox is not null)
|
||||
{
|
||||
control.CachedModelsComboBox.SelectedItem = e.NewValue;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
control._suppressSelection = false;
|
||||
}
|
||||
|
||||
control.UpdateSelectedModelDetails();
|
||||
}
|
||||
|
||||
private static void OnStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var control = (FoundryLocalModelPicker)d;
|
||||
control.UpdateVisualStates();
|
||||
}
|
||||
|
||||
private void SubscribeToCachedModels(IEnumerable<ModelDetails> oldValue, IEnumerable<ModelDetails> newValue)
|
||||
{
|
||||
if (_cachedModelsSubscription is not null)
|
||||
{
|
||||
_cachedModelsSubscription.CollectionChanged -= CachedModels_CollectionChanged;
|
||||
_cachedModelsSubscription = null;
|
||||
}
|
||||
|
||||
if (newValue is INotifyCollectionChanged observable)
|
||||
{
|
||||
observable.CollectionChanged += CachedModels_CollectionChanged;
|
||||
_cachedModelsSubscription = observable;
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToDownloadableModels(IEnumerable oldValue, IEnumerable newValue)
|
||||
{
|
||||
if (_downloadableModelsSubscription is not null)
|
||||
{
|
||||
_downloadableModelsSubscription.CollectionChanged -= DownloadableModels_CollectionChanged;
|
||||
_downloadableModelsSubscription = null;
|
||||
}
|
||||
|
||||
if (newValue is INotifyCollectionChanged observable)
|
||||
{
|
||||
observable.CollectionChanged += DownloadableModels_CollectionChanged;
|
||||
_downloadableModelsSubscription = observable;
|
||||
}
|
||||
}
|
||||
|
||||
private void CachedModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateVisualStates();
|
||||
}
|
||||
|
||||
private void DownloadableModels_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
UpdateVisualStates();
|
||||
}
|
||||
|
||||
private void CachedModelsComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (_suppressSelection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_suppressSelection = true;
|
||||
var selected = CachedModelsComboBox.SelectedItem as ModelDetails;
|
||||
SetValue(SelectedModelProperty, selected);
|
||||
SelectionChanged?.Invoke(this, selected);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_suppressSelection = false;
|
||||
}
|
||||
|
||||
UpdateSelectedModelDetails();
|
||||
}
|
||||
|
||||
private void UpdateSelectedModelDetails()
|
||||
{
|
||||
if (SelectedModelDetailsPanel is null || SelectedModelDescriptionText is null || SelectedModelTagsPanel is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasCachedModels || SelectedModel is not ModelDetails model)
|
||||
{
|
||||
SelectedModelDetailsPanel.Visibility = Visibility.Collapsed;
|
||||
SelectedModelDescriptionText.Text = string.Empty;
|
||||
SelectedModelTagsPanel.Children.Clear();
|
||||
SelectedModelTagsPanel.Visibility = Visibility.Collapsed;
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedModelDetailsPanel.Visibility = Visibility.Visible;
|
||||
SelectedModelDescriptionText.Text = string.IsNullOrWhiteSpace(model.Description)
|
||||
? "No description provided."
|
||||
: model.Description;
|
||||
|
||||
SelectedModelTagsPanel.Children.Clear();
|
||||
|
||||
AddTag(GetModelSizeText(model.Size));
|
||||
AddTag(GetLicenseShortText(model.License), model.License);
|
||||
|
||||
foreach (var deviceTag in GetDeviceTags(model.HardwareAccelerators))
|
||||
{
|
||||
AddTag(deviceTag);
|
||||
}
|
||||
|
||||
SelectedModelTagsPanel.Visibility = SelectedModelTagsPanel.Children.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
void AddTag(string text, string tooltip = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text) || SelectedModelTagsPanel is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Border tag = new();
|
||||
if (Resources.TryGetValue("TagBorderStyle", out var borderStyleObj) && borderStyleObj is Style borderStyle)
|
||||
{
|
||||
tag.Style = borderStyle;
|
||||
}
|
||||
|
||||
TextBlock label = new()
|
||||
{
|
||||
Text = text,
|
||||
};
|
||||
|
||||
if (Resources.TryGetValue("TagTextStyle", out var textStyleObj) && textStyleObj is Style textStyle)
|
||||
{
|
||||
label.Style = textStyle;
|
||||
}
|
||||
|
||||
tag.Child = label;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tooltip))
|
||||
{
|
||||
ToolTipService.SetToolTip(tag, new TextBlock
|
||||
{
|
||||
Text = tooltip,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
});
|
||||
}
|
||||
|
||||
SelectedModelTagsPanel.Children.Add(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchFoundryModelListButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo processInfo = new()
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
Arguments = "-NoExit -Command \"foundry model list\"",
|
||||
UseShellExecute = true,
|
||||
};
|
||||
|
||||
Process.Start(processInfo);
|
||||
StatusText = "Opening PowerShell and running 'foundry model list'...";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusText = $"Unable to start PowerShell. {ex.Message}";
|
||||
Debug.WriteLine($"[FoundryLocalModelPicker] Failed to run 'foundry model list': {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshModelsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
RequestLoad(refresh: true);
|
||||
}
|
||||
|
||||
private void UpdateVisualStates()
|
||||
{
|
||||
LoadingIndicator.IsActive = IsLoading;
|
||||
|
||||
if (IsLoading)
|
||||
{
|
||||
VisualStateManager.GoToState(this, "ShowLoading", true);
|
||||
}
|
||||
else if (!IsAvailable)
|
||||
{
|
||||
VisualStateManager.GoToState(this, "ShowNotAvailable", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
VisualStateManager.GoToState(this, "ShowModels", true);
|
||||
}
|
||||
|
||||
if (LoadingStatusTextBlock is not null)
|
||||
{
|
||||
LoadingStatusTextBlock.Text = string.IsNullOrWhiteSpace(StatusText)
|
||||
? "Loading Foundry Local status..."
|
||||
: StatusText;
|
||||
}
|
||||
|
||||
NoModelsPanel.Visibility = HasCachedModels ? Visibility.Collapsed : Visibility.Visible;
|
||||
if (CachedModelsComboBox is not null)
|
||||
{
|
||||
CachedModelsComboBox.Visibility = HasCachedModels ? Visibility.Visible : Visibility.Collapsed;
|
||||
CachedModelsComboBox.IsEnabled = HasCachedModels;
|
||||
}
|
||||
|
||||
UpdateSelectedModelDetails();
|
||||
|
||||
Bindings.Update();
|
||||
}
|
||||
|
||||
public static string GetModelSizeText(long size)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
const long kiloByte = 1024;
|
||||
const long megaByte = kiloByte * 1024;
|
||||
const long gigaByte = megaByte * 1024;
|
||||
|
||||
if (size >= gigaByte)
|
||||
{
|
||||
return $"{size / (double)gigaByte:0.##} GB";
|
||||
}
|
||||
|
||||
if (size >= megaByte)
|
||||
{
|
||||
return $"{size / (double)megaByte:0.##} MB";
|
||||
}
|
||||
|
||||
if (size >= kiloByte)
|
||||
{
|
||||
return $"{size / (double)kiloByte:0.##} KB";
|
||||
}
|
||||
|
||||
return $"{size} B";
|
||||
}
|
||||
|
||||
public static Visibility GetModelSizeVisibility(long size)
|
||||
{
|
||||
return size > 0 ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetDeviceTags(IReadOnlyCollection<HardwareAccelerator> accelerators)
|
||||
{
|
||||
if (accelerators is null || accelerators.Count == 0)
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
HashSet<string> tags = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var accelerator in accelerators)
|
||||
{
|
||||
switch (accelerator)
|
||||
{
|
||||
case HardwareAccelerator.CPU:
|
||||
tags.Add("CPU");
|
||||
break;
|
||||
case HardwareAccelerator.GPU:
|
||||
case HardwareAccelerator.DML:
|
||||
tags.Add("GPU");
|
||||
break;
|
||||
case HardwareAccelerator.NPU:
|
||||
case HardwareAccelerator.QNN:
|
||||
tags.Add("NPU");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tags.Count > 0 ? tags.ToArray() : Array.Empty<string>();
|
||||
}
|
||||
|
||||
public static Visibility GetDeviceVisibility(IReadOnlyCollection<HardwareAccelerator> accelerators)
|
||||
{
|
||||
return GetDeviceTags(accelerators).Any() ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public static string GetLicenseShortText(string license)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(license))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var trimmed = license.Trim();
|
||||
int separatorIndex = trimmed.IndexOfAny(['(', '[', ':']);
|
||||
if (separatorIndex > 0)
|
||||
{
|
||||
trimmed = trimmed[..separatorIndex].Trim();
|
||||
}
|
||||
|
||||
if (trimmed.Length > 24)
|
||||
{
|
||||
trimmed = $"{trimmed[..24].TrimEnd()}…";
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
public static Visibility GetLicenseVisibility(string license)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(license) ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public sealed class FoundryLoadRequestedEventArgs : EventArgs
|
||||
{
|
||||
public FoundryLoadRequestedEventArgs(bool refresh)
|
||||
{
|
||||
Refresh = refresh;
|
||||
}
|
||||
|
||||
public bool Refresh { get; }
|
||||
}
|
||||
}
|
||||
@@ -3,28 +3,43 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls"
|
||||
xmlns:converters="using:Microsoft.PowerToys.Settings.UI.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Helpers"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="using:Microsoft.PowerToys.Settings.UI.Library"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:viewmodels="using:Microsoft.PowerToys.Settings.UI.ViewModels"
|
||||
x:Name="RootPage"
|
||||
AutomationProperties.LandmarkType="Main"
|
||||
mc:Ignorable="d">
|
||||
<local:NavigablePage.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.dark.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.dark.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.light.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.light.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<ImageSource x:Key="DialogHeaderImage">ms-appx:///Assets/Settings/Modules/APDialog.light.png</ImageSource>
|
||||
<ImageSource x:Key="OpenAIIconImage">ms-appx:///Assets/Settings/Icons/Models/OpenAI.light.svg</ImageSource>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
<Style x:Key="MenuFlyoutItemHeaderStyle" TargetType="MenuFlyoutItem">
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="IsEnabled" Value="False" />
|
||||
<Setter Property="IsHitTestVisible" Value="False" />
|
||||
</Style>
|
||||
|
||||
<converters:ServiceTypeToIconConverter x:Key="ServiceTypeToIconConverter" />
|
||||
<DataTemplate x:Key="AdditionalActionTemplate" x:DataType="models:AdvancedPasteAdditionalAction">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<controls:ShortcutControl
|
||||
@@ -65,171 +80,144 @@
|
||||
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||
</InfoBar.IconSource>
|
||||
</InfoBar>
|
||||
<tkcontrols:SettingsCard
|
||||
|
||||
<!-- Paste with AI -->
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="AdvancedPasteEnableAISettingsCard"
|
||||
x:Uid="AdvancedPaste_EnableAISettingsCard"
|
||||
IsEnabled="{x:Bind ViewModel.IsOnlineAIModelsDisallowedByGPO, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
|
||||
<tkcontrols:SettingsCard.HeaderIcon>
|
||||
IsEnabled="{x:Bind ViewModel.IsOnlineAIModelsDisallowedByGPO, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
|
||||
IsExpanded="{x:Bind ViewModel.IsAIEnabled, Mode=OneWay}"
|
||||
ItemsSource="{x:Bind ViewModel.PasteAIConfiguration.Providers, Mode=OneWay}">
|
||||
<tkcontrols:SettingsExpander.HeaderIcon>
|
||||
<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" />
|
||||
</tkcontrols:SettingsCard.HeaderIcon>
|
||||
<tkcontrols:SwitchPresenter TargetType="x:Boolean" Value="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}">
|
||||
<tkcontrols:Case Value="True">
|
||||
<Button x:Uid="AdvancedPaste_DisableAIButton" Click="AdvancedPaste_DisableAIButton_Click" />
|
||||
</tkcontrols:Case>
|
||||
<tkcontrols:Case Value="False">
|
||||
<Button
|
||||
x:Uid="AdvancedPaste_EnableAIButton"
|
||||
Click="AdvancedPaste_EnableAIButton_Click"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</tkcontrols:Case>
|
||||
</tkcontrols:SwitchPresenter>
|
||||
<tkcontrols:SettingsCard.Description>
|
||||
</tkcontrols:SettingsExpander.HeaderIcon>
|
||||
<ToggleSwitch
|
||||
x:Name="AdvancedPaste_EnableAIToggle"
|
||||
x:Uid="AdvancedPaste_EnableAIToggle"
|
||||
IsOn="{x:Bind ViewModel.IsAIEnabled, Mode=OneWay}"
|
||||
Toggled="AdvancedPaste_EnableAIToggle_Toggled" />
|
||||
<tkcontrols:SettingsExpander.Description>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="AdvancedPaste_EnableAISettingsCardDescription" />
|
||||
<HyperlinkButton x:Uid="AdvancedPaste_EnableAISettingsCardDescriptionLearnMore" NavigateUri="https://learn.microsoft.com/windows/powertoys/advanced-paste" />
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard.Description>
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteEnableAdvancedAI"
|
||||
x:Uid="AdvancedPaste_EnableAdvancedAI"
|
||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SemanticKernel.png}"
|
||||
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.IsAdvancedAIEnabled, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Description>
|
||||
<tkcontrols:SettingsExpander.ItemsHeader>
|
||||
<tkcontrols:SettingsCard
|
||||
Description="Add online or local models"
|
||||
Header="Model providers"
|
||||
Style="{StaticResource DefaultSettingsExpanderItemStyle}">
|
||||
<Button Content="Add model" Style="{StaticResource AccentButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout x:Name="AddProviderMenuFlyout" Opening="AddProviderMenuFlyout_Opening" />
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.ItemsHeader>
|
||||
<tkcontrols:SettingsExpander.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:PasteAIProviderDefinition">
|
||||
<tkcontrols:SettingsCard
|
||||
Description="{x:Bind ServiceType, Mode=OneWay}"
|
||||
Header="{x:Bind ModelName, Mode=OneWay}"
|
||||
HeaderIcon="{x:Bind ServiceType, Mode=OneWay, Converter={StaticResource ServiceTypeToIconConverter}}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<Button
|
||||
Padding="8"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Tag="{x:Bind}">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
Click="EditPasteAIProviderButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
Tag="{x:Bind}"
|
||||
Text="Edit" />
|
||||
<MenuFlyoutSeparator />
|
||||
<MenuFlyoutItem
|
||||
Click="RemovePasteAIProviderButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
Tag="{x:Bind}"
|
||||
Text="Remove" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</tkcontrols:SettingsExpander.ItemTemplate>
|
||||
</tkcontrols:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<!-- Activation and behavior -->
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_BehaviorSettingsGroup" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<controls:GPOInfoControl ShowWarning="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteClipboardHistoryEnabledSettingsCard"
|
||||
x:Uid="AdvancedPaste_Clipboard_History_Enabled_SettingsCard"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ClipboardHistoryEnabled, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</controls:GPOInfoControl>
|
||||
<tkcontrols:SettingsCard Name="AdvancedPasteCloseAfterLosingFocus" x:Uid="AdvancedPaste_CloseAfterLosingFocus">
|
||||
<tkcontrols:SettingsCard.HeaderIcon>
|
||||
<PathIcon Data="M 4 16.284 C 1 22.284 29 59.284 71 101.284 L 143 174.284 L 101 220.284 C 54 271.284 5 367.284 14 390.284 C 23 416.284 40 406.284 56 367.284 C 64 347.284 76 320.284 82 307.284 C 97 278.284 160 215.284 175 215.284 C 181 215.284 199 228.284 214 243.284 C 239 270.284 240 273.284 224 286.284 C 202 304.284 180 357.284 180 392.284 C 180 430.284 213 481.284 252 505.284 C 297 532.284 349 531.284 394 500.284 C 414 486.284 434 475.284 438 475.284 C 442 475.284 484 514.284 532 562.284 C 602 631.284 622 647.284 632 637.284 C 642 627.284 581 561.284 335 315.284 C 164 144.284 22 5.284 18 5.284 C 14 5.284 8 10.284 4 16.284 Z M 337 367.284 C 372 401.284 400 435.284 400 442.284 C 400 457.284 349 485.284 321 485.284 C 269 485.284 220 437.284 220 385.284 C 220 357.284 248 305.284 262 305.284 C 269 305.284 303 333.284 337 367.284 Z M 248 132.284 C 228 137.284 225 151.284 241 161.284 C 247 164.284 284 168.284 324 169.284 C 393 171.284 442 188.284 491 227.284 C 522 252.284 578 335.284 585 364.284 C 592 399.284 607 412.284 622 397.284 C 629 390.284 627 370.284 615 333.284 C 590 260.284 506 176.284 427 147.284 C 373 127.284 293 120.284 248 132.284 Z" />
|
||||
</tkcontrols:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CloseAfterLosingFocus, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteShowCustomPreviewSettingsCard"
|
||||
x:Uid="AdvancedPaste_ShowCustomPreviewSettingsCard"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowCustomPreview, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteUIActions"
|
||||
x:Uid="AdvancedPasteUI_Actions"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}">
|
||||
<Button
|
||||
x:Uid="AdvancedPasteUI_AddCustomActionButton"
|
||||
Click="AddCustomActionButton_Click"
|
||||
Style="{ThemeResource AccentButtonStyle}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="AdvancedPasteUIShortcut"
|
||||
x:Uid="AdvancedPasteUI_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.AdvancedPasteUIShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="PasteAsPlainTextShortcut" x:Uid="PasteAsPlainText_Shortcut">
|
||||
<tkcontrols:SettingsExpander.ItemsHeader>
|
||||
<InfoBar
|
||||
x:Uid="GPO_SettingIsManaged"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
|
||||
IsTabStop="{x:Bind ViewModel.ShowClipboardHistoryIsGpoConfiguredInfoBar, Mode=OneWay}"
|
||||
Severity="Informational">
|
||||
<InfoBar.IconSource>
|
||||
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||
</InfoBar.IconSource>
|
||||
</InfoBar>
|
||||
</tkcontrols:SettingsExpander.ItemsHeader>
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<tkcontrols:SettingsCard
|
||||
Name="AdvancedPasteClipboardHistoryEnabledSettingsCard"
|
||||
ContentAlignment="Left"
|
||||
IsEnabled="{x:Bind ViewModel.ClipboardHistoryEnabled, Mode=OneWay}">
|
||||
<controls:CheckBoxWithDescriptionControl x:Uid="AdvancedPaste_Clipboard_History_Enabled_SettingsCard" IsChecked="{x:Bind ViewModel.ClipboardHistoryEnabled, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="AdvancedPasteCloseAfterLosingFocus" ContentAlignment="Left">
|
||||
<CheckBox x:Uid="AdvancedPaste_CloseAfterLosingFocus" IsChecked="{x:Bind ViewModel.CloseAfterLosingFocus, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="AdvancedPasteShowCustomPreviewSettingsCard" ContentAlignment="Left">
|
||||
<controls:CheckBoxWithDescriptionControl x:Uid="AdvancedPaste_ShowCustomPreviewSettingsCard" IsChecked="{x:Bind ViewModel.ShowCustomPreview, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<!-- Built-in actions -->
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_Direct_Access_Hotkeys_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="PasteAsPlainTextShortcut"
|
||||
x:Uid="PasteAsPlainText_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.PasteAsPlainTextShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="PasteAsMarkdownShortcut" x:Uid="PasteAsMarkdown_Shortcut">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="PasteAsMarkdownShortcut"
|
||||
x:Uid="PasteAsMarkdown_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.PasteAsMarkdownShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Name="PasteAsJsonShortcut" x:Uid="PasteAsJson_Shortcut">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="PasteAsJsonShortcut"
|
||||
x:Uid="PasteAsJson_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.PasteAsJsonShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<ItemsControl
|
||||
x:Name="CustomActions"
|
||||
x:Uid="CustomActions"
|
||||
HorizontalAlignment="Stretch"
|
||||
IsEnabled="{x:Bind ViewModel.IsOpenAIEnabled, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
ItemsSource="{x:Bind ViewModel.CustomActions, Mode=OneWay}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:AdvancedPasteCustomAction">
|
||||
<tkcontrols:SettingsCard
|
||||
Margin="0,0,0,2"
|
||||
Click="EditCustomActionButton_Click"
|
||||
Description="{x:Bind Prompt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Header="{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsActionIconVisible="False"
|
||||
IsClickEnabled="True">
|
||||
<tkcontrols:SettingsCard.Resources>
|
||||
<x:Double x:Key="SettingsCardActionButtonWidth">0</x:Double>
|
||||
</tkcontrols:SettingsCard.Resources>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=Shortcut, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
x:Uid="Enable_CustomAction"
|
||||
AutomationProperties.HelpText="{x:Bind Name, Mode=OneWay}"
|
||||
IsOn="{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
OffContent=""
|
||||
OnContent="" />
|
||||
<Button
|
||||
x:Uid="More_Options_Button"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Style="{StaticResource SubtleButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="MoveUp"
|
||||
Click="ReorderButtonUp_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind CanMoveUp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="MoveDown"
|
||||
Click="ReorderButtonDown_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind CanMoveDown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<MenuFlyoutSeparator />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="RemoveItem"
|
||||
Click="DeleteCustomActionButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="true" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="More_Options_ButtonTooltip" />
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<InfoBar
|
||||
x:Uid="AdvancedPaste_ShortcutWarning"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.IsConflictingCopyShortcut, Mode=OneWay}"
|
||||
IsTabStop="{x:Bind ViewModel.IsConflictingCopyShortcut, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_Additional_Actions_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="ImageToText"
|
||||
x:Uid="ImageToText"
|
||||
DataContext="{x:Bind ViewModel.AdditionalActions.ImageToText, Mode=OneWay}">
|
||||
DataContext="{x:Bind ViewModel.AdditionalActions.ImageToText, Mode=OneWay}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<ContentControl ContentTemplate="{StaticResource AdditionalActionTemplate}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsExpander
|
||||
@@ -312,74 +300,100 @@
|
||||
IsTabStop="{x:Bind ViewModel.IsAdditionalActionConflictingCopyShortcut, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<!-- Custom actions -->
|
||||
<controls:SettingsGroup x:Uid="AdvancedPaste_Additional_Actions_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="AdvancedPasteUIActions"
|
||||
x:Uid="AdvancedPasteUI_Actions"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.IsAIEnabled, Mode=OneWay}"
|
||||
IsExpanded="True"
|
||||
ItemsSource="{x:Bind ViewModel.CustomActions, Mode=OneWay}">
|
||||
<Button
|
||||
x:Uid="AdvancedPasteUI_AddCustomActionButton"
|
||||
Click="AddCustomActionButton_Click"
|
||||
Style="{ThemeResource AccentButtonStyle}" />
|
||||
<tkcontrols:SettingsExpander.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:AdvancedPasteCustomAction">
|
||||
<tkcontrols:SettingsCard
|
||||
Margin="0,0,0,2"
|
||||
Click="EditCustomActionButton_Click"
|
||||
Description="{x:Bind Description, Mode=OneWay}"
|
||||
Header="{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsActionIconVisible="False"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<tkcontrols:SettingsCard.Resources>
|
||||
<x:Double x:Key="SettingsCardActionButtonWidth">0</x:Double>
|
||||
</tkcontrols:SettingsCard.Resources>
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock Text="{x:Bind Prompt, Mode=OneWay}" TextWrapping="Wrap" />
|
||||
</ToolTipService.ToolTip>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=Shortcut, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
x:Uid="Enable_CustomAction"
|
||||
AutomationProperties.HelpText="{x:Bind Name, Mode=OneWay}"
|
||||
IsOn="{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
OffContent=""
|
||||
OnContent="" />
|
||||
<Button
|
||||
x:Uid="More_Options_Button"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Content=""
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Style="{StaticResource SubtleButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="MoveUp"
|
||||
Click="ReorderButtonUp_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind CanMoveUp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Tag="{x:Bind}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="MoveDown"
|
||||
Click="ReorderButtonDown_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind CanMoveDown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Tag="{x:Bind}" />
|
||||
<MenuFlyoutSeparator />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="RemoveItem"
|
||||
Click="DeleteCustomActionButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="true"
|
||||
Tag="{x:Bind}" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock x:Uid="More_Options_ButtonTooltip" />
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</tkcontrols:SettingsExpander.ItemTemplate>
|
||||
</tkcontrols:SettingsExpander>
|
||||
<InfoBar
|
||||
x:Uid="AdvancedPaste_ShortcutWarning"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.IsConflictingCopyShortcut, Mode=OneWay}"
|
||||
IsTabStop="{x:Bind ViewModel.IsConflictingCopyShortcut, Mode=OneWay}"
|
||||
Severity="Warning" />
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
<controls:PageLink x:Uid="LearnMore_AdvancedPaste" Link="https://aka.ms/PowerToysOverview_AdvancedPaste" />
|
||||
</controls:SettingsPageControl.PrimaryLinks>
|
||||
</controls:SettingsPageControl>
|
||||
<ContentDialog
|
||||
x:Name="EnableAIDialog"
|
||||
x:Uid="EnableAIDialog"
|
||||
IsPrimaryButtonEnabled="False"
|
||||
IsSecondaryButtonEnabled="True"
|
||||
PrimaryButtonStyle="{StaticResource AccentButtonStyle}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<Grid RowSpacing="24">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image Margin="-24,-24,-24,0" Source="{ThemeResource DialogHeaderImage}" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap">
|
||||
<Run x:Uid="AdvancedPaste_EnableAIDialog_Description" />
|
||||
<Hyperlink NavigateUri="https://openai.com/policies/terms-of-use" TabIndex="3">
|
||||
<Run x:Uid="TermsLink" />
|
||||
</Hyperlink>
|
||||
<Run x:Uid="AIFooterSeparator" Foreground="{ThemeResource TextFillColorSecondaryBrush}">|</Run>
|
||||
<Hyperlink NavigateUri="https://openai.com/policies/privacy-policy" TabIndex="3">
|
||||
<Run x:Uid="PrivacyLink" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
<StackPanel Grid.Row="2" Orientation="Vertical">
|
||||
<TextBlock x:Uid="AdvancedPaste_EnableAIDialog_ConfigureOpenAIKey" FontWeight="SemiBold" />
|
||||
<TextBlock Grid.Row="2" TextWrapping="Wrap">
|
||||
<Run x:Uid="AdvancedPaste_EnableAIDialog_LoginIntoText" />
|
||||
<Hyperlink NavigateUri="https://platform.openai.com/api-keys">
|
||||
<Run x:Uid="AdvancedPaste_EnableAIDialog_OpenAIApiKeysOverviewText" />
|
||||
</Hyperlink>
|
||||
<LineBreak />
|
||||
<Run x:Uid="AdvancedPaste_EnableAIDialog_CreateNewKeyText" />
|
||||
<LineBreak />
|
||||
<Run x:Uid="AdvancedPaste_EnableAIDialog_NoteAICreditsText" />
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="3" ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
x:Uid="AdvancedPaste_EnableAIDialogOpenAIApiKey"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBox
|
||||
x:Name="AdvancedPaste_EnableAIDialogOpenAIApiKey"
|
||||
Grid.Column="1"
|
||||
MinWidth="248"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
TextChanged="AdvancedPaste_EnableAIDialogOpenAIApiKey_TextChanged" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</ContentDialog>
|
||||
<ContentDialog
|
||||
x:Name="CustomActionDialog"
|
||||
x:Uid="CustomActionDialog"
|
||||
@@ -396,6 +410,11 @@
|
||||
Width="340"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<TextBox
|
||||
x:Uid="AdvancedPasteUI_CustomAction_Description"
|
||||
Width="340"
|
||||
HorizontalAlignment="Left"
|
||||
Text="{Binding Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<TextBox
|
||||
x:Uid="AdvancedPasteUI_CustomAction_Prompt"
|
||||
Width="340"
|
||||
@@ -406,5 +425,169 @@
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
|
||||
<!-- Paste AI provider dialog -->
|
||||
<ContentDialog
|
||||
x:Name="PasteAIProviderConfigurationDialog"
|
||||
Title="Paste with AI provider configuration"
|
||||
Closed="PasteAIProviderConfigurationDialog_Closed"
|
||||
PrimaryButtonClick="PasteAIProviderConfigurationDialog_PrimaryButtonClick"
|
||||
PrimaryButtonStyle="{ThemeResource AccentButtonStyle}"
|
||||
PrimaryButtonText="Save"
|
||||
SecondaryButtonText="Cancel">
|
||||
<ContentDialog.Resources>
|
||||
<x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
|
||||
<x:Double x:Key="ContentDialogMaxHeight">700</x:Double>
|
||||
<StaticResource x:Key="ContentDialogTopOverlay" ResourceKey="NavigationViewContentBackground" />
|
||||
</ContentDialog.Resources>
|
||||
<ScrollViewer
|
||||
MaxHeight="550"
|
||||
Margin="-16,0,-24,-24"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel
|
||||
MinWidth="640"
|
||||
Padding="16,0,16,16"
|
||||
Spacing="16">
|
||||
<InfoBar
|
||||
x:Name="PasteAIProviderGpoInfoBar"
|
||||
x:Uid="GPO_SettingIsManaged"
|
||||
Margin="0,12,0,0"
|
||||
IsClosable="False"
|
||||
IsOpen="{x:Bind ViewModel.ShowPasteAIProviderGpoConfiguredInfoBar, Mode=OneWay}"
|
||||
IsTabStop="{x:Bind ViewModel.ShowPasteAIProviderGpoConfiguredInfoBar, Mode=OneWay}"
|
||||
Severity="Informational">
|
||||
<InfoBar.IconSource>
|
||||
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="" />
|
||||
</InfoBar.IconSource>
|
||||
</InfoBar>
|
||||
<StackPanel
|
||||
Margin="0,12,0,0"
|
||||
Orientation="Vertical"
|
||||
Spacing="8"
|
||||
Visibility="{x:Bind GetServiceLegalVisibility(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}">
|
||||
<TextBlock
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind GetServiceLegalDescription(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<StackPanel
|
||||
Margin="0,0,0,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<HyperlinkButton
|
||||
Padding="0"
|
||||
Content="{x:Bind GetServiceTermsLabel(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}"
|
||||
FontSize="12"
|
||||
NavigateUri="{x:Bind GetServiceTermsUri(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}"
|
||||
Visibility="{x:Bind GetServiceTermsVisibility(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}" />
|
||||
<HyperlinkButton
|
||||
Padding="0"
|
||||
Content="{x:Bind GetServicePrivacyLabel(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}"
|
||||
FontSize="12"
|
||||
NavigateUri="{x:Bind GetServicePrivacyUri(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}"
|
||||
Visibility="{x:Bind GetServicePrivacyVisibility(ViewModel.PasteAIProviderDraft?.ServiceType), Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Rectangle Height="1" Fill="{ThemeResource DividerStrokeColorDefaultBrush}" />
|
||||
<StackPanel
|
||||
Margin="0,8,0,48"
|
||||
Orientation="Vertical"
|
||||
Spacing="16">
|
||||
<TextBox
|
||||
x:Name="PasteAIModelNameTextBox"
|
||||
MinWidth="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
Header="Model name"
|
||||
PlaceholderText="gpt-4"
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.ModelName, Mode=TwoWay}" />
|
||||
<TextBox
|
||||
x:Name="PasteAIEndpointUrlTextBox"
|
||||
MinWidth="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
Header="Endpoint URL"
|
||||
PlaceholderText="https://your-resource.openai.azure.com/"
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.EndpointUrl, Mode=TwoWay}" />
|
||||
|
||||
<PasswordBox
|
||||
x:Name="PasteAIApiKeyPasswordBox"
|
||||
MinWidth="200"
|
||||
Header="API key"
|
||||
PlaceholderText="Enter API Key" />
|
||||
<TextBox
|
||||
x:Name="PasteAIApiVersionTextBox"
|
||||
MinWidth="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
Header="API version"
|
||||
PlaceholderText="2024-10-01"
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.ApiVersion, Mode=TwoWay}"
|
||||
Visibility="Collapsed" />
|
||||
<TextBox
|
||||
x:Name="PasteAIDeploymentNameTextBox"
|
||||
MinWidth="200"
|
||||
Header="Deployment name"
|
||||
PlaceholderText="gpt-4"
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.DeploymentName, Mode=TwoWay}" />
|
||||
<TextBox
|
||||
x:Name="PasteAISystemPromptTextBox"
|
||||
MinWidth="200"
|
||||
MinHeight="76"
|
||||
HorizontalAlignment="Stretch"
|
||||
AcceptsReturn="True"
|
||||
Header="System prompt"
|
||||
PlaceholderText="You are tasked with reformatting user's clipboard data. Use the user's instructions, and the content of their clipboard below to edit their clipboard content as they have requested it. Do not output anything else besides the reformatted clipboard content."
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.SystemPrompt, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<Grid
|
||||
x:Name="FoundryLocalPanel"
|
||||
Margin="0,8,0,0"
|
||||
Visibility="Collapsed">
|
||||
<controls:FoundryLocalModelPicker x:Name="FoundryLocalPicker" />
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
x:Name="PasteAIModelPanel"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<TextBox
|
||||
x:Name="PasteAIModelPathTextBox"
|
||||
MinWidth="200"
|
||||
HorizontalAlignment="Stretch"
|
||||
Header="Model path"
|
||||
PlaceholderText="C:\Models\phi-3.onnx"
|
||||
Text="{x:Bind ViewModel.PasteAIProviderDraft.ModelPath, Mode=TwoWay}" />
|
||||
<Button
|
||||
VerticalAlignment="Bottom"
|
||||
Click="BrowsePasteAIModelPath_Click"
|
||||
Content="{ui:FontIcon Glyph=,
|
||||
FontSize=16}"
|
||||
Style="{StaticResource SubtleButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch
|
||||
x:Name="PasteAIModerationToggle"
|
||||
x:Uid="AdvancedPaste_EnablePasteAIModerationToggle"
|
||||
IsOn="{x:Bind ViewModel.PasteAIProviderDraft.ModerationEnabled, Mode=TwoWay}"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<ToggleSwitch
|
||||
x:Name="PasteAIEnableAdvancedAICheckBox"
|
||||
IsOn="{x:Bind ViewModel.PasteAIProviderDraft.EnableAdvancedAI, Mode=TwoWay}"
|
||||
Toggled="PasteAIEnableAdvancedAICheckBox_Toggled"
|
||||
Visibility="Collapsed">
|
||||
<ToolTipService.ToolTip>
|
||||
<TextBlock Text="" TextWrapping="Wrap" />
|
||||
</ToolTipService.ToolTip>
|
||||
<ToggleSwitch.Header>
|
||||
<TextBlock>
|
||||
<Run Text="Enable Advanced AI" /> <LineBreak />
|
||||
<Run Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="Use built-in functions to handle complex tasks. Token consumption may increase." />
|
||||
</TextBlock>
|
||||
</ToggleSwitch.Header>
|
||||
</ToggleSwitch>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</ContentDialog>
|
||||
</Grid>
|
||||
</local:NavigablePage>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user