Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Github Copilot to be used with Terminal Chat #18014

Merged
merged 106 commits into from
Oct 28, 2024

Conversation

PankajBhojwani
Copy link
Contributor

Summary of the Pull Request

  • Implements GithubCopilotLLMProvider, which is an implementation of ILMProvider that leverages Github Copilot
  • Github auth flow can be initiated from the settings UI
  • Modifies the ILMProvider interface to include an IBrandingData interface, that allows a provider to specify how it wants certain elements of the TerminalChat UI to look
  • Modified the various telemetry events to include the name of the currently connected provider

Validation Steps Performed

  • Auth flow works
  • Automatic refresh of the auth tokens works, meaning you don't need to repeat the auth flow every few days

PR Checklist

  • Closes #xxx
  • Tests added/passed
  • Documentation updated
    • If checked, please file a pull request on our docs repo and link it here: #xxx
  • Schema updated (if necessary)

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm at 43/48 files (sorry for the delay!)

src/cascadia/QueryExtension/AzureLLMProvider.h Outdated Show resolved Hide resolved
src/cascadia/QueryExtension/AzureLLMProvider.h Outdated Show resolved Hide resolved
src/cascadia/QueryExtension/ExtensionPalette.h Outdated Show resolved Hide resolved
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Spacing="4">
<mux:ImageIcon Source="{x:Bind BadgeBitmapImage}"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highly amazed this worked. It should have failed because WUX and MUX image sources are different (????)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish I had an answer for this haha

src/cascadia/QueryExtension/ExtensionPalette.xaml Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalApp/TerminalPage.cpp Outdated Show resolved Hide resolved
Comment on lines 92 to 94
const auto randomStateString = unbox_value_or<hstring>(authValues.TryLookup(stateKey).try_as<IPropertyValue>(), L"");
// only handle this if the state strings match
if (randomStateString == parsedUrl.QueryParsed().GetFirstValueByName(stateKey))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we also confirm that the random state string matches the one stored on the app?

Copy link
Contributor Author

@PankajBhojwani PankajBhojwani Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand the question - randomStateString here is the one stored on the app

Base automatically changed from dev/pabhoj/featurellm_openai to feature/llm October 28, 2024 19:34
Comment on lines +1639 to +1642
authValuesJson.SetNamedValue(L"url", WDJ::JsonValue::CreateStringValue(uriString));
authValuesJson.SetNamedValue(L"state", WDJ::JsonValue::CreateStringValue(randomStateString));

_createAndSetAuthenticationForLMProvider(LLMProvider::GithubCopilot, authValuesJson.ToString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a JSON key contract between App and Provider that we should have been avoiding - what does it communicate, and why does it need to know the internal format of the auth blob?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the blob that ends up getting stored, this is the one to complete the auth flow, i.e. to hand the correct uri (which contains the necessary code to complete the authentication) and the random state string to the provider. The one that eventually gets stored has a format unknown to the App

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, this should be promoted to being a real function on an interface like IOAuthAuthenticatedProvider or similar. We don't need to do that now, but it IS still currently effectively a secret and undocumented contract (and the kind of thing I hate: using JSON to pass data from one part of the app to another (which is different from the 'opaque blob' thing, which uses JSON as an implementation detail for one component to save data about ITSELF))

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, you don't have to change the Azure and OAI ones to use the opaque blob thing. It's fine - the app already HAS to peek inside it.

const auto uriString{ uriArgs.Uri() };
if (!uriString.empty())
{
Windows::Foundation::Uri uri{ uriString };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically this will throw if the URI string is wrong. wt handle-uri foobarbaz will maybe make terminal blow up

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to fix this in a followup!

Comment on lines +1639 to +1642
authValuesJson.SetNamedValue(L"url", WDJ::JsonValue::CreateStringValue(uriString));
authValuesJson.SetNamedValue(L"state", WDJ::JsonValue::CreateStringValue(randomStateString));

_createAndSetAuthenticationForLMProvider(LLMProvider::GithubCopilot, authValuesJson.ToString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually, this should be promoted to being a real function on an interface like IOAuthAuthenticatedProvider or similar. We don't need to do that now, but it IS still currently effectively a secret and undocumented contract (and the kind of thing I hate: using JSON to pass data from one part of the app to another (which is different from the 'opaque blob' thing, which uses JSON as an implementation detail for one component to save data about ITSELF))

@DHowett DHowett merged commit b2524f9 into feature/llm Oct 28, 2024
20 checks passed
@DHowett DHowett deleted the dev/pabhoj/featurellm_capi branch October 28, 2024 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants