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

Switch to webview-based sign-in flow #2382

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

pkukielka
Copy link
Contributor

@pkukielka pkukielka commented Oct 3, 2024

@pkukielka pkukielka changed the title Switch to webview-based sign-iin flow Switch to webview-based sign-in flow Oct 3, 2024
@pkukielka pkukielka marked this pull request as draft October 3, 2024 15:02
Copy link
Contributor

@mkondratek mkondratek left a comment

Choose a reason for hiding this comment

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

in general looks good - I will try it in the morning 🌅

import com.sourcegraph.cody.telemetry.TelemetryV2
import com.sourcegraph.cody.vscode.InlineCompletionTriggerKind
import com.sourcegraph.utils.CodyEditorUtil

class CodyDocumentListener(val project: Project) : BulkAwareDocumentListener {

// TODO: Looks like this functionality is broken after the migration to webview
Copy link
Contributor

Choose a reason for hiding this comment

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

  • let us have a linear issue for this one

codyAccountManager.getAccounts().forEach { oldAccount ->
val token = codyAccountManager.getTokenForAccount(oldAccount)
if (token != null) {
CodyAccount(oldAccount.server).storeToken(token)
Copy link
Contributor

Choose a reason for hiding this comment

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

nice

val id: String,
val username: String,
val displayName: String?,
val avatarURL: String?
Copy link
Contributor

Choose a reason for hiding this comment

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

we do not use avatarURL anymore - I think we can remove it

Comment on lines +133 to +150
@JsonRequest("secrets/get")
fun secrets_get(params: Secrets_GetParams): CompletableFuture<String?> {
return CompletableFuture.completedFuture(
CodyAccount(SourcegraphServerPath(params.key)).getToken())
}

@JsonRequest("secrets/store")
fun secrets_store(params: Secrets_StoreParams): CompletableFuture<Null?> {
CodyAccount(SourcegraphServerPath(params.key)).storeToken(params.value)
return CompletableFuture.completedFuture(null)
}

@JsonRequest("secrets/delete")
fun secrets_delete(params: Secrets_DeleteParams): CompletableFuture<Null?> {
CodyAccount(SourcegraphServerPath(params.key)).storeToken(null)
return CompletableFuture.completedFuture(null)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe a stupid question but... is it safe? are there any security issues? would the secrets be present in the trace logs?

Copy link
Contributor

Choose a reason for hiding this comment

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

We log the secrets in the agent trace, not the log. You have to set an extra environment variable to turn on that level of logging... I think it should be fine.

We already log tokens in that file today... the ExtensionConfiguration message from JetBrains to Agent has the token in it... see build/sourcegraph/cody-agent-trace.json after a debugging session.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a s Dominic said :)

@@ -79,15 +64,4 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
notification.addAction(neverShowAgainAction);
Notifications.Bus.notify(notification);
}

private void showMissingTokenNotification() {
Copy link
Contributor

Choose a reason for hiding this comment

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

btw, I wonder... what if the token expires (or is removed)? 🤔 what will happen (with chat, with autocomplete)?

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 will test this scenario today. In general I think we should then (if user try to call some action explicitly) show cody panel, and it should be showing login panel.

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we want to keep this action? I know it is possible to export chats from History tab in the webview. Simply, this action is an actual jetbrains action and can be searched for and run from anywhere

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, for now we should keep this, and Explain, etc.

It would be a nice cleanup project later to ingest the VSCode package.json and consider wiring up those commands automatically--or at least linting that we have them.

@dominiccooney dominiccooney self-requested a review October 4, 2024 00:41
private val cardPanel = JPanel(cardLayout)
val allContentPanel: JComponent = JPanel(GridLayout(1, 1))
val allContentPanel: JComponent = JPanel(CardLayout())
private val mainPanel = JPanel(GridBagLayout())
Copy link
Contributor

Choose a reason for hiding this comment

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

We were using the cardlayout to swap between the loading, login and onboarding components.

We can't put the webview in a CardLayout because JetBrains remote doesn't render it, so we are swapping the components.

But now there are only two components to swap: Loading and webview. So we don't need this panel anymore.

Let's just have allContentPanel with whatever trivial layout (GridLayout(1,1) etc.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So this is weird, because I tried to simplify it at the start but it was not working without CardLayout.
But maybe it was error on my side, I will check again :)

}

@JsonRequest("secrets/store")
fun secrets_store(params: Secrets_StoreParams): CompletableFuture<Null?> {
Copy link
Contributor

Choose a reason for hiding this comment

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

A nullable null... Why not a nullable nullable null 🤔


@JsonNotification("window/didChangeContext")
fun window_didChangeContext(params: Window_DidChangeContextParams) {
println(params)
Copy link
Contributor

@dominiccooney dominiccooney Oct 4, 2024

Choose a reason for hiding this comment

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

Let's not spam the console. Info logging it might be fine.

Is this, in fact, important for refreshing the status bar icon? "cody.activated" will be true when the extension thinks it is good to go.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, refreshing status icon bar is part I/ know I missed but I forget to add it at the end.
Thanks, I will add it now!

@@ -0,0 +1,101 @@
package com.sourcegraph.cody.auth.depracated
Copy link
Contributor

Choose a reason for hiding this comment

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

Spelling: deprecated


@RequiresEdt
internal fun updateAccountToken(account: DeprecatedCodyAccount, newToken: String) {
service<DeprecatedCodyPersistentAccounts>().accounts = (getAccounts() - account) + account
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems tricky, maybe the method should be called addOrUpdateAccountToken or something?

@@ -172,7 +172,7 @@ class CodyAutocompleteManager {

val textDocument: TextDocument = IntelliJTextDocument(editor, project)

if (isTriggeredExplicitly && CodyAuthenticationManager.getInstance().hasNoActiveAccount()) {
if (isTriggeredExplicitly && !CodyAccount.hasActiveAccount()) {
HintManager.getInstance().showErrorHint(editor, "Cody: Sign in to use autocomplete")
Copy link
Contributor

Choose a reason for hiding this comment

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

Ugh, we should link to the sign in panel here! Maybe add a TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I think we should just show it.
I will do the changes, thanks!

@@ -1,8 +0,0 @@
package com.sourcegraph.cody.chat.actions
Copy link
Contributor

Choose a reason for hiding this comment

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

This too, I believe we should keep these commands.

@@ -12,8 +12,7 @@ class NewChatAction : DumbAwareEDTAction() {
}

override fun update(event: AnActionEvent) {
val hasActiveAccount = CodyAuthenticationManager.getInstance().hasActiveAccount()
event.presentation.isEnabled = hasActiveAccount
event.presentation.isEnabled = CodyAccount.hasActiveAccount()
Copy link
Contributor

Choose a reason for hiding this comment

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

This CodyAccount.hasActiveAccount, we should be using the flag we got from window/didChangeContext "cody.activated" instead.

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 agree in principle, but it is not as simple.
I need to also know account, in particular to be able to check if it's enterprise/pro/free, which in turn I need to properly render LLM selection in edit window.
But now I think maybe we should add additional flag to the model, and avoid this problem in the first place.
It would allow us to remove quite a bit of code on the jetbrains side.

RunOnceUtil.runOnceForProject(project, "CodyMigrateChatHistory-v2") {
ChatHistoryMigration.migrate(project)
}
RunOnceUtil.runOnceForProject(project, "AccountsToCodyMigration") {
AccountsMigration.migrate()
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious but are these guaranteed to run in this order? Is it important?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AFAIR their are, this code is synchronous.

Copy link
Contributor

@dominiccooney dominiccooney left a comment

Choose a reason for hiding this comment

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

Feedback inline, please take a look.

Approving to unblock since you have multiple sides to land.

We can go further than this, I think, by listening to window/didChangeContext and hooking a notification to the AuthStatus observer, but we can work on those in follow up patches if it is easier.

println(params)
}

@JsonNotification("globalStorage/didChange")
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's not sniff global storage for this. We should be listening to the configuration observable and pushing a semantic, application-level message to the IDE.

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.

3 participants