2024-05-09 10:32:03 -04:00
// 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.Globalization ;
using System.IO ;
using System.Net ;
2024-09-16 16:09:43 -04:00
2024-05-09 10:32:03 -04:00
using Azure ;
using Azure.AI.OpenAI ;
using ManagedCommon ;
using Microsoft.PowerToys.Settings.UI.Library ;
using Microsoft.PowerToys.Telemetry ;
using Windows.Security.Credentials ;
namespace AdvancedPaste.Helpers
{
public class AICompletionsHelper
{
// Return Response and Status code from the request.
public struct AICompletionsResponse
{
public AICompletionsResponse ( string response , int apiRequestStatus )
{
Response = response ;
ApiRequestStatus = apiRequestStatus ;
}
public string Response { get ; }
public int ApiRequestStatus { get ; }
}
private string _openAIKey ;
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
private string _modelName = "gpt-3.5-turbo-instruct" ;
2024-05-09 10:32:03 -04:00
public bool IsAIEnabled = > ! string . IsNullOrEmpty ( this . _openAIKey ) ;
public AICompletionsHelper ( )
{
this . _openAIKey = LoadOpenAIKey ( ) ;
}
public void SetOpenAIKey ( string openAIKey )
{
this . _openAIKey = openAIKey ;
}
public string GetKey ( )
{
return _openAIKey ;
}
public static string LoadOpenAIKey ( )
{
PasswordVault vault = new PasswordVault ( ) ;
try
{
PasswordCredential cred = vault . Retrieve ( "https://platform.openai.com/api-keys" , "PowerToys_AdvancedPaste_OpenAIKey" ) ;
if ( cred is not null )
{
return cred . Password . ToString ( ) ;
}
}
catch ( Exception )
{
}
return string . Empty ;
}
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
private Response < Completions > GetAICompletion ( string systemInstructions , string userMessage )
2024-05-09 10:32:03 -04:00
{
OpenAIClient azureAIClient = new OpenAIClient ( _openAIKey ) ;
var response = azureAIClient . GetCompletions (
new CompletionsOptions ( )
{
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
DeploymentName = _modelName ,
2024-05-09 10:32:03 -04:00
Prompts =
{
systemInstructions + "\n\n" + userMessage ,
} ,
Temperature = 0.01F ,
MaxTokens = 2000 ,
} ) ;
if ( response . Value . Choices [ 0 ] . FinishReason = = "length" )
{
Console . WriteLine ( "Cut off due to length constraints" ) ;
}
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
return response ;
2024-05-09 10:32:03 -04:00
}
public AICompletionsResponse AIFormatString ( string inputInstructions , string inputString )
{
string systemInstructions = $ @ "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 . ";
string userMessage = $ @ "User instructions:
{ inputInstructions }
Clipboard Content :
{ inputString }
Output :
";
string aiResponse = null ;
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
Response < Completions > rawAIResponse = null ;
2024-05-09 10:32:03 -04:00
int apiRequestStatus = ( int ) HttpStatusCode . OK ;
try
{
[AdvancedPaste]Improved telemetry (#33520)
<!-- 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
This PR improves advanced paste telemetry. Here's what's changed
- Added `AdvancedPasteClipboardItemClicked` event
- Changed `CustomFormatEvent` to only fire on successful completion and
include the number of tokens used, and the model name
Here are the goals of adding this telemtry:
- `AdvancedPasteClipboardItemClicked` helps us estimate the total number
of user who are using the clipboard history feature, which helps us
prioritize future investments and improvements in PowerToys. (This is
just regular feature usage data).
- `CustomFormatEvent` now includes number of tokens used, and the model
name. We are considering using alternative models to power Advanced
Paste (as we've heard feedback about this), and these different models
could have different token lengths. Understanding the average usage will
help us make good decisions that will benefit the most users. As well,
the model name is hard coded right now, but in the future if we do add
different AI models for completion then this will help us compare their
performance.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [X] Communication: I've discussed this with core contributors already.
If work hasn't been agreed, this work might be rejected
<!-- 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
The details above are detailed enough since this change is super small.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Ensured that PowerToys successfully built (Need help verifying the
events fire off correctly).
2024-06-27 11:42:15 -04:00
rawAIResponse = this . GetAICompletion ( systemInstructions , userMessage ) ;
aiResponse = rawAIResponse . Value . Choices [ 0 ] . Text ;
int promptTokens = rawAIResponse . Value . Usage . PromptTokens ;
int completionTokens = rawAIResponse . Value . Usage . CompletionTokens ;
PowerToysTelemetry . Log . WriteEvent ( new Telemetry . AdvancedPasteGenerateCustomFormatEvent ( promptTokens , completionTokens , _modelName ) ) ;
2024-05-09 10:32:03 -04:00
}
catch ( Azure . RequestFailedException error )
{
Logger . LogError ( "GetAICompletion failed" , error ) ;
PowerToysTelemetry . Log . WriteEvent ( new Telemetry . AdvancedPasteGenerateCustomErrorEvent ( error . Message ) ) ;
apiRequestStatus = error . Status ;
}
catch ( Exception error )
{
Logger . LogError ( "GetAICompletion failed" , error ) ;
PowerToysTelemetry . Log . WriteEvent ( new Telemetry . AdvancedPasteGenerateCustomErrorEvent ( error . Message ) ) ;
apiRequestStatus = - 1 ;
}
return new AICompletionsResponse ( aiResponse , apiRequestStatus ) ;
}
}
}