From 56c69f5eebb9976e6eeec0200334ae647d112324 Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Tue, 12 Dec 2023 22:46:16 +0200 Subject: [PATCH] feat: allow commit message and method name generation with Azure service --- .../GenerateGitCommitMessageAction.java | 47 ++++++++++++++----- .../completions/CompletionRequestHandler.java | 18 ++++--- .../completions/MethodNameLookupListener.java | 36 ++++++++------ .../resources/messages/codegpt.properties | 3 +- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java index 769a7ce0..91f90564 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java @@ -24,9 +24,12 @@ import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.EncodingManager; import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.completions.CompletionClientProvider; +import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; import ee.carlrobert.codegpt.settings.configuration.ConfigurationState; +import ee.carlrobert.codegpt.settings.service.ServiceType; import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; +import ee.carlrobert.codegpt.settings.state.SettingsState; import ee.carlrobert.codegpt.ui.OverlayUtil; import ee.carlrobert.llm.client.openai.completion.ErrorDetails; import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionMessage; @@ -54,11 +57,22 @@ public class GenerateGitCommitMessageAction extends AnAction { @Override public void update(@NotNull AnActionEvent event) { - var apiKeyExists = OpenAICredentialsManager.getInstance().isApiKeySet(); - event.getPresentation().setEnabled(apiKeyExists && !getCheckedFilePaths(event).isEmpty()); - event.getPresentation().setText(CodeGPTBundle.get(apiKeyExists - ? "action.generateCommitMessage.title" - : "action.generateCommitMessage.serviceWarning")); + var selectedService = SettingsState.getInstance().getSelectedService(); + if (selectedService == ServiceType.OPENAI || selectedService == ServiceType.AZURE) { + var filesSelected = !getCheckedFilePaths(event).isEmpty(); + var callAllowed = (selectedService == ServiceType.OPENAI + && OpenAICredentialsManager.getInstance().isApiKeySet()) + || (selectedService == ServiceType.AZURE + && AzureCredentialsManager.getInstance().isCredentialSet()); + event.getPresentation().setEnabled(callAllowed && filesSelected); + event.getPresentation().setText(CodeGPTBundle.get(callAllowed + ? "action.generateCommitMessage.title" + : "action.generateCommitMessage.missingCredentials")); + } else { + event.getPresentation().setEnabled(false); + event.getPresentation() + .setText(CodeGPTBundle.get("action.generateCommitMessage.serviceWarning")); + } } @Override @@ -82,14 +96,21 @@ public class GenerateGitCommitMessageAction extends AnAction { } private void generateMessage(Project project, Editor editor, String gitDiff) { - CompletionClientProvider.getOpenAIClient().getChatCompletion( - new OpenAIChatCompletionRequest.Builder(List.of( - new OpenAIChatCompletionMessage("system", - ConfigurationState.getInstance().getCommitMessagePrompt()), - new OpenAIChatCompletionMessage("user", gitDiff))) - .setModel(OpenAISettingsState.getInstance().getModel()) - .build(), - getEventListener(project, editor.getDocument())); + var request = new OpenAIChatCompletionRequest.Builder(List.of( + new OpenAIChatCompletionMessage("system", + ConfigurationState.getInstance().getCommitMessagePrompt()), + new OpenAIChatCompletionMessage("user", gitDiff))) + .setModel(OpenAISettingsState.getInstance().getModel()) + .build(); + var selectedService = SettingsState.getInstance().getSelectedService(); + if (selectedService == ServiceType.OPENAI) { + CompletionClientProvider.getOpenAIClient() + .getChatCompletion(request, getEventListener(project, editor.getDocument())); + } + if (selectedService == ServiceType.AZURE) { + CompletionClientProvider.getAzureClient() + .getChatCompletion(request, getEventListener(project, editor.getDocument())); + } } private CompletionEventListener getEventListener(Project project, Document document) { diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java index 6d960d1b..8e387185 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java @@ -52,17 +52,21 @@ public class CompletionRequestHandler { return CompletionRequestService.getInstance() .getChatCompletionAsync(conversation, message, retry, useContextualSearch, eventListener); } catch (Throwable ex) { - var errorMessage = "Something went wrong"; - if (ex instanceof TotalUsageExceededException) { - errorMessage = - "The length of the context exceeds the maximum limit that the model can handle. " - + "Try reducing the input message or maximum completion token size."; - } - completionResponseEventListener.handleError(new ErrorDetails(errorMessage), ex); + handleCallException(ex); throw ex; } } + private void handleCallException(Throwable ex) { + var errorMessage = "Something went wrong"; + if (ex instanceof TotalUsageExceededException) { + errorMessage = + "The length of the context exceeds the maximum limit that the model can handle. " + + "Try reducing the input message or maximum completion token size."; + } + completionResponseEventListener.handleError(new ErrorDetails(errorMessage), ex); + } + private class CompletionRequestWorker extends SwingWorker { private final Conversation conversation; diff --git a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java index 5f1f447f..1a0aa2fb 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java @@ -51,29 +51,35 @@ public class MethodNameLookupListener implements LookupManagerListener { LookupImpl lookup, Application application, String prompt) { - Optional.ofNullable(getCompletionResponse(prompt)) - .ifPresent(response -> { - for (var value : response.split(",")) { - application.runReadAction(() -> { - lookup.addItem( - LookupElementBuilder.create(value.trim()).withIcon(Icons.Sparkle), - PrefixMatcher.ALWAYS_TRUE); - application.invokeLater(() -> lookup.refreshUi(true, true)); - }); - } + getCompletionResponse(prompt).ifPresent(response -> { + for (var value : response.split(",")) { + application.runReadAction(() -> { + lookup.addItem( + LookupElementBuilder.create(value.trim()).withIcon(Icons.Sparkle), + PrefixMatcher.ALWAYS_TRUE); + application.invokeLater(() -> lookup.refreshUi(true, true)); }); + } + }); } - private @Nullable String getCompletionResponse(String prompt) { + // TODO: Refactor + private Optional getCompletionResponse(String prompt) { var selectedService = SettingsState.getInstance().getSelectedService(); - if (selectedService == OPENAI || selectedService == AZURE) { + if (selectedService == OPENAI) { return Optional.ofNullable(CompletionClientProvider.getOpenAIClient() .getChatCompletion( CompletionRequestProvider.buildOpenAILookupCompletionRequest(prompt)) .getChoices()) - .map(choices -> choices.get(0).getMessage().getContent()) - .orElse(null); + .map(choices -> choices.get(0).getMessage().getContent()); } - return null; + if (selectedService == AZURE) { + return Optional.ofNullable(CompletionClientProvider.getAzureClient() + .getChatCompletion( + CompletionRequestProvider.buildOpenAILookupCompletionRequest(prompt)) + .getChoices()) + .map(choices -> choices.get(0).getMessage().getContent()); + } + return Optional.empty(); } } diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index 7b5ebe9b..174c8a91 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -2,7 +2,8 @@ project.label=CodeGPT notification.group.name=CodeGPT notification group action.generateCommitMessage.title=Generate Message action.generateCommitMessage.description=Generate commit message using OpenAI service -action.generateCommitMessage.serviceWarning=Messages can only be generated with the OpenAI service. +action.generateCommitMessage.serviceWarning=Messages can only be generated with OpenAI or Azure service +action.generateCommitMessage.missingCredentials=Credentials not provided action.includeFilesInContext.title=Include In Context... action.includeFilesInContext.dialog.title=Include In Context action.includeFilesInContext.dialog.description=Choose the files that you wish to include in the final prompt