diff --git a/src/main/java/ee/carlrobert/codegpt/PluginStartupActivity.java b/src/main/java/ee/carlrobert/codegpt/PluginStartupActivity.java index 5635825a..4c780c35 100644 --- a/src/main/java/ee/carlrobert/codegpt/PluginStartupActivity.java +++ b/src/main/java/ee/carlrobert/codegpt/PluginStartupActivity.java @@ -10,8 +10,9 @@ import ee.carlrobert.codegpt.completions.you.auth.AuthenticationHandler; import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationError; import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationService; import ee.carlrobert.codegpt.completions.you.auth.response.YouAuthenticationResponse; -import ee.carlrobert.codegpt.credentials.YouCredentialsManager; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.credentials.YouCredentialManager; +import ee.carlrobert.codegpt.settings.GeneralSettings; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.ui.OverlayUtil; import org.jetbrains.annotations.NotNull; @@ -29,12 +30,8 @@ public class PluginStartupActivity implements StartupActivity { } private void handleYouServiceAuthentication() { - var settings = SettingsState.getInstance(); - if (!settings.isPreviouslySignedIn()) { - return; - } - - var password = YouCredentialsManager.getInstance().getAccountPassword(); + var settings = YouSettings.getCurrentState(); + var password = YouCredentialManager.getInstance().getCredential(); if (!settings.getEmail().isEmpty() && password != null && !password.isEmpty()) { YouAuthenticationService.getInstance() .signInAsync(settings.getEmail(), password, new AuthenticationHandler() { diff --git a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java index 91707521..498ad797 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/GenerateGitCommitMessageAction.java @@ -25,9 +25,9 @@ import ee.carlrobert.codegpt.EncodingManager; import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.completions.CompletionRequestService; import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; -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.completion.CompletionEventListener; @@ -53,11 +53,11 @@ public class GenerateGitCommitMessageAction extends AnAction { @Override public void update(@NotNull AnActionEvent event) { - var selectedService = SettingsState.getInstance().getSelectedService(); + var selectedService = GeneralSettings.getCurrentState().getSelectedService(); if (selectedService == ServiceType.OPENAI || selectedService == ServiceType.AZURE) { var filesSelected = !getReferencedFilePaths(event).isEmpty(); var callAllowed = (selectedService == ServiceType.OPENAI - && OpenAICredentialsManager.getInstance().isApiKeySet()) + && OpenAICredentialManager.getInstance().isCredentialSet()) || (selectedService == ServiceType.AZURE && AzureCredentialsManager.getInstance().isCredentialSet()); event.getPresentation().setEnabled(callAllowed && filesSelected); diff --git a/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java b/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java index 9d724cce..e4b9c6af 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/IncludeFilesInContextAction.java @@ -2,6 +2,8 @@ package ee.carlrobert.codegpt.actions; import static com.intellij.openapi.actionSystem.CommonDataKeys.VIRTUAL_FILE_ARRAY; import static com.intellij.openapi.ui.DialogWrapper.OK_EXIT_CODE; +import static ee.carlrobert.codegpt.settings.IncludedFilesSettingsState.DEFAULT_PROMPT_TEMPLATE; +import static ee.carlrobert.codegpt.settings.IncludedFilesSettingsState.DEFAULT_REPEATABLE_CONTEXT; import static java.lang.String.format; import com.intellij.openapi.actionSystem.AnAction; @@ -24,7 +26,7 @@ import com.intellij.util.ui.UI.PanelFactory; import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.CodeGPTKeys; import ee.carlrobert.codegpt.EncodingManager; -import ee.carlrobert.codegpt.settings.state.IncludedFilesSettingsState; +import ee.carlrobert.codegpt.settings.IncludedFilesSettings; import ee.carlrobert.codegpt.ui.UIUtil; import ee.carlrobert.codegpt.ui.checkbox.FileCheckboxTree; import ee.carlrobert.codegpt.ui.checkbox.PsiElementCheckboxTree; @@ -70,7 +72,7 @@ public class IncludeFilesInContextAction extends AnAction { } }); - var includedFilesSettings = IncludedFilesSettingsState.getInstance(); + var includedFilesSettings = IncludedFilesSettings.getCurrentState(); var promptTemplateTextArea = UIUtil.createTextArea(includedFilesSettings.getPromptTemplate()); var repeatableContextTextArea = UIUtil.createTextArea(includedFilesSettings.getRepeatableContext()); @@ -225,12 +227,11 @@ public class IncludeFilesInContextAction extends AnAction { var restoreButton = new JButton( CodeGPTBundle.get("action.includeFilesInContext.dialog.restoreToDefaults.label")); restoreButton.addActionListener(e -> { - var includedFilesSettings = IncludedFilesSettingsState.getInstance(); - includedFilesSettings.setPromptTemplate(IncludedFilesSettingsState.DEFAULT_PROMPT_TEMPLATE); - includedFilesSettings.setRepeatableContext( - IncludedFilesSettingsState.DEFAULT_REPEATABLE_CONTEXT); - promptTemplateTextArea.setText(IncludedFilesSettingsState.DEFAULT_PROMPT_TEMPLATE); - repeatableContextTextArea.setText(IncludedFilesSettingsState.DEFAULT_REPEATABLE_CONTEXT); + var includedFilesSettings = IncludedFilesSettings.getCurrentState(); + includedFilesSettings.setPromptTemplate(DEFAULT_PROMPT_TEMPLATE); + includedFilesSettings.setRepeatableContext(DEFAULT_REPEATABLE_CONTEXT); + promptTemplateTextArea.setText(DEFAULT_PROMPT_TEMPLATE); + repeatableContextTextArea.setText(DEFAULT_REPEATABLE_CONTEXT); }); return restoreButton; } diff --git a/src/main/java/ee/carlrobert/codegpt/actions/OpenSettingsAction.java b/src/main/java/ee/carlrobert/codegpt/actions/OpenSettingsAction.java index 8cc25e64..04d82265 100644 --- a/src/main/java/ee/carlrobert/codegpt/actions/OpenSettingsAction.java +++ b/src/main/java/ee/carlrobert/codegpt/actions/OpenSettingsAction.java @@ -5,7 +5,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.ShowSettingsUtil; import ee.carlrobert.codegpt.CodeGPTBundle; -import ee.carlrobert.codegpt.settings.SettingsConfigurable; +import ee.carlrobert.codegpt.settings.GeneralSettingsConfigurable; import org.jetbrains.annotations.NotNull; public class OpenSettingsAction extends AnAction { @@ -18,6 +18,7 @@ public class OpenSettingsAction extends AnAction { @Override public void actionPerformed(@NotNull AnActionEvent e) { - ShowSettingsUtil.getInstance().showSettingsDialog(e.getProject(), SettingsConfigurable.class); + ShowSettingsUtil.getInstance() + .showSettingsDialog(e.getProject(), GeneralSettingsConfigurable.class); } } diff --git a/src/main/java/ee/carlrobert/codegpt/codecompletions/CallDebouncer.java b/src/main/java/ee/carlrobert/codegpt/codecompletions/CallDebouncer.java index d9085240..5af69500 100644 --- a/src/main/java/ee/carlrobert/codegpt/codecompletions/CallDebouncer.java +++ b/src/main/java/ee/carlrobert/codegpt/codecompletions/CallDebouncer.java @@ -5,7 +5,7 @@ import static ee.carlrobert.codegpt.settings.service.ServiceType.LLAMA_CPP; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.project.Project; import ee.carlrobert.codegpt.CodeGPTBundle; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -35,9 +35,10 @@ public class CallDebouncer { Future prev = delayedMap.put(key, scheduler.schedule(() -> { try { cancelPreviousCall(); - var progressIndicator = LLAMA_CPP.equals(SettingsState.getInstance().getSelectedService()) - ? createProgressIndicator() - : null; + var progressIndicator = + LLAMA_CPP.equals(GeneralSettings.getCurrentState().getSelectedService()) + ? createProgressIndicator() + : null; currentCall.set(runnable.call(progressIndicator)); } finally { delayedMap.remove(key); diff --git a/src/main/java/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestProvider.java b/src/main/java/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestProvider.java index 728f7350..49a6f25a 100644 --- a/src/main/java/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestProvider.java +++ b/src/main/java/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestProvider.java @@ -1,7 +1,7 @@ package ee.carlrobert.codegpt.codecompletions; import ee.carlrobert.codegpt.completions.llama.LlamaModel; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; import ee.carlrobert.llm.client.llama.completion.LlamaCompletionRequest; import ee.carlrobert.llm.client.openai.completion.request.OpenAITextCompletionRequest; import javax.annotation.ParametersAreNonnullByDefault; @@ -38,7 +38,7 @@ public class CodeCompletionRequestProvider { } private InfillPromptTemplate getLlamaInfillPromptTemplate() { - var settings = LlamaSettingsState.getInstance(); + var settings = LlamaSettings.getCurrentState(); if (!settings.isRunLocalServer()) { return settings.getRemoteModelInfillPromptTemplate(); } diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionClientProvider.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionClientProvider.java index 4afcbbcd..a55a32cb 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionClientProvider.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionClientProvider.java @@ -5,16 +5,15 @@ import static java.lang.String.format; import ee.carlrobert.codegpt.CodeGPTPlugin; import ee.carlrobert.codegpt.completions.you.YouUserManager; import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; -import ee.carlrobert.codegpt.credentials.LlamaCredentialsManager; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; -import ee.carlrobert.codegpt.settings.advanced.AdvancedSettingsState; -import ee.carlrobert.codegpt.settings.state.AzureSettingsState; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; +import ee.carlrobert.codegpt.credentials.LlamaCredentialManager; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import ee.carlrobert.codegpt.settings.advanced.AdvancedSettings; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import ee.carlrobert.llm.client.azure.AzureClient; import ee.carlrobert.llm.client.azure.AzureCompletionRequestParams; import ee.carlrobert.llm.client.llama.LlamaClient; -import ee.carlrobert.llm.client.llama.LlamaClient.Builder; import ee.carlrobert.llm.client.openai.OpenAIClient; import ee.carlrobert.llm.client.you.UTMParameters; import ee.carlrobert.llm.client.you.YouClient; @@ -27,8 +26,8 @@ import okhttp3.OkHttpClient; public class CompletionClientProvider { public static OpenAIClient getOpenAIClient() { - var settings = OpenAISettingsState.getInstance(); - var builder = new OpenAIClient.Builder(OpenAICredentialsManager.getInstance().getApiKey()) + var settings = OpenAISettings.getCurrentState(); + var builder = new OpenAIClient.Builder(OpenAICredentialManager.getInstance().getCredential()) .setOrganization(settings.getOrganization()); var baseHost = settings.getBaseHost(); if (baseHost != null) { @@ -38,12 +37,13 @@ public class CompletionClientProvider { } public static AzureClient getAzureClient() { - var settings = AzureSettingsState.getInstance(); + var settings = AzureSettings.getCurrentState(); var params = new AzureCompletionRequestParams( settings.getResourceName(), settings.getDeploymentId(), settings.getApiVersion()); - var builder = new AzureClient.Builder(AzureCredentialsManager.getInstance().getSecret(), params) + var builder = new AzureClient + .Builder(AzureCredentialsManager.getInstance().getCredential(), params) .setActiveDirectoryAuthentication(settings.isUseAzureActiveDirectoryAuthentication()); var baseHost = settings.getBaseHost(); if (baseHost != null) { @@ -74,12 +74,12 @@ public class CompletionClientProvider { } public static LlamaClient getLlamaClient() { - LlamaSettingsState llamaSettingsState = LlamaSettingsState.getInstance(); - Builder builder = new Builder() - .setPort(llamaSettingsState.getServerPort()); - if (!llamaSettingsState.isRunLocalServer()) { - builder.setHost(llamaSettingsState.getBaseHost()); - String apiKey = LlamaCredentialsManager.getInstance().getApiKey(); + var llamaSettings = LlamaSettings.getCurrentState(); + var builder = new LlamaClient.Builder() + .setPort(llamaSettings.getServerPort()); + if (!llamaSettings.isRunLocalServer()) { + builder.setHost(llamaSettings.getBaseHost()); + String apiKey = LlamaCredentialManager.getInstance().getCredential(); if (apiKey != null && !apiKey.isBlank()) { builder.setApiKey(apiKey); } @@ -89,7 +89,7 @@ public class CompletionClientProvider { private static OkHttpClient.Builder getDefaultClientBuilder() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); - var advancedSettings = AdvancedSettingsState.getInstance(); + var advancedSettings = AdvancedSettings.getCurrentState(); var proxyHost = advancedSettings.getProxyHost(); var proxyPort = advancedSettings.getProxyPort(); if (!proxyHost.isEmpty() && proxyPort != 0) { diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java index 9a39c79b..06e8ab4e 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestHandler.java @@ -1,7 +1,8 @@ package ee.carlrobert.codegpt.completions; import com.intellij.openapi.diagnostic.Logger; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; +import ee.carlrobert.codegpt.settings.GeneralSettingsState; import ee.carlrobert.codegpt.telemetry.TelemetryAction; import ee.carlrobert.llm.client.openai.completion.ErrorDetails; import ee.carlrobert.llm.client.you.completion.YouCompletionEventListener; @@ -42,7 +43,7 @@ public class CompletionRequestHandler { private EventSource startCall( CallParameters callParameters, - CompletionEventListener eventListener) { + CompletionEventListener eventListener) { try { return CompletionRequestService.getInstance() .getChatCompletionAsync(callParameters, useContextualSearch, eventListener); @@ -71,7 +72,7 @@ public class CompletionRequestHandler { } protected Void doInBackground() { - var settings = SettingsState.getInstance(); + var settings = GeneralSettings.getCurrentState(); try { eventSource = startCall(callParameters, new YouRequestCompletionEventListener()); } catch (TotalUsageExceededException e) { @@ -124,7 +125,7 @@ public class CompletionRequestHandler { } } - private void sendInfo(SettingsState settings) { + private void sendInfo(GeneralSettingsState settings) { TelemetryAction.COMPLETION.createActionMessage() .property("conversationId", callParameters.getConversation().getId().toString()) .property("model", callParameters.getConversation().getModel()) diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java index 2913274e..7c62427f 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestProvider.java @@ -14,13 +14,13 @@ import ee.carlrobert.codegpt.completions.llama.PromptTemplate; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.ConversationsState; import ee.carlrobert.codegpt.conversations.message.Message; +import ee.carlrobert.codegpt.settings.GeneralSettings; +import ee.carlrobert.codegpt.settings.IncludedFilesSettings; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; -import ee.carlrobert.codegpt.settings.state.IncludedFilesSettingsState; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; -import ee.carlrobert.codegpt.settings.state.YouSettingsState; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.telemetry.core.configuration.TelemetryConfiguration; import ee.carlrobert.codegpt.telemetry.core.service.UserId; import ee.carlrobert.embedding.EmbeddingsService; @@ -51,9 +51,6 @@ public class CompletionRequestProvider { public static final String FIX_COMPILE_ERRORS_SYSTEM_PROMPT = getResourceContent( "/prompts/fix-compile-errors.txt"); - public static final String INLINE_COMPLETION_PROMPT = getResourceContent( - "/prompts/inline-completion-prompt.txt"); - private final EncodingManager encodingManager = EncodingManager.getInstance(); private final EmbeddingsService embeddingsService; private final Conversation conversation; @@ -67,7 +64,7 @@ public class CompletionRequestProvider { public static String getPromptWithContext(List referencedFiles, String userPrompt) { - var includedFilesSettings = IncludedFilesSettingsState.getInstance(); + var includedFilesSettings = IncludedFilesSettings.getCurrentState(); var repeatableContext = referencedFiles.stream() .map(item -> includedFilesSettings.getRepeatableContext() .replace("{FILE_PATH}", item.getFilePath()) @@ -89,7 +86,7 @@ public class CompletionRequestProvider { new OpenAIChatCompletionMessage("system", getResourceContent("/prompts/method-name-generator.txt")), new OpenAIChatCompletionMessage("user", context))) - .setModel(OpenAISettingsState.getInstance().getModel()) + .setModel(OpenAISettings.getCurrentState().getModel()) .setStream(false) .build(); } @@ -104,7 +101,7 @@ public class CompletionRequestProvider { public LlamaCompletionRequest buildLlamaCompletionRequest( Message message, ConversationType conversationType) { - var settings = LlamaSettingsState.getInstance(); + var settings = LlamaSettings.getCurrentState(); PromptTemplate promptTemplate; if (settings.isRunLocalServer()) { promptTemplate = settings.isUseCustomModel() @@ -136,7 +133,7 @@ public class CompletionRequestProvider { public YouCompletionRequest buildYouCompletionRequest(Message message) { var requestBuilder = new YouCompletionRequest.Builder(message.getPrompt()) - .setUseGPT4Model(YouSettingsState.getInstance().isUseGPT4Model()) + .setUseGPT4Model(YouSettings.getCurrentState().isUseGPT4Model()) .setChatHistory(conversation.getMessages().stream() .map(prevMessage -> new YouCompletionRequestMessage( prevMessage.getPrompt(), @@ -207,7 +204,8 @@ public class CompletionRequestProvider { boolean useContextualSearch) { var messages = buildMessages(callParameters, useContextualSearch); - if (model == null || SettingsState.getInstance().getSelectedService() == ServiceType.YOU) { + if (model == null + || GeneralSettings.getCurrentState().getSelectedService() == ServiceType.YOU) { return messages; } diff --git a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java index 00048424..2070ec53 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/CompletionRequestService.java @@ -10,11 +10,11 @@ import com.intellij.openapi.components.Service; import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestProvider; import ee.carlrobert.codegpt.codecompletions.InfillRequestDetails; import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; -import ee.carlrobert.codegpt.settings.state.AzureSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionMessage; import ee.carlrobert.llm.client.openai.completion.request.OpenAIChatCompletionRequest; import ee.carlrobert.llm.completion.CompletionEventListener; @@ -35,11 +35,11 @@ public final class CompletionRequestService { public EventSource getChatCompletionAsync( CallParameters callParameters, boolean useContextualSearch, - CompletionEventListener eventListener) { + CompletionEventListener eventListener) { var requestProvider = new CompletionRequestProvider(callParameters.getConversation()); - switch (SettingsState.getInstance().getSelectedService()) { + switch (GeneralSettings.getCurrentState().getSelectedService()) { case OPENAI: - var openAISettings = OpenAISettingsState.getInstance(); + var openAISettings = OpenAISettings.getCurrentState(); return CompletionClientProvider.getOpenAIClient().getChatCompletionAsync( requestProvider.buildOpenAIChatCompletionRequest( openAISettings.getModel(), @@ -48,7 +48,7 @@ public final class CompletionRequestService { openAISettings.isUsingCustomPath() ? openAISettings.getPath() : null), eventListener); case AZURE: - var azureSettings = AzureSettingsState.getInstance(); + var azureSettings = AzureSettings.getCurrentState(); return CompletionClientProvider.getAzureClient().getChatCompletionAsync( requestProvider.buildOpenAIChatCompletionRequest( null, @@ -73,9 +73,9 @@ public final class CompletionRequestService { public EventSource getCodeCompletionAsync( InfillRequestDetails requestDetails, - CompletionEventListener eventListener) { + CompletionEventListener eventListener) { var requestProvider = new CodeCompletionRequestProvider(requestDetails); - switch (SettingsState.getInstance().getSelectedService()) { + switch (GeneralSettings.getCurrentState().getSelectedService()) { case OPENAI: return CompletionClientProvider.getOpenAIClient() .getCompletionAsync(requestProvider.buildOpenAIRequest(), eventListener); @@ -94,9 +94,9 @@ public final class CompletionRequestService { new OpenAIChatCompletionMessage("system", ConfigurationSettings.getCurrentState().getCommitMessagePrompt()), new OpenAIChatCompletionMessage("user", prompt))) - .setModel(OpenAISettingsState.getInstance().getModel()) + .setModel(OpenAISettings.getCurrentState().getModel()) .build(); - var selectedService = SettingsState.getInstance().getSelectedService(); + var selectedService = GeneralSettings.getCurrentState().getSelectedService(); if (selectedService == OPENAI) { CompletionClientProvider.getOpenAIClient().getChatCompletionAsync(request, eventListener); } @@ -106,7 +106,7 @@ public final class CompletionRequestService { } public Optional getLookupCompletion(String prompt) { - var selectedService = SettingsState.getInstance().getSelectedService(); + var selectedService = GeneralSettings.getCurrentState().getSelectedService(); if (selectedService == YOU || selectedService == LLAMA_CPP) { return Optional.empty(); } @@ -123,12 +123,12 @@ public final class CompletionRequestService { } public boolean isRequestAllowed() { - var selectedService = SettingsState.getInstance().getSelectedService(); + var selectedService = GeneralSettings.getCurrentState().getSelectedService(); if (selectedService == AZURE) { return AzureCredentialsManager.getInstance().isCredentialSet(); } if (selectedService == OPENAI) { - return OpenAICredentialsManager.getInstance().isApiKeySet(); + return OpenAICredentialManager.getInstance().isCredentialSet(); } return true; } diff --git a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java index 3f0c6906..a5d4ffd7 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/MethodNameLookupListener.java @@ -10,7 +10,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiUtilCore; import ee.carlrobert.codegpt.Icons; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings; import java.util.Optional; import org.jetbrains.annotations.Nullable; @@ -21,10 +21,10 @@ public class MethodNameLookupListener implements LookupManagerListener { public void activeLookupChanged(@Nullable Lookup oldLookup, @Nullable Lookup newLookup) { var application = ApplicationManager.getApplication(); var configuration = ConfigurationSettings.getCurrentState(); - var credentialsManager = OpenAICredentialsManager.getInstance(); + var credentialsManager = OpenAICredentialManager.getInstance(); if (!configuration.isMethodNameGenerationEnabled() - || !credentialsManager.isApiKeySet() + || !credentialsManager.isCredentialSet() || !(newLookup instanceof LookupImpl)) { return; } diff --git a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java index 34568997..8d734d2f 100644 --- a/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java +++ b/src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerAgent.java @@ -17,8 +17,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.CodeGPTPlugin; -import ee.carlrobert.codegpt.settings.service.ServerProgressPanel; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.llama.form.ServerProgressPanel; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -130,7 +130,7 @@ public final class LlamaServerAgent implements Disposable { if ("HTTP server listening".equals(serverMessage.getMessage())) { LOG.info("Server up and running!"); - LlamaSettingsState.getInstance().setServerPort(port); + LlamaSettings.getCurrentState().setServerPort(port); onSuccess.run(); } } catch (Exception ignore) { diff --git a/src/main/java/ee/carlrobert/codegpt/conversations/ConversationService.java b/src/main/java/ee/carlrobert/codegpt/conversations/ConversationService.java index bc73c737..c5ec8641 100644 --- a/src/main/java/ee/carlrobert/codegpt/conversations/ConversationService.java +++ b/src/main/java/ee/carlrobert/codegpt/conversations/ConversationService.java @@ -6,11 +6,11 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.Service; import ee.carlrobert.codegpt.completions.CallParameters; import ee.carlrobert.codegpt.conversations.message.Message; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; -import ee.carlrobert.codegpt.settings.state.AzureSettingsState; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Comparator; @@ -42,13 +42,13 @@ public final class ConversationService { } public Conversation createConversation(String clientCode) { - var settings = SettingsState.getInstance(); var conversation = new Conversation(); conversation.setId(UUID.randomUUID()); conversation.setClientCode(clientCode); conversation.setCreatedOn(LocalDateTime.now()); conversation.setUpdatedOn(LocalDateTime.now()); - conversation.setModel(getModelForSelectedService(settings.getSelectedService())); + conversation.setModel(getModelForSelectedService( + GeneralSettings.getCurrentState().getSelectedService())); return conversation; } @@ -111,7 +111,7 @@ public final class ConversationService { } public Conversation startConversation() { - var completionCode = SettingsState.getInstance().getSelectedService().getCompletionCode(); + var completionCode = GeneralSettings.getCurrentState().getSelectedService().getCompletionCode(); var conversation = createConversation(completionCode); conversationState.setCurrentConversation(conversation); addConversation(conversation); @@ -189,13 +189,13 @@ public final class ConversationService { private static String getModelForSelectedService(ServiceType serviceType) { switch (serviceType) { case OPENAI: - return OpenAISettingsState.getInstance().getModel(); + return OpenAISettings.getCurrentState().getModel(); case AZURE: - return AzureSettingsState.getInstance().getDeploymentId(); + return AzureSettings.getCurrentState().getDeploymentId(); case YOU: return "YouCode"; case LLAMA_CPP: - var llamaSettings = LlamaSettingsState.getInstance(); + var llamaSettings = LlamaSettings.getCurrentState(); return llamaSettings.isUseCustomModel() ? llamaSettings.getCustomLlamaModelPath() : llamaSettings.getHuggingFaceModel().getCode(); diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/AbstractCredentialsManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/AbstractCredentialsManager.java new file mode 100644 index 00000000..937c3d6e --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/credentials/AbstractCredentialsManager.java @@ -0,0 +1,52 @@ +package ee.carlrobert.codegpt.credentials; + +import com.intellij.credentialStore.CredentialAttributes; +import com.intellij.credentialStore.CredentialAttributesKt; +import com.intellij.ide.passwordSafe.PasswordSafe; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.jetbrains.annotations.Nullable; + +abstract class AbstractCredentialsManager { + + private static final PasswordSafe passwordSafe = PasswordSafe.getInstance(); + + private final Map credentialMapping; + private final Map credentialCache = new ConcurrentHashMap<>(); + + protected AbstractCredentialsManager(String... keys) { + credentialMapping = Stream.of(keys).collect(Collectors.toConcurrentMap( + key -> key, + key -> new CredentialAttributes(CredentialAttributesKt.generateServiceName("CodeGPT", key)) + )); + } + + public abstract boolean isCredentialSet(); + + protected boolean isCredentialSet(String key) { + var credential = getCredential(key); + return credential != null && !credential.isEmpty(); + } + + public abstract String getCredential(); + + protected @Nullable String getCredential(String key) { + String cachedCredential = credentialCache.get(key); + if (cachedCredential != null) { + return cachedCredential; + } + + String credential = passwordSafe.getPassword(credentialMapping.get(key)); + if (credential != null) { + credentialCache.put(key, credential); + } + return credential; + } + + protected void setCredential(String key, String credential) { + passwordSafe.setPassword(credentialMapping.get(key), credential); + credentialCache.put(key, credential); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/AzureCredentialsManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/AzureCredentialsManager.java index bbee6592..f91a4455 100644 --- a/src/main/java/ee/carlrobert/codegpt/credentials/AzureCredentialsManager.java +++ b/src/main/java/ee/carlrobert/codegpt/credentials/AzureCredentialsManager.java @@ -1,70 +1,52 @@ package ee.carlrobert.codegpt.credentials; -import com.intellij.credentialStore.CredentialAttributes; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.Service; -import ee.carlrobert.codegpt.settings.state.AzureSettingsState; -import org.jetbrains.annotations.Nullable; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; @Service -public final class AzureCredentialsManager { +public final class AzureCredentialsManager extends AbstractCredentialsManager { - private static final CredentialAttributes azureOpenAIApiKeyCredentialAttributes = - CredentialsUtil.createCredentialAttributes("AZURE_OPENAI_API_KEY"); - private static final CredentialAttributes azureActiveDirectoryTokenCredentialAttributes = - CredentialsUtil.createCredentialAttributes("AZURE_ACTIVE_DIRECTORY_TOKEN"); - - private String azureOpenAIApiKey; - private String azureActiveDirectoryToken; + public static final String API_KEY = "AZURE_OPENAI_API_KEY"; + public static final String ACTIVE_DIRECTORY_TOKEN = "AZURE_ACTIVE_DIRECTORY_TOKEN"; private AzureCredentialsManager() { - azureOpenAIApiKey = CredentialsUtil.getPassword(azureOpenAIApiKeyCredentialAttributes); - azureActiveDirectoryToken = - CredentialsUtil.getPassword(azureActiveDirectoryTokenCredentialAttributes); + super(API_KEY, ACTIVE_DIRECTORY_TOKEN); } public static AzureCredentialsManager getInstance() { return ApplicationManager.getApplication().getService(AzureCredentialsManager.class); } - public String getSecret() { - return AzureSettingsState.getInstance().isUseAzureActiveDirectoryAuthentication() - ? azureActiveDirectoryToken - : azureOpenAIApiKey; - } - - public @Nullable String getAzureOpenAIApiKey() { - return azureOpenAIApiKey; - } - - public void setApiKey(String azureOpenAIApiKey) { - this.azureOpenAIApiKey = azureOpenAIApiKey; - CredentialsUtil.setPassword(azureOpenAIApiKeyCredentialAttributes, azureOpenAIApiKey); - } - - public @Nullable String getAzureActiveDirectoryToken() { - return azureActiveDirectoryToken; - } - - public void setAzureActiveDirectoryToken(String azureActiveDirectoryToken) { - this.azureActiveDirectoryToken = azureActiveDirectoryToken; - CredentialsUtil.setPassword( - azureActiveDirectoryTokenCredentialAttributes, - azureActiveDirectoryToken); - } - + @Override public boolean isCredentialSet() { - if (AzureSettingsState.getInstance().isUseAzureApiKeyAuthentication()) { - return isKeySet(); + if (AzureSettings.getCurrentState().isUseAzureApiKeyAuthentication()) { + return isCredentialSet(ACTIVE_DIRECTORY_TOKEN); } - return isTokenSet(); + return isCredentialSet(API_KEY); } - private boolean isTokenSet() { - return azureActiveDirectoryToken != null && !azureActiveDirectoryToken.isEmpty(); + @Override + public String getCredential() { + if (AzureSettings.getCurrentState().isUseAzureActiveDirectoryAuthentication()) { + return getActiveDirectoryToken(); + } + return getApiKey(); } - private boolean isKeySet() { - return azureOpenAIApiKey != null && !azureOpenAIApiKey.isEmpty(); + public void setApiKey(String apiKey) { + setCredential(API_KEY, apiKey); + } + + public String getApiKey() { + return getCredential(API_KEY); + } + + public void setActiveDirectoryToken(String activeDirectoryToken) { + setCredential(ACTIVE_DIRECTORY_TOKEN, activeDirectoryToken); + } + + public String getActiveDirectoryToken() { + return getCredential(ACTIVE_DIRECTORY_TOKEN); } } \ No newline at end of file diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/CredentialsUtil.java b/src/main/java/ee/carlrobert/codegpt/credentials/CredentialsUtil.java deleted file mode 100644 index bf187d85..00000000 --- a/src/main/java/ee/carlrobert/codegpt/credentials/CredentialsUtil.java +++ /dev/null @@ -1,23 +0,0 @@ -package ee.carlrobert.codegpt.credentials; - -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.credentialStore.CredentialAttributesKt; -import com.intellij.ide.passwordSafe.PasswordSafe; -import org.jetbrains.annotations.Nullable; - -public class CredentialsUtil { - - private static final PasswordSafe passwordSafe = PasswordSafe.getInstance(); - - public static CredentialAttributes createCredentialAttributes(String key) { - return new CredentialAttributes(CredentialAttributesKt.generateServiceName("CodeGPT", key)); - } - - public static void setPassword(CredentialAttributes credentialAttributes, String password) { - passwordSafe.setPassword(credentialAttributes, password); - } - - public static @Nullable String getPassword(CredentialAttributes credentialAttributes) { - return passwordSafe.getPassword(credentialAttributes); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialManager.java new file mode 100644 index 00000000..ae47dbdc --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialManager.java @@ -0,0 +1,16 @@ +package ee.carlrobert.codegpt.credentials; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; + +@Service +public final class LlamaCredentialManager extends SingleCredentialManager { + + private LlamaCredentialManager() { + super("LLAMA_API_KEY"); + } + + public static LlamaCredentialManager getInstance() { + return ApplicationManager.getApplication().getService(LlamaCredentialManager.class); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialsManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialsManager.java deleted file mode 100644 index e4e9c1e8..00000000 --- a/src/main/java/ee/carlrobert/codegpt/credentials/LlamaCredentialsManager.java +++ /dev/null @@ -1,36 +0,0 @@ -package ee.carlrobert.codegpt.credentials; - -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.Service; -import org.jetbrains.annotations.Nullable; - -@Service -public final class LlamaCredentialsManager { - - private static final CredentialAttributes llamaApiKeyCredentialAttributes = - CredentialsUtil.createCredentialAttributes("LLAMA_API_KEY"); - - private String llamaApiKey; - - private LlamaCredentialsManager() { - llamaApiKey = CredentialsUtil.getPassword(llamaApiKeyCredentialAttributes); - } - - public static LlamaCredentialsManager getInstance() { - return ApplicationManager.getApplication().getService(LlamaCredentialsManager.class); - } - - public boolean isApiKeySet() { - return llamaApiKey != null && !llamaApiKey.isEmpty(); - } - - public @Nullable String getApiKey() { - return llamaApiKey; - } - - public void setApiKey(String llamaApiKey) { - this.llamaApiKey = llamaApiKey; - CredentialsUtil.setPassword(llamaApiKeyCredentialAttributes, llamaApiKey); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialManager.java new file mode 100644 index 00000000..bf23b4b7 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialManager.java @@ -0,0 +1,16 @@ +package ee.carlrobert.codegpt.credentials; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; + +@Service +public final class OpenAICredentialManager extends SingleCredentialManager { + + private OpenAICredentialManager() { + super("OPENAI_API_KEY"); + } + + public static OpenAICredentialManager getInstance() { + return ApplicationManager.getApplication().getService(OpenAICredentialManager.class); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialsManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialsManager.java deleted file mode 100644 index f1b13ad4..00000000 --- a/src/main/java/ee/carlrobert/codegpt/credentials/OpenAICredentialsManager.java +++ /dev/null @@ -1,36 +0,0 @@ -package ee.carlrobert.codegpt.credentials; - -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.Service; -import org.jetbrains.annotations.Nullable; - -@Service -public final class OpenAICredentialsManager { - - private static final CredentialAttributes openAIApiKeyCredentialAttributes = - CredentialsUtil.createCredentialAttributes("OPENAI_API_KEY"); - - private String openAIApiKey; - - private OpenAICredentialsManager() { - openAIApiKey = CredentialsUtil.getPassword(openAIApiKeyCredentialAttributes); - } - - public static OpenAICredentialsManager getInstance() { - return ApplicationManager.getApplication().getService(OpenAICredentialsManager.class); - } - - public boolean isApiKeySet() { - return openAIApiKey != null && !openAIApiKey.isEmpty(); - } - - public @Nullable String getApiKey() { - return openAIApiKey; - } - - public void setApiKey(String openAIApiKey) { - this.openAIApiKey = openAIApiKey; - CredentialsUtil.setPassword(openAIApiKeyCredentialAttributes, openAIApiKey); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/SingleCredentialManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/SingleCredentialManager.java new file mode 100644 index 00000000..1596bfb5 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/credentials/SingleCredentialManager.java @@ -0,0 +1,25 @@ +package ee.carlrobert.codegpt.credentials; + +abstract class SingleCredentialManager extends AbstractCredentialsManager { + + private final String key; + + public SingleCredentialManager(String key) { + super(key); + this.key = key; + } + + @Override + public boolean isCredentialSet() { + return isCredentialSet(key); + } + + @Override + public String getCredential() { + return getCredential(key); + } + + public void setCredential(String credential) { + setCredential(key, credential); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialManager.java new file mode 100644 index 00000000..c1f013f0 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialManager.java @@ -0,0 +1,16 @@ +package ee.carlrobert.codegpt.credentials; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; + +@Service +public final class YouCredentialManager extends SingleCredentialManager { + + private YouCredentialManager() { + super("YOU_ACCOUNT_PASSWORD"); + } + + public static YouCredentialManager getInstance() { + return ApplicationManager.getApplication().getService(YouCredentialManager.class); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialsManager.java b/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialsManager.java deleted file mode 100644 index cc3d9a5c..00000000 --- a/src/main/java/ee/carlrobert/codegpt/credentials/YouCredentialsManager.java +++ /dev/null @@ -1,32 +0,0 @@ -package ee.carlrobert.codegpt.credentials; - -import com.intellij.credentialStore.CredentialAttributes; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.Service; -import org.jetbrains.annotations.Nullable; - -@Service -public final class YouCredentialsManager { - - private static final CredentialAttributes accountPasswordCredentialAttributes = - CredentialsUtil.createCredentialAttributes("ACCOUNT_PASSWORD"); - - private String accountPassword; - - private YouCredentialsManager() { - accountPassword = CredentialsUtil.getPassword(accountPasswordCredentialAttributes); - } - - public static YouCredentialsManager getInstance() { - return ApplicationManager.getApplication().getService(YouCredentialsManager.class); - } - - public @Nullable String getAccountPassword() { - return accountPassword; - } - - public void setAccountPassword(String accountPassword) { - this.accountPassword = accountPassword; - CredentialsUtil.setPassword(accountPasswordCredentialAttributes, accountPassword); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/SettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettings.java similarity index 50% rename from src/main/java/ee/carlrobert/codegpt/settings/state/SettingsState.java rename to src/main/java/ee/carlrobert/codegpt/settings/GeneralSettings.java index fa36d6fc..4394410d 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/SettingsState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettings.java @@ -1,55 +1,54 @@ -package ee.carlrobert.codegpt.settings.state; - -import static java.lang.String.format; +package ee.carlrobert.codegpt.settings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; import ee.carlrobert.codegpt.completions.HuggingFaceModel; import ee.carlrobert.codegpt.completions.llama.LlamaModel; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.settings.service.ServiceType; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import org.jetbrains.annotations.NotNull; @State(name = "CodeGPT_GeneralSettings_210", storages = @Storage("CodeGPT_GeneralSettings_210.xml")) -public class SettingsState implements PersistentStateComponent { +public class GeneralSettings implements PersistentStateComponent { - private String email = ""; - private String displayName = ""; - private boolean previouslySignedIn; - private ServiceType selectedService = ServiceType.OPENAI; + private GeneralSettingsState state = new GeneralSettingsState(); - public SettingsState() { - } - - public static SettingsState getInstance() { - return ApplicationManager.getApplication().getService(SettingsState.class); + @Override + @NotNull + public GeneralSettingsState getState() { + return state; } @Override - public SettingsState getState() { - return this; + public void loadState(@NotNull GeneralSettingsState state) { + this.state = state; } - @Override - public void loadState(@NotNull SettingsState state) { - XmlSerializerUtil.copyBean(state, this); + public static GeneralSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static GeneralSettings getInstance() { + return ApplicationManager.getApplication().getService(GeneralSettings.class); } public void sync(Conversation conversation) { var clientCode = conversation.getClientCode(); if ("chat.completion".equals(clientCode)) { - setSelectedService(ServiceType.OPENAI); - OpenAISettingsState.getInstance().setModel(conversation.getModel()); + state.setSelectedService(ServiceType.OPENAI); + OpenAISettings.getCurrentState().setModel(conversation.getModel()); } if ("azure.chat.completion".equals(clientCode)) { - setSelectedService(ServiceType.AZURE); + state.setSelectedService(ServiceType.AZURE); } if ("llama.chat.completion".equals(clientCode)) { - setSelectedService(ServiceType.LLAMA_CPP); - var llamaSettings = LlamaSettingsState.getInstance(); + state.setSelectedService(ServiceType.LLAMA_CPP); + var llamaSettings = LlamaSettings.getCurrentState(); try { var huggingFaceModel = HuggingFaceModel.valueOf(conversation.getModel()); llamaSettings.setHuggingFaceModel(huggingFaceModel); @@ -60,20 +59,20 @@ public class SettingsState implements PersistentStateComponent { } } if ("you.chat.completion".equals(clientCode)) { - setSelectedService(ServiceType.YOU); + state.setSelectedService(ServiceType.YOU); } } public String getModel() { - switch (selectedService) { + switch (state.getSelectedService()) { case OPENAI: - return OpenAISettingsState.getInstance().getModel(); + return OpenAISettings.getCurrentState().getModel(); case AZURE: - return AzureSettingsState.getInstance().getDeploymentId(); + return AzureSettings.getCurrentState().getDeploymentId(); case YOU: return "YouCode"; case LLAMA_CPP: - var llamaSettings = LlamaSettingsState.getInstance(); + var llamaSettings = LlamaSettings.getCurrentState(); if (llamaSettings.isUseCustomModel()) { var filePath = llamaSettings.getCustomLlamaModelPath(); int lastSeparatorIndex = filePath.lastIndexOf('/'); @@ -84,7 +83,7 @@ public class SettingsState implements PersistentStateComponent { } var huggingFaceModel = llamaSettings.getHuggingFaceModel(); var llamaModel = LlamaModel.findByHuggingFaceModel(huggingFaceModel); - return format( + return String.format( "%s %dB (Q%d)", llamaModel.getLabel(), huggingFaceModel.getParameterSize(), @@ -93,43 +92,4 @@ public class SettingsState implements PersistentStateComponent { return "Unknown"; } } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getDisplayName() { - if (displayName == null || displayName.isEmpty()) { - var systemUserName = System.getProperty("user.name"); - if (systemUserName == null || systemUserName.isEmpty()) { - return "User"; - } - return systemUserName; - } - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public boolean isPreviouslySignedIn() { - return previouslySignedIn; - } - - public void setPreviouslySignedIn(boolean previouslySignedIn) { - this.previouslySignedIn = previouslySignedIn; - } - - public ServiceType getSelectedService() { - return selectedService; - } - - public void setSelectedService(ServiceType selectedService) { - this.selectedService = selectedService; - } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/SettingsComponent.java b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsComponent.java similarity index 53% rename from src/main/java/ee/carlrobert/codegpt/settings/SettingsComponent.java rename to src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsComponent.java index a465aa47..25951741 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/SettingsComponent.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsComponent.java @@ -1,56 +1,50 @@ package ee.carlrobert.codegpt.settings; +import static ee.carlrobert.codegpt.settings.service.ServiceType.AZURE; +import static ee.carlrobert.codegpt.settings.service.ServiceType.LLAMA_CPP; +import static ee.carlrobert.codegpt.settings.service.ServiceType.OPENAI; +import static ee.carlrobert.codegpt.settings.service.ServiceType.YOU; import static java.util.stream.Collectors.toList; import com.intellij.openapi.Disposable; import com.intellij.openapi.ui.ComboBox; -import com.intellij.openapi.ui.ComponentValidator; -import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.SystemInfoRt; import com.intellij.ui.components.JBTextField; import com.intellij.util.ui.FormBuilder; import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.settings.service.ServiceSelectionForm; import ee.carlrobert.codegpt.settings.service.ServiceType; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; import java.awt.CardLayout; import java.util.Arrays; import javax.swing.DefaultComboBoxModel; import javax.swing.JComponent; import javax.swing.JPanel; -public class SettingsComponent { +public class GeneralSettingsComponent { private final JPanel mainPanel; private final JBTextField displayNameField; private final ComboBox serviceComboBox; private final ServiceSelectionForm serviceSelectionForm; - public SettingsComponent(Disposable parentDisposable, SettingsState settings) { - displayNameField = new JBTextField(settings.getDisplayName(), 20); - + public GeneralSettingsComponent(Disposable parentDisposable, GeneralSettings settings) { + displayNameField = new JBTextField(settings.getState().getDisplayName(), 20); serviceSelectionForm = new ServiceSelectionForm(parentDisposable); var cardLayout = new CardLayout(); var cards = new JPanel(cardLayout); - cards.add(serviceSelectionForm.getOpenAIServiceSectionPanel(), ServiceType.OPENAI.getCode()); - cards.add(serviceSelectionForm.getAzureServiceSectionPanel(), ServiceType.AZURE.getCode()); - cards.add(serviceSelectionForm.getYouServiceSectionPanel(), ServiceType.YOU.getCode()); - cards.add(serviceSelectionForm.getLlamaServiceSectionPanel(), ServiceType.LLAMA_CPP.getCode()); + cards.add(serviceSelectionForm.getOpenAISettingsForm().getForm(), OPENAI.getCode()); + cards.add(serviceSelectionForm.getAzureSettingsForm().getForm(), AZURE.getCode()); + cards.add(serviceSelectionForm.getYouSettingsForm(), YOU.getCode()); + cards.add(serviceSelectionForm.getLlamaSettingsForm(), LLAMA_CPP.getCode()); var serviceComboBoxModel = new DefaultComboBoxModel(); serviceComboBoxModel.addAll(Arrays.stream(ServiceType.values()) - .filter(it -> ServiceType.LLAMA_CPP != it || SystemInfoRt.isUnix) + .filter(it -> LLAMA_CPP != it || SystemInfoRt.isUnix) .collect(toList())); serviceComboBox = new ComboBox<>(serviceComboBoxModel); - serviceComboBox.setSelectedItem(ServiceType.OPENAI); + serviceComboBox.setSelectedItem(OPENAI); serviceComboBox.setPreferredSize(displayNameField.getPreferredSize()); - var serviceInputValidator = createInputValidator(parentDisposable, serviceComboBox); - serviceInputValidator.revalidate(); - serviceComboBox.addItemListener(e -> { - serviceInputValidator.revalidate(); - cardLayout.show(cards, ((ServiceType) e.getItem()).getCode()); - }); - + serviceComboBox.addItemListener(e -> + cardLayout.show(cards, ((ServiceType) e.getItem()).getCode())); mainPanel = FormBuilder.createFormBuilder() .addLabeledComponent( CodeGPTBundle.get("settingsConfigurable.displayName.label"), @@ -90,27 +84,4 @@ public class SettingsComponent { public void setDisplayName(String displayName) { displayNameField.setText(displayName); } - - private ComponentValidator createInputValidator( - Disposable parentDisposable, - JComponent component) { - var validator = new ComponentValidator(parentDisposable) - .withValidator(() -> { - if (component instanceof ComboBox) { - var selectedItem = ((ComboBox) component).getSelectedItem(); - if (selectedItem == ServiceType.OPENAI - && OpenAISettingsState.getInstance().isOpenAIQuotaExceeded()) { - return new ValidationInfo( - CodeGPTBundle.get("settings.openaiQuotaExceeded"), - component); - } - } - - return null; - }) - .andStartOnFocusLost() - .installOn(component); - validator.enableValidation(); - return validator; - } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java new file mode 100644 index 00000000..f7296573 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java @@ -0,0 +1,142 @@ +package ee.carlrobert.codegpt.settings; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.util.Disposer; +import ee.carlrobert.codegpt.CodeGPTBundle; +import ee.carlrobert.codegpt.conversations.ConversationsState; +import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; +import ee.carlrobert.codegpt.credentials.LlamaCredentialManager; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettings; +import ee.carlrobert.codegpt.settings.service.azure.AzureSettingsForm; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.llama.form.LlamaSettingsForm; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettingsForm; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; +import ee.carlrobert.codegpt.settings.service.you.YouSettingsForm; +import ee.carlrobert.codegpt.telemetry.TelemetryAction; +import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; +import ee.carlrobert.codegpt.util.ApplicationUtil; +import javax.swing.JComponent; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.Nullable; + +public class GeneralSettingsConfigurable implements Configurable { + + private Disposable parentDisposable; + + private GeneralSettingsComponent component; + + @Nls(capitalization = Nls.Capitalization.Title) + @Override + public String getDisplayName() { + return CodeGPTBundle.get("settings.displayName"); + } + + @Override + public JComponent getPreferredFocusedComponent() { + return component.getPreferredFocusedComponent(); + } + + @Nullable + @Override + public JComponent createComponent() { + var settings = GeneralSettings.getInstance(); + parentDisposable = Disposer.newDisposable(); + component = new GeneralSettingsComponent(parentDisposable, settings); + return component.getPanel(); + } + + @Override + public boolean isModified() { + var settings = GeneralSettings.getCurrentState(); + var serviceSelectionForm = component.getServiceSelectionForm(); + return !component.getDisplayName().equals(settings.getDisplayName()) + || component.getSelectedService() != settings.getSelectedService() + || OpenAISettings.getInstance().isModified(serviceSelectionForm.getOpenAISettingsForm()) + || AzureSettings.getInstance().isModified(serviceSelectionForm.getAzureSettingsForm()) + || YouSettings.getInstance().isModified(serviceSelectionForm.getYouSettingsForm()) + || LlamaSettings.getInstance().isModified(serviceSelectionForm.getLlamaSettingsForm()); + } + + @Override + public void apply() { + var settings = GeneralSettings.getCurrentState(); + settings.setDisplayName(component.getDisplayName()); + settings.setSelectedService(component.getSelectedService()); + + var serviceSelectionForm = component.getServiceSelectionForm(); + var openAISettingsForm = serviceSelectionForm.getOpenAISettingsForm(); + applyOpenAISettings(openAISettingsForm); + applyAzureSettings(serviceSelectionForm.getAzureSettingsForm()); + applyYouSettings(serviceSelectionForm.getYouSettingsForm()); + applyLlamaSettings(serviceSelectionForm.getLlamaSettingsForm()); + + var serviceChanged = component.getSelectedService() != settings.getSelectedService(); + var modelChanged = !OpenAISettings.getCurrentState().getModel() + .equals(openAISettingsForm.getModel()); + if (serviceChanged || modelChanged) { + resetActiveTab(); + if (serviceChanged) { + TelemetryAction.SETTINGS_CHANGED.createActionMessage() + .property("service", component.getSelectedService().getCode().toLowerCase()) + .send(); + } + } + } + + private void applyLlamaSettings(LlamaSettingsForm form) { + LlamaCredentialManager.getInstance() + .setCredential(form.getLlamaServerPreferencesForm().getApiKey()); + LlamaSettings.getInstance().loadState(form.getCurrentState()); + } + + private void applyYouSettings(YouSettingsForm form) { + YouSettings.getInstance().loadState(form.getCurrentState()); + } + + private void applyAzureSettings(AzureSettingsForm form) { + AzureSettings.getInstance().loadState(form.getCurrentState()); + var azureCredentials = AzureCredentialsManager.getInstance(); + azureCredentials.setApiKey(form.getApiKey()); + azureCredentials.setActiveDirectoryToken(form.getActiveDirectoryToken()); + } + + @Override + public void reset() { + var settings = GeneralSettings.getCurrentState(); + component.setDisplayName(settings.getDisplayName()); + component.setSelectedService(settings.getSelectedService()); + + var serviceSelectionForm = component.getServiceSelectionForm(); + serviceSelectionForm.getOpenAISettingsForm().resetForm(); + serviceSelectionForm.getAzureSettingsForm().resetForm(); + serviceSelectionForm.getLlamaSettingsForm().resetForm(); + serviceSelectionForm.getYouSettingsForm().resetForm(); + } + + @Override + public void disposeUIResources() { + if (parentDisposable != null) { + Disposer.dispose(parentDisposable); + } + component = null; + } + + private void applyOpenAISettings(OpenAISettingsForm form) { + OpenAICredentialManager.getInstance().setCredential(form.getApiKey()); + OpenAISettings.getInstance().loadState(form.getCurrentState()); + } + + private void resetActiveTab() { + ConversationsState.getInstance().setCurrentConversation(null); + var project = ApplicationUtil.findCurrentProject(); + if (project == null) { + throw new RuntimeException("Could not find current project."); + } + + project.getService(StandardChatToolWindowContentManager.class).resetAll(); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsState.java new file mode 100644 index 00000000..2c266c13 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsState.java @@ -0,0 +1,32 @@ +package ee.carlrobert.codegpt.settings; + +import ee.carlrobert.codegpt.settings.service.ServiceType; + +public class GeneralSettingsState { + + private String displayName = ""; + private ServiceType selectedService = ServiceType.OPENAI; + + public String getDisplayName() { + if (displayName == null || displayName.isEmpty()) { + var systemUserName = System.getProperty("user.name"); + if (systemUserName == null || systemUserName.isEmpty()) { + return "User"; + } + return systemUserName; + } + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public ServiceType getSelectedService() { + return selectedService; + } + + public void setSelectedService(ServiceType selectedService) { + this.selectedService = selectedService; + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettings.java new file mode 100644 index 00000000..9772b966 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettings.java @@ -0,0 +1,34 @@ +package ee.carlrobert.codegpt.settings; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import org.jetbrains.annotations.NotNull; + +@State( + name = "CodeGPT_IncludedFilesSettings", + storages = @Storage("CodeGPT_IncludedFilesSettings.xml")) +public class IncludedFilesSettings implements PersistentStateComponent { + + private IncludedFilesSettingsState state = new IncludedFilesSettingsState(); + + @Override + @NotNull + public IncludedFilesSettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull IncludedFilesSettingsState state) { + this.state = state; + } + + public static IncludedFilesSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static IncludedFilesSettings getInstance() { + return ApplicationManager.getApplication().getService(IncludedFilesSettings.class); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettingsState.java new file mode 100644 index 00000000..33337808 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettingsState.java @@ -0,0 +1,32 @@ +package ee.carlrobert.codegpt.settings; + +public class IncludedFilesSettingsState { + + public static final String DEFAULT_PROMPT_TEMPLATE = + "Use the following context to answer question at the end:\n\n" + + "{REPEATABLE_CONTEXT}\n\n" + + "Question: {QUESTION}"; + public static final String DEFAULT_REPEATABLE_CONTEXT = + "File Path: {FILE_PATH}\n" + + "File Content:\n" + + "{FILE_CONTENT}"; + + private String promptTemplate = DEFAULT_PROMPT_TEMPLATE; + private String repeatableContext = DEFAULT_REPEATABLE_CONTEXT; + + public String getPromptTemplate() { + return promptTemplate; + } + + public void setPromptTemplate(String promptTemplate) { + this.promptTemplate = promptTemplate; + } + + public String getRepeatableContext() { + return repeatableContext; + } + + public void setRepeatableContext(String repeatableContext) { + this.repeatableContext = repeatableContext; + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/SettingsConfigurable.java b/src/main/java/ee/carlrobert/codegpt/settings/SettingsConfigurable.java deleted file mode 100644 index 2df7a5f6..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/SettingsConfigurable.java +++ /dev/null @@ -1,144 +0,0 @@ -package ee.carlrobert.codegpt.settings; - -import com.intellij.openapi.Disposable; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.util.Disposer; -import ee.carlrobert.codegpt.CodeGPTBundle; -import ee.carlrobert.codegpt.conversations.ConversationsState; -import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; -import ee.carlrobert.codegpt.credentials.LlamaCredentialsManager; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; -import ee.carlrobert.codegpt.settings.state.AzureSettingsState; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; -import ee.carlrobert.codegpt.settings.state.YouSettingsState; -import ee.carlrobert.codegpt.telemetry.TelemetryAction; -import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; -import ee.carlrobert.codegpt.util.ApplicationUtil; -import javax.swing.JComponent; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.Nullable; - -public class SettingsConfigurable implements Configurable { - - private Disposable parentDisposable; - - private SettingsComponent settingsComponent; - - @Nls(capitalization = Nls.Capitalization.Title) - @Override - public String getDisplayName() { - return CodeGPTBundle.get("settings.displayName"); - } - - @Override - public JComponent getPreferredFocusedComponent() { - return settingsComponent.getPreferredFocusedComponent(); - } - - @Nullable - @Override - public JComponent createComponent() { - var settings = SettingsState.getInstance(); - parentDisposable = Disposer.newDisposable(); - settingsComponent = new SettingsComponent(parentDisposable, settings); - return settingsComponent.getPanel(); - } - - @Override - public boolean isModified() { - var settings = SettingsState.getInstance(); - var openAISettings = OpenAISettingsState.getInstance(); - var azureSettings = AzureSettingsState.getInstance(); - var llamaSettings = LlamaSettingsState.getInstance(); - - var serviceSelectionForm = settingsComponent.getServiceSelectionForm(); - return !settingsComponent.getDisplayName().equals(settings.getDisplayName()) - || isServiceChanged(settings) - || openAISettings.isModified(serviceSelectionForm) - || azureSettings.isModified(serviceSelectionForm) - || serviceSelectionForm.isDisplayWebSearchResults() - != YouSettingsState.getInstance().isDisplayWebSearchResults() - || llamaSettings.isModified(serviceSelectionForm); - } - - @Override - public void apply() { - var serviceSelectionForm = settingsComponent.getServiceSelectionForm(); - - var prevKey = OpenAICredentialsManager.getInstance().getApiKey(); - if (prevKey != null && !prevKey.equals(serviceSelectionForm.getOpenAIApiKey())) { - OpenAISettingsState.getInstance().setOpenAIQuotaExceeded(false); - } - - OpenAICredentialsManager.getInstance().setApiKey(serviceSelectionForm.getOpenAIApiKey()); - AzureCredentialsManager.getInstance().setApiKey(serviceSelectionForm.getAzureOpenAIApiKey()); - AzureCredentialsManager.getInstance() - .setAzureActiveDirectoryToken(serviceSelectionForm.getAzureActiveDirectoryToken()); - LlamaCredentialsManager.getInstance() - .setApiKey(serviceSelectionForm.getLlamaServerPreferencesForm().getApiKey()); - - var settings = SettingsState.getInstance(); - settings.setDisplayName(settingsComponent.getDisplayName()); - settings.setSelectedService(settingsComponent.getSelectedService()); - - var azureSettings = AzureSettingsState.getInstance(); - var openAISettings = OpenAISettingsState.getInstance(); - openAISettings.apply(serviceSelectionForm); - azureSettings.apply(serviceSelectionForm); - LlamaSettingsState.getInstance().apply(serviceSelectionForm); - YouSettingsState.getInstance() - .setDisplayWebSearchResults(serviceSelectionForm.isDisplayWebSearchResults()); - - var serviceChanged = isServiceChanged(settings); - var modelChanged = !openAISettings.getModel().equals(serviceSelectionForm.getOpenAIModel()); - if (serviceChanged || modelChanged) { - resetActiveTab(); - if (serviceChanged) { - TelemetryAction.SETTINGS_CHANGED.createActionMessage() - .property("service", settingsComponent.getSelectedService().getCode().toLowerCase()) - .send(); - } - } - } - - @Override - public void reset() { - var settings = SettingsState.getInstance(); - var serviceSelectionForm = settingsComponent.getServiceSelectionForm(); - - // settingsComponent.setEmail(settings.getEmail()); - settingsComponent.setDisplayName(settings.getDisplayName()); - settingsComponent.setSelectedService(settings.getSelectedService()); - - OpenAISettingsState.getInstance().reset(serviceSelectionForm); - AzureSettingsState.getInstance().reset(serviceSelectionForm); - LlamaSettingsState.getInstance().reset(serviceSelectionForm); - - serviceSelectionForm.setDisplayWebSearchResults( - YouSettingsState.getInstance().isDisplayWebSearchResults()); - } - - @Override - public void disposeUIResources() { - if (parentDisposable != null) { - Disposer.dispose(parentDisposable); - } - settingsComponent = null; - } - - private boolean isServiceChanged(SettingsState settings) { - return settingsComponent.getSelectedService() != settings.getSelectedService(); - } - - private void resetActiveTab() { - ConversationsState.getInstance().setCurrentConversation(null); - var project = ApplicationUtil.findCurrentProject(); - if (project == null) { - throw new RuntimeException("Could not find current project."); - } - - project.getService(StandardChatToolWindowContentManager.class).resetAll(); - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettings.java new file mode 100644 index 00000000..acf5c783 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettings.java @@ -0,0 +1,34 @@ +package ee.carlrobert.codegpt.settings.advanced; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import org.jetbrains.annotations.NotNull; + +@State( + name = "CodeGPT_AdvancedSettings_210", + storages = @Storage("CodeGPT_AdvancedSettings_210.xml")) +public class AdvancedSettings implements PersistentStateComponent { + + private AdvancedSettingsState state = new AdvancedSettingsState(); + + @Override + @NotNull + public AdvancedSettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull AdvancedSettingsState state) { + this.state = state; + } + + public static AdvancedSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static AdvancedSettings getInstance() { + return ApplicationManager.getApplication().getService(AdvancedSettings.class); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsComponent.java b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsComponent.java index 5df9e439..42397497 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsComponent.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsComponent.java @@ -82,70 +82,6 @@ public class AdvancedSettingsComponent { return mainPanel; } - public Proxy.Type getProxyType() { - return (Proxy.Type) proxyTypeComboBox.getSelectedItem(); - } - - public void setProxyType(Proxy.Type type) { - proxyTypeComboBox.setSelectedItem(type); - } - - public String getProxyHost() { - return proxyHostField.getText().trim(); - } - - public void setProxyHost(String host) { - proxyHostField.setText(host.trim()); - } - - public int getProxyPort() { - return proxyPortField.getNumber(); - } - - public void setProxyPort(int port) { - proxyPortField.setNumber(port); - } - - public boolean isProxyAuthSelected() { - return proxyAuthCheckbox.isSelected(); - } - - public void setUseProxyAuthentication(boolean isProxyAuthSelected) { - proxyAuthCheckbox.setSelected(isProxyAuthSelected); - } - - public String getProxyAuthUsername() { - return proxyAuthUsername.getText().trim(); - } - - public void setProxyUsername(String proxyUsername) { - proxyAuthUsername.setText(proxyUsername); - } - - public String getProxyAuthPassword() { - return new String(proxyAuthPassword.getPassword()); - } - - public void setProxyPassword(String proxyPassword) { - proxyAuthPassword.setText(proxyPassword); - } - - public int getConnectionTimeout() { - return connectionTimeoutField.getNumber(); - } - - public void setConnectionTimeoutField(int timeout) { - connectionTimeoutField.setNumber(timeout); - } - - public int getReadTimeout() { - return readTimeoutField.getNumber(); - } - - public void setReadTimeout(int timeout) { - readTimeoutField.setNumber(timeout); - } - private JComponent createProxySettingsForm() { var proxyPanel = new JPanel(); proxyPanel.setBorder(JBUI.Borders.emptyLeft(16)); @@ -191,4 +127,29 @@ public class AdvancedSettingsComponent { return proxyPanel; } + + public AdvancedSettingsState getCurrentFormState() { + var state = new AdvancedSettingsState(); + state.setProxyType((Proxy.Type) proxyTypeComboBox.getSelectedItem()); + state.setProxyHost(proxyHostField.getText().trim()); + state.setProxyPort(proxyPortField.getNumber()); + state.setProxyAuthSelected(proxyAuthCheckbox.isSelected()); + state.setProxyUsername(proxyAuthUsername.getText().trim()); + state.setProxyPassword(new String(proxyAuthPassword.getPassword())); + state.setConnectTimeout(connectionTimeoutField.getNumber()); + state.setReadTimeout(readTimeoutField.getNumber()); + return state; + } + + public void resetForm() { + var advancedSettings = AdvancedSettings.getCurrentState(); + proxyTypeComboBox.setSelectedItem(advancedSettings.getProxyType()); + proxyHostField.setText(advancedSettings.getProxyHost()); + proxyPortField.setNumber(advancedSettings.getProxyPort()); + proxyAuthCheckbox.setSelected(advancedSettings.isProxyAuthSelected()); + proxyAuthUsername.setText(advancedSettings.getProxyUsername()); + proxyAuthPassword.setText(advancedSettings.getProxyPassword()); + connectionTimeoutField.setNumber(advancedSettings.getConnectTimeout()); + readTimeoutField.setNumber(advancedSettings.getReadTimeout()); + } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsConfigurable.java b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsConfigurable.java index 7aae281c..18cf1e61 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsConfigurable.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsConfigurable.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable; public class AdvancedSettingsConfigurable implements Configurable { - private AdvancedSettingsComponent advancedSettingsComponent; + private AdvancedSettingsComponent component; @Nls(capitalization = Nls.Capitalization.Title) @Override @@ -19,54 +19,27 @@ public class AdvancedSettingsConfigurable implements Configurable { @Nullable @Override public JComponent createComponent() { - var advancedSettings = AdvancedSettingsState.getInstance(); - advancedSettingsComponent = new AdvancedSettingsComponent(advancedSettings); - return advancedSettingsComponent.getPanel(); + component = new AdvancedSettingsComponent(AdvancedSettings.getCurrentState()); + return component.getPanel(); } @Override public boolean isModified() { - var advancedSettings = AdvancedSettingsState.getInstance(); - return !advancedSettingsComponent.getProxyType().equals(advancedSettings.getProxyType()) - || !advancedSettingsComponent.getProxyHost().equals(advancedSettings.getProxyHost()) - || advancedSettingsComponent.getProxyPort() != advancedSettings.getProxyPort() - || advancedSettingsComponent.isProxyAuthSelected() != advancedSettings.isProxyAuthSelected() - || !advancedSettingsComponent.getProxyAuthUsername() - .equals(advancedSettings.getProxyUsername()) - || !advancedSettingsComponent.getProxyAuthPassword() - .equals(advancedSettings.getProxyPassword()) - || advancedSettingsComponent.getConnectionTimeout() != advancedSettings.getConnectTimeout() - || advancedSettingsComponent.getReadTimeout() != advancedSettings.getReadTimeout(); + return !component.getCurrentFormState().equals(AdvancedSettings.getCurrentState()); } @Override public void apply() { - var advancedSettings = AdvancedSettingsState.getInstance(); - advancedSettings.setProxyType(advancedSettingsComponent.getProxyType()); - advancedSettings.setProxyHost(advancedSettingsComponent.getProxyHost()); - advancedSettings.setProxyPort(advancedSettingsComponent.getProxyPort()); - advancedSettings.setProxyAuthSelected(advancedSettingsComponent.isProxyAuthSelected()); - advancedSettings.setProxyUsername(advancedSettingsComponent.getProxyAuthUsername()); - advancedSettings.setProxyPassword(advancedSettingsComponent.getProxyAuthPassword()); - advancedSettings.setConnectTimeout(advancedSettingsComponent.getConnectionTimeout()); - advancedSettings.setReadTimeout(advancedSettingsComponent.getReadTimeout()); + AdvancedSettings.getInstance().loadState(component.getCurrentFormState()); } @Override public void reset() { - var advancedSettings = AdvancedSettingsState.getInstance(); - advancedSettingsComponent.setProxyType(advancedSettings.getProxyType()); - advancedSettingsComponent.setProxyHost(advancedSettings.getProxyHost()); - advancedSettingsComponent.setProxyPort(advancedSettings.getProxyPort()); - advancedSettingsComponent.setUseProxyAuthentication(advancedSettings.isProxyAuthSelected()); - advancedSettingsComponent.setProxyUsername(advancedSettings.getProxyUsername()); - advancedSettingsComponent.setProxyPassword(advancedSettings.getProxyPassword()); - advancedSettingsComponent.setConnectionTimeoutField(advancedSettings.getConnectTimeout()); - advancedSettingsComponent.setReadTimeout(advancedSettings.getReadTimeout()); + component.resetForm(); } @Override public void disposeUIResources() { - advancedSettingsComponent = null; + component = null; } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsState.java index 293f8057..8bad4328 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettingsState.java @@ -1,18 +1,9 @@ package ee.carlrobert.codegpt.settings.advanced; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; import java.net.Proxy; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.Objects; -@State( - name = "CodeGPT_AdvancedSettings_210", - storages = @Storage("CodeGPT_AdvancedSettings_210.xml")) -public class AdvancedSettingsState implements PersistentStateComponent { +public class AdvancedSettingsState { private String proxyHost = ""; private int proxyPort; @@ -23,21 +14,6 @@ public class AdvancedSettingsState implements PersistentStateComponent openAICompletionModelComboBox; - - private final JBRadioButton useAzureApiKeyAuthenticationRadioButton; - private final JBPasswordField azureApiKeyField; - private final JPanel azureApiKeyFieldPanel; - private final JBRadioButton useAzureActiveDirectoryAuthenticationRadioButton; - private final JBPasswordField azureActiveDirectoryTokenField; - private final JPanel azureActiveDirectoryTokenFieldPanel; - private final JBTextField azureBaseHostField; - private final JBTextField azurePathField; - private final JBTextField azureResourceNameField; - private final JBTextField azureDeploymentIdField; - private final JBTextField azureApiVersionField; - private final JPanel azureServiceSectionPanel; - - private final JPanel youServiceSectionPanel; - private final JBCheckBox displayWebSearchResultsCheckBox; - - private final LlamaServiceSelectionForm llamaServiceSectionPanel; + private final OpenAISettingsForm openAISettingsForm; + private final AzureSettingsForm azureSettingsForm; + private final LlamaSettingsForm llamaSettingsForm; + private final YouSettingsForm youSettingsForm; public ServiceSelectionForm(Disposable parentDisposable) { - this.parentDisposable = parentDisposable; - openAIApiKeyField = new JBPasswordField(); - openAIApiKeyField.setColumns(30); - openAIApiKeyField.setText(OpenAICredentialsManager.getInstance().getApiKey()); - - var azureSettings = AzureSettingsState.getInstance(); - useAzureApiKeyAuthenticationRadioButton = new JBRadioButton( - CodeGPTBundle.get("settingsConfigurable.service.azure.useApiKeyAuth.label"), - azureSettings.isUseAzureApiKeyAuthentication()); - useAzureActiveDirectoryAuthenticationRadioButton = new JBRadioButton( - CodeGPTBundle.get("settingsConfigurable.service.azure.useActiveDirectoryAuth.label"), - azureSettings.isUseAzureActiveDirectoryAuthentication()); - azureApiKeyField = new JBPasswordField(); - azureApiKeyField.setColumns(30); - azureApiKeyField.setText(AzureCredentialsManager.getInstance().getAzureOpenAIApiKey()); - azureApiKeyFieldPanel = UI.PanelFactory.panel(azureApiKeyField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) - .resizeX(false) - .createPanel(); - azureActiveDirectoryTokenField = new JBPasswordField(); - azureActiveDirectoryTokenField.setColumns(30); - azureActiveDirectoryTokenField.setText( - AzureCredentialsManager.getInstance().getAzureActiveDirectoryToken()); - azureActiveDirectoryTokenFieldPanel = UI.PanelFactory.panel(azureActiveDirectoryTokenField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.service.azure.bearerToken.label")) - .resizeX(false) - .createPanel(); - - var openAISettings = OpenAISettingsState.getInstance(); - openAIBaseHostField = new JBTextField(openAISettings.getBaseHost(), 30); - openAIPathField = new JBTextField(openAISettings.getPath(), 30); - openAIOrganizationField = new JBTextField(openAISettings.getOrganization(), 30); - - var selectedOpenAIModel = OpenAIChatCompletionModel.findByCode(openAISettings.getModel()); - - openAICompletionModelComboBox = new ComboBox<>( - new EnumComboBoxModel<>(OpenAIChatCompletionModel.class)); - openAICompletionModelComboBox.setSelectedItem(selectedOpenAIModel); - - azureBaseHostField = new JBTextField(azureSettings.getBaseHost(), 35); - azurePathField = new JBTextField(azureSettings.getPath(), 35); - azureResourceNameField = new JBTextField(azureSettings.getResourceName(), 35); - azureDeploymentIdField = new JBTextField(azureSettings.getDeploymentId(), 35); - azureApiVersionField = new JBTextField(azureSettings.getApiVersion(), 35); - - displayWebSearchResultsCheckBox = new JBCheckBox( - CodeGPTBundle.get("settingsConfigurable.service.you.displayResults.label"), - YouSettingsState.getInstance().isDisplayWebSearchResults()); - - openAIServiceSectionPanel = createOpenAIServiceSectionPanel(); - azureServiceSectionPanel = createAzureServiceSectionPanel(); - youServiceSectionPanel = createYouServiceSectionPanel(); - llamaServiceSectionPanel = new LlamaServiceSelectionForm(); - - registerPanelsVisibility(azureSettings); - registerRadioButtons(); - - ApplicationManager.getApplication() - .getMessageBus() - .connect() - .subscribe(AuthenticationNotifier.AUTHENTICATION_TOPIC, - (AuthenticationNotifier) () -> displayWebSearchResultsCheckBox.setEnabled(true)); + openAISettingsForm = new OpenAISettingsForm(OpenAISettings.getCurrentState()); + azureSettingsForm = new AzureSettingsForm(AzureSettings.getCurrentState()); + youSettingsForm = new YouSettingsForm(YouSettings.getCurrentState(), parentDisposable); + llamaSettingsForm = new LlamaSettingsForm(LlamaSettings.getCurrentState()); } - private JPanel createOpenAIServiceSectionPanel() { - var requestConfigurationPanel = UI.PanelFactory.grid() - .add(UI.PanelFactory.panel(openAICompletionModelComboBox) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.shared.model.label")) - .resizeX(false)) - .add(UI.PanelFactory.panel(openAIOrganizationField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.service.openai.organization.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get( - "settingsConfigurable.section.openai.organization.comment"))) - .add(UI.PanelFactory.panel(openAIBaseHostField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.shared.baseHost.label")) - .resizeX(false)) - .add(UI.PanelFactory.panel(openAIPathField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.shared.path.label")) - .resizeX(false)) - .createPanel(); - - var apiKeyFieldPanel = UI.PanelFactory.panel(openAIApiKeyField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) - .resizeX(false) - .withComment( - CodeGPTBundle.get("settingsConfigurable.service.openai.apiKey.comment")) - .withCommentHyperlinkListener(UIUtil::handleHyperlinkClicked) - .createPanel(); - - return FormBuilder.createFormBuilder() - .addComponent(new TitledSeparator( - CodeGPTBundle.get("settingsConfigurable.shared.authentication.title"))) - .addComponent(withEmptyLeftBorder(apiKeyFieldPanel)) - .addComponent(new TitledSeparator( - CodeGPTBundle.get("settingsConfigurable.shared.requestConfiguration.title"))) - .addComponent(withEmptyLeftBorder(requestConfigurationPanel)) - .addComponentFillVertically(new JPanel(), 0) - .getPanel(); + public OpenAISettingsForm getOpenAISettingsForm() { + return openAISettingsForm; } - private JPanel createAzureServiceSectionPanel() { - var authPanel = withEmptyLeftBorder(FormBuilder.createFormBuilder() - .addComponent(UI.PanelFactory - .panel(useAzureApiKeyAuthenticationRadioButton) - .resizeX(false) - .createPanel()) - .addComponent(withEmptyLeftBorder(azureApiKeyFieldPanel)) - .addComponent(UI.PanelFactory - .panel(useAzureActiveDirectoryAuthenticationRadioButton) - .resizeX(false) - .createPanel()) - .addComponent(withEmptyLeftBorder(azureActiveDirectoryTokenFieldPanel)) - .getPanel()); - - var configPanel = withEmptyLeftBorder(UI.PanelFactory.grid() - .add(UI.PanelFactory.panel(azureResourceNameField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.service.azure.resourceName.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get( - "settingsConfigurable.service.azure.resourceName.comment"))) - .add(UI.PanelFactory.panel(azureDeploymentIdField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.service.azure.deploymentId.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get( - "settingsConfigurable.service.azure.deploymentId.comment"))) - .add(UI.PanelFactory.panel(azureApiVersionField) - .withLabel(CodeGPTBundle.get( - "settingsConfigurable.service.azure.apiVersion.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get( - "settingsConfigurable.service.azure.apiVersion.comment"))) - .add(UI.PanelFactory.panel(azureBaseHostField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.baseHost.label")) - .resizeX(false)) - .add(UI.PanelFactory.panel(azurePathField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.path.label")) - .resizeX(false)) - .createPanel()); - - return FormBuilder.createFormBuilder() - .addComponent(new TitledSeparator( - CodeGPTBundle.get("settingsConfigurable.shared.authentication.title"))) - .addComponent(authPanel) - .addComponent(new TitledSeparator( - CodeGPTBundle.get("settingsConfigurable.shared.requestConfiguration.title"))) - .addComponent(configPanel) - .addComponentFillVertically(new JPanel(), 0) - .getPanel(); + public AzureSettingsForm getAzureSettingsForm() { + return azureSettingsForm; } - private JPanel createYouServiceSectionPanel() { - return FormBuilder.createFormBuilder() - .addComponent(new YouServiceSelectionForm(parentDisposable)) - .addComponent(new TitledSeparator( - CodeGPTBundle.get("settingsConfigurable.service.you.chatPreferences.title"))) - .addComponent(withEmptyLeftBorder(displayWebSearchResultsCheckBox)) - .addComponentFillVertically(new JPanel(), 0) - .getPanel(); + public YouSettingsForm getYouSettingsForm() { + return youSettingsForm; } - private JComponent withEmptyLeftBorder(JComponent component) { - component.setBorder(JBUI.Borders.emptyLeft(16)); - return component; - } - - private void registerPanelsVisibility(AzureSettingsState azureSettings) { - azureApiKeyFieldPanel.setVisible(azureSettings.isUseAzureApiKeyAuthentication()); - azureActiveDirectoryTokenFieldPanel.setVisible( - azureSettings.isUseAzureActiveDirectoryAuthentication()); - } - - private void registerRadioButtons() { - registerRadioButtons(List.of( - Map.entry(useAzureApiKeyAuthenticationRadioButton, azureApiKeyFieldPanel), - Map.entry(useAzureActiveDirectoryAuthenticationRadioButton, - azureActiveDirectoryTokenFieldPanel))); - } - - private void registerRadioButtons(List> entries) { - var buttonGroup = new ButtonGroup(); - entries.forEach(entry -> buttonGroup.add(entry.getKey())); - entries.forEach(entry -> entry.getKey().addActionListener((e) -> { - for (Map.Entry innerEntry : entries) { - innerEntry.getValue().setVisible(innerEntry.equals(entry)); - } - })); - } - - public void setOpenAIApiKey(String apiKey) { - openAIApiKeyField.setText(apiKey); - } - - public String getOpenAIApiKey() { - return new String(openAIApiKeyField.getPassword()); - } - - public void setOpenAIBaseHost(String baseHost) { - openAIBaseHostField.setText(baseHost); - } - - public String getOpenAIBaseHost() { - return openAIBaseHostField.getText(); - } - - public void setOpenAIOrganization(String organization) { - openAIOrganizationField.setText(organization); - } - - public String getOpenAIOrganization() { - return openAIOrganizationField.getText(); - } - - public void setOpenAIModel(String model) { - openAICompletionModelComboBox.setSelectedItem(OpenAIChatCompletionModel.findByCode(model)); - } - - public String getOpenAIModel() { - return ((OpenAIChatCompletionModel) (openAICompletionModelComboBox.getModel() - .getSelectedItem())) - .getCode(); - } - - public void setAzureActiveDirectoryAuthenticationSelected(boolean selected) { - useAzureActiveDirectoryAuthenticationRadioButton.setSelected(selected); - } - - public boolean isAzureActiveDirectoryAuthenticationSelected() { - return useAzureActiveDirectoryAuthenticationRadioButton.isSelected(); - } - - public void setAzureActiveDirectoryToken(String bearerToken) { - azureActiveDirectoryTokenField.setText(bearerToken); - } - - public String getAzureActiveDirectoryToken() { - return new String(azureActiveDirectoryTokenField.getPassword()); - } - - public void setAzureApiKeyAuthenticationSelected(boolean selected) { - useAzureApiKeyAuthenticationRadioButton.setSelected(selected); - } - - public boolean isAzureApiKeyAuthenticationSelected() { - return useAzureApiKeyAuthenticationRadioButton.isSelected(); - } - - public void setAzureApiKey(String apiKey) { - azureApiKeyField.setText(apiKey); - } - - public String getAzureOpenAIApiKey() { - return new String(azureApiKeyField.getPassword()); - } - - public void setAzureResourceName(String resourceName) { - azureResourceNameField.setText(resourceName); - } - - public String getAzureResourceName() { - return azureResourceNameField.getText(); - } - - public void setAzureDeploymentId(String deploymentId) { - azureDeploymentIdField.setText(deploymentId); - } - - public String getAzureDeploymentId() { - return azureDeploymentIdField.getText(); - } - - public void setAzureApiVersion(String apiVersion) { - azureApiVersionField.setText(apiVersion); - } - - public String getAzureApiVersion() { - return azureApiVersionField.getText(); - } - - public void setAzureBaseHost(String baseHost) { - azureBaseHostField.setText(baseHost); - } - - public String getAzureBaseHost() { - return azureBaseHostField.getText(); - } - - public void setDisplayWebSearchResults(boolean displayWebSearchResults) { - displayWebSearchResultsCheckBox.setSelected(displayWebSearchResults); - } - - public boolean isDisplayWebSearchResults() { - return displayWebSearchResultsCheckBox.isSelected(); - } - - public LlamaServerPreferencesForm getLlamaServerPreferencesForm() { - return llamaServiceSectionPanel.getLlamaServerPreferencesForm(); - } - - public LlamaModelPreferencesForm getLlamaModelPreferencesForm() { - return llamaServiceSectionPanel.getLlamaModelPreferencesForm(); - } - - public LlamaRequestPreferencesForm getLlamaRequestPreferencesForm() { - return llamaServiceSectionPanel.getLlamaRequestPreferencesForm(); - } - - public void setOpenAIPath(String path) { - openAIPathField.setText(path); - } - - public String getOpenAIPath() { - return openAIPathField.getText(); - } - - public void setAzurePath(String path) { - azurePathField.setText(path); - } - - public String getAzurePath() { - return azurePathField.getText(); - } - - public void setLlamaRunLocalServer(boolean runLocalServer) { - llamaServiceSectionPanel.setRunLocalServer(runLocalServer); - } - - public boolean isLlamaRunLocalServer() { - return llamaServiceSectionPanel.isRunLocalServer(); - } - - public void setLlamaBaseHost(String baseHost) { - llamaServiceSectionPanel.setBaseHost(baseHost); - } - - public String getLlamaBaseHost() { - return llamaServiceSectionPanel.getBaseHost(); - } - - public void setLlamaServerPort(int serverPort) { - llamaServiceSectionPanel.setServerPort(serverPort); - } - - public int getLlamaServerPort() { - return llamaServiceSectionPanel.getServerPort(); - } - - public JPanel getOpenAIServiceSectionPanel() { - return openAIServiceSectionPanel; - } - - public JPanel getAzureServiceSectionPanel() { - return azureServiceSectionPanel; - } - - public JPanel getYouServiceSectionPanel() { - return youServiceSectionPanel; - } - - public JPanel getLlamaServiceSectionPanel() { - return llamaServiceSectionPanel; - } - - public int getContextSize() { - return llamaServiceSectionPanel.getContextSize(); - } - - public void setContextSize(int contextSize) { - llamaServiceSectionPanel.setContextSize(contextSize); - } - - public int getThreads() { - return llamaServiceSectionPanel.getThreads(); - } - - public void setThreads(int threads) { - llamaServiceSectionPanel.setThreads(threads); - } - - public String getAdditionalParameters() { - return llamaServiceSectionPanel.getAdditionalParameters(); - } - - public void setAdditionalParameters(String additionalParameters) { - llamaServiceSectionPanel.setAdditionalParameters(additionalParameters); - } - - public PromptTemplate getLlamaPromptTemplate() { - return getLlamaServerPreferencesForm().getPromptTemplate(); - } - - public void setLlamaPromptTemplate(PromptTemplate promptTemplate) { - getLlamaServerPreferencesForm().setPromptTemplate(promptTemplate); + public LlamaSettingsForm getLlamaSettingsForm() { + return llamaSettingsForm; } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettings.java new file mode 100644 index 00000000..8e4b8521 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettings.java @@ -0,0 +1,43 @@ +package ee.carlrobert.codegpt.settings.service.azure; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +@State(name = "CodeGPT_AzureSettings_210", storages = @Storage("CodeGPT_AzureSettings_210.xml")) +public class AzureSettings implements PersistentStateComponent { + + private AzureSettingsState state = new AzureSettingsState(); + + @Override + @NotNull + public AzureSettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull AzureSettingsState state) { + this.state = state; + } + + public static AzureSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static AzureSettings getInstance() { + return ApplicationManager.getApplication().getService(AzureSettings.class); + } + + public boolean isModified(AzureSettingsForm form) { + var credentialsManager = AzureCredentialsManager.getInstance(); + return !form.getCurrentState().equals(state) + || !StringUtils.equals( + form.getActiveDirectoryToken(), + credentialsManager.getActiveDirectoryToken()) + || !StringUtils.equals(form.getApiKey(), credentialsManager.getApiKey()); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsForm.java new file mode 100644 index 00000000..4c867366 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsForm.java @@ -0,0 +1,184 @@ +package ee.carlrobert.codegpt.settings.service.azure; + +import static ee.carlrobert.codegpt.ui.UIUtil.withEmptyLeftBorder; + +import com.intellij.ui.TitledSeparator; +import com.intellij.ui.components.JBPasswordField; +import com.intellij.ui.components.JBRadioButton; +import com.intellij.ui.components.JBTextField; +import com.intellij.util.ui.FormBuilder; +import com.intellij.util.ui.UI; +import ee.carlrobert.codegpt.CodeGPTBundle; +import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; +import java.util.List; +import java.util.Map; +import javax.swing.ButtonGroup; +import javax.swing.JPanel; +import org.jetbrains.annotations.Nullable; + +public class AzureSettingsForm { + + private final JBRadioButton useAzureApiKeyAuthenticationRadioButton; + private final JBPasswordField azureApiKeyField; + private final JPanel azureApiKeyFieldPanel; + private final JBRadioButton useAzureActiveDirectoryAuthenticationRadioButton; + private final JBPasswordField azureActiveDirectoryTokenField; + private final JPanel azureActiveDirectoryTokenFieldPanel; + private final JBTextField azureBaseHostField; + private final JBTextField azurePathField; + private final JBTextField azureResourceNameField; + private final JBTextField azureDeploymentIdField; + private final JBTextField azureApiVersionField; + + public AzureSettingsForm(AzureSettingsState settings) { + useAzureApiKeyAuthenticationRadioButton = new JBRadioButton( + CodeGPTBundle.get("settingsConfigurable.service.azure.useApiKeyAuth.label"), + settings.isUseAzureApiKeyAuthentication()); + useAzureActiveDirectoryAuthenticationRadioButton = new JBRadioButton( + CodeGPTBundle.get("settingsConfigurable.service.azure.useActiveDirectoryAuth.label"), + settings.isUseAzureActiveDirectoryAuthentication()); + azureApiKeyField = new JBPasswordField(); + azureApiKeyField.setColumns(30); + azureApiKeyField.setText(AzureCredentialsManager.getInstance().getApiKey()); + azureApiKeyFieldPanel = UI.PanelFactory.panel(azureApiKeyField) + .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) + .resizeX(false) + .createPanel(); + azureActiveDirectoryTokenField = new JBPasswordField(); + azureActiveDirectoryTokenField.setColumns(30); + azureActiveDirectoryTokenField.setText( + AzureCredentialsManager.getInstance().getActiveDirectoryToken()); + azureActiveDirectoryTokenFieldPanel = UI.PanelFactory.panel(azureActiveDirectoryTokenField) + .withLabel(CodeGPTBundle.get("settingsConfigurable.service.azure.bearerToken.label")) + .resizeX(false) + .createPanel(); + azureBaseHostField = new JBTextField(settings.getBaseHost(), 35); + azurePathField = new JBTextField(settings.getPath(), 35); + azureResourceNameField = new JBTextField(settings.getResourceName(), 35); + azureDeploymentIdField = new JBTextField(settings.getDeploymentId(), 35); + azureApiVersionField = new JBTextField(settings.getApiVersion(), 35); + + registerPanelsVisibility(settings); + registerRadioButtons(); + } + + public JPanel getForm() { + var authPanel = withEmptyLeftBorder(FormBuilder.createFormBuilder() + .addComponent(UI.PanelFactory + .panel(useAzureApiKeyAuthenticationRadioButton) + .resizeX(false) + .createPanel()) + .addComponent(withEmptyLeftBorder(azureApiKeyFieldPanel)) + .addComponent(UI.PanelFactory + .panel(useAzureActiveDirectoryAuthenticationRadioButton) + .resizeX(false) + .createPanel()) + .addComponent(withEmptyLeftBorder(azureActiveDirectoryTokenFieldPanel)) + .getPanel()); + + var configPanel = withEmptyLeftBorder(UI.PanelFactory.grid() + .add(UI.PanelFactory.panel(azureResourceNameField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.service.azure.resourceName.label")) + .resizeX(false) + .withComment(CodeGPTBundle.get( + "settingsConfigurable.service.azure.resourceName.comment"))) + .add(UI.PanelFactory.panel(azureDeploymentIdField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.service.azure.deploymentId.label")) + .resizeX(false) + .withComment(CodeGPTBundle.get( + "settingsConfigurable.service.azure.deploymentId.comment"))) + .add(UI.PanelFactory.panel(azureApiVersionField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.service.azure.apiVersion.label")) + .resizeX(false) + .withComment(CodeGPTBundle.get( + "settingsConfigurable.service.azure.apiVersion.comment"))) + .add(UI.PanelFactory.panel(azureBaseHostField) + .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.baseHost.label")) + .resizeX(false)) + .add(UI.PanelFactory.panel(azurePathField) + .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.path.label")) + .resizeX(false)) + .createPanel()); + + return FormBuilder.createFormBuilder() + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.shared.authentication.title"))) + .addComponent(authPanel) + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.shared.requestConfiguration.title"))) + .addComponent(configPanel) + .addComponentFillVertically(new JPanel(), 0) + .getPanel(); + } + + public AzureSettingsState getCurrentState() { + var state = new AzureSettingsState(); + state.setUseAzureActiveDirectoryAuthentication( + useAzureActiveDirectoryAuthenticationRadioButton.isSelected()); + state.setUseAzureApiKeyAuthentication(useAzureApiKeyAuthenticationRadioButton.isSelected()); + state.setResourceName(azureResourceNameField.getText()); + state.setDeploymentId(azureDeploymentIdField.getText()); + state.setApiVersion(azureApiVersionField.getText()); + state.setBaseHost(azureBaseHostField.getText()); + state.setPath(azurePathField.getText()); + return state; + } + + public void resetForm() { + var state = AzureSettings.getCurrentState(); + azureApiKeyField.setText(AzureCredentialsManager.getInstance().getApiKey()); + azureActiveDirectoryTokenField.setText( + AzureCredentialsManager.getInstance().getActiveDirectoryToken()); + useAzureApiKeyAuthenticationRadioButton.setSelected(state.isUseAzureApiKeyAuthentication()); + useAzureActiveDirectoryAuthenticationRadioButton.setSelected( + state.isUseAzureActiveDirectoryAuthentication()); + azureResourceNameField.setText(state.getResourceName()); + azureDeploymentIdField.setText(state.getDeploymentId()); + azureApiVersionField.setText(state.getApiVersion()); + azureBaseHostField.setText(state.getBaseHost()); + azurePathField.setText(state.getPath()); + } + + public @Nullable String getActiveDirectoryToken() { + var activeDirToken = new String(azureActiveDirectoryTokenField.getPassword()); + if (activeDirToken.isEmpty()) { + return null; + } + return activeDirToken; + } + + public @Nullable String getApiKey() { + var apiKey = new String(azureApiKeyField.getPassword()); + if (apiKey.isEmpty()) { + return null; + } + return apiKey; + } + + private void registerPanelsVisibility(AzureSettingsState azureSettings) { + azureApiKeyFieldPanel.setVisible(azureSettings.isUseAzureApiKeyAuthentication()); + azureActiveDirectoryTokenFieldPanel.setVisible( + azureSettings.isUseAzureActiveDirectoryAuthentication()); + } + + private void registerRadioButtons() { + registerRadioButtons(List.of( + Map.entry(useAzureApiKeyAuthenticationRadioButton, azureApiKeyFieldPanel), + Map.entry(useAzureActiveDirectoryAuthenticationRadioButton, + azureActiveDirectoryTokenFieldPanel))); + } + + // TODO: Move + private void registerRadioButtons(List> entries) { + var buttonGroup = new ButtonGroup(); + entries.forEach(entry -> buttonGroup.add(entry.getKey())); + entries.forEach(entry -> entry.getKey().addActionListener((e) -> { + for (Map.Entry innerEntry : entries) { + innerEntry.getValue().setVisible(innerEntry.equals(entry)); + } + })); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsState.java new file mode 100644 index 00000000..956e50f5 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/azure/AzureSettingsState.java @@ -0,0 +1,103 @@ +package ee.carlrobert.codegpt.settings.service.azure; + +import com.intellij.util.xmlb.annotations.Transient; +import java.util.Objects; + +public class AzureSettingsState { + + private static final String BASE_PATH = "/openai/deployments/%s/chat/completions?api-version=%s"; + + private String resourceName = ""; + private String deploymentId = ""; + private String apiVersion = ""; + private String baseHost = "https://%s.openai.azure.com"; + private String path = BASE_PATH; + private boolean useAzureApiKeyAuthentication = true; + private boolean useAzureActiveDirectoryAuthentication; + + @Transient + public boolean isUsingCustomPath() { + return !BASE_PATH.equals(path); + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getDeploymentId() { + return deploymentId; + } + + public void setDeploymentId(String deploymentId) { + this.deploymentId = deploymentId; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public String getBaseHost() { + return baseHost; + } + + public void setBaseHost(String baseHost) { + this.baseHost = baseHost; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public boolean isUseAzureApiKeyAuthentication() { + return useAzureApiKeyAuthentication; + } + + public void setUseAzureApiKeyAuthentication(boolean useAzureApiKeyAuthentication) { + this.useAzureApiKeyAuthentication = useAzureApiKeyAuthentication; + } + + public boolean isUseAzureActiveDirectoryAuthentication() { + return useAzureActiveDirectoryAuthentication; + } + + public void setUseAzureActiveDirectoryAuthentication( + boolean useAzureActiveDirectoryAuthentication) { + this.useAzureActiveDirectoryAuthentication = useAzureActiveDirectoryAuthentication; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AzureSettingsState that = (AzureSettingsState) o; + return useAzureApiKeyAuthentication == that.useAzureApiKeyAuthentication + && useAzureActiveDirectoryAuthentication == that.useAzureActiveDirectoryAuthentication + && Objects.equals(resourceName, that.resourceName) + && Objects.equals(deploymentId, that.deploymentId) + && Objects.equals(apiVersion, that.apiVersion) + && Objects.equals(baseHost, that.baseHost) + && Objects.equals(path, that.path); + } + + @Override + public int hashCode() { + return Objects.hash(resourceName, deploymentId, apiVersion, baseHost, path, + useAzureApiKeyAuthentication, useAzureActiveDirectoryAuthentication); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettings.java new file mode 100644 index 00000000..e188a80d --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettings.java @@ -0,0 +1,42 @@ +package ee.carlrobert.codegpt.settings.service.llama; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import ee.carlrobert.codegpt.credentials.LlamaCredentialManager; +import ee.carlrobert.codegpt.settings.service.llama.form.LlamaSettingsForm; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +@State(name = "CodeGPT", storages = @Storage("CodeGPT_LlamaSettings.xml")) +public class LlamaSettings implements PersistentStateComponent { + + private LlamaSettingsState state = new LlamaSettingsState(); + + @Override + @NotNull + public LlamaSettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull LlamaSettingsState state) { + this.state = state; + } + + public static LlamaSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static LlamaSettings getInstance() { + return ApplicationManager.getApplication().getService(LlamaSettings.class); + } + + public boolean isModified(LlamaSettingsForm form) { + return !form.getCurrentState().equals(state) + || !StringUtils.equals( + form.getLlamaServerPreferencesForm().getApiKey(), + LlamaCredentialManager.getInstance().getCredential()); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java new file mode 100644 index 00000000..bbb2b51e --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java @@ -0,0 +1,213 @@ +package ee.carlrobert.codegpt.settings.service.llama; + +import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate; +import ee.carlrobert.codegpt.completions.HuggingFaceModel; +import ee.carlrobert.codegpt.completions.llama.PromptTemplate; +import java.io.IOException; +import java.net.ServerSocket; +import java.util.Objects; + +public class LlamaSettingsState { + + private boolean runLocalServer = true; + private boolean useCustomModel; + private String customLlamaModelPath = ""; + private HuggingFaceModel huggingFaceModel = HuggingFaceModel.CODE_LLAMA_7B_Q4; + private PromptTemplate localModelPromptTemplate = PromptTemplate.LLAMA; + private PromptTemplate remoteModelPromptTemplate = PromptTemplate.LLAMA; + private InfillPromptTemplate localModelInfillPromptTemplate = InfillPromptTemplate.LLAMA; + private InfillPromptTemplate remoteModelInfillPromptTemplate = InfillPromptTemplate.LLAMA; + private String baseHost = "http://localhost:8080"; + private Integer serverPort = getRandomAvailablePortOrDefault(); + private int contextSize = 2048; + private int threads = 8; + private String additionalParameters = ""; + private int topK = 40; + private double topP = 0.9; + private double minP = 0.05; + private double repeatPenalty = 1.1; + + public boolean isUseCustomModel() { + return useCustomModel; + } + + public void setUseCustomModel(boolean useCustomModel) { + this.useCustomModel = useCustomModel; + } + + public String getCustomLlamaModelPath() { + return customLlamaModelPath; + } + + public void setCustomLlamaModelPath(String customLlamaModelPath) { + this.customLlamaModelPath = customLlamaModelPath; + } + + public HuggingFaceModel getHuggingFaceModel() { + return huggingFaceModel; + } + + public void setHuggingFaceModel(HuggingFaceModel huggingFaceModel) { + this.huggingFaceModel = huggingFaceModel; + } + + public PromptTemplate getLocalModelPromptTemplate() { + return localModelPromptTemplate; + } + + public void setLocalModelPromptTemplate( + PromptTemplate localModelPromptTemplate) { + this.localModelPromptTemplate = localModelPromptTemplate; + } + + public InfillPromptTemplate getLocalModelInfillPromptTemplate() { + return localModelInfillPromptTemplate; + } + + public void setLocalModelInfillPromptTemplate( + InfillPromptTemplate localModelInfillPromptTemplate) { + this.localModelInfillPromptTemplate = localModelInfillPromptTemplate; + } + + public InfillPromptTemplate getRemoteModelInfillPromptTemplate() { + return remoteModelInfillPromptTemplate; + } + + public void setRemoteModelInfillPromptTemplate( + InfillPromptTemplate remoteModelInfillPromptTemplate) { + this.remoteModelInfillPromptTemplate = remoteModelInfillPromptTemplate; + } + + public boolean isRunLocalServer() { + return runLocalServer; + } + + public void setRunLocalServer(boolean runLocalServer) { + this.runLocalServer = runLocalServer; + } + + public String getBaseHost() { + return baseHost; + } + + public void setBaseHost(String baseHost) { + this.baseHost = baseHost; + } + + public PromptTemplate getRemoteModelPromptTemplate() { + return remoteModelPromptTemplate; + } + + public void setRemoteModelPromptTemplate( + PromptTemplate remoteModelPromptTemplate) { + this.remoteModelPromptTemplate = remoteModelPromptTemplate; + } + + public Integer getServerPort() { + return serverPort; + } + + public void setServerPort(Integer serverPort) { + this.serverPort = serverPort; + } + + public int getContextSize() { + return contextSize; + } + + public void setContextSize(int contextSize) { + this.contextSize = contextSize; + } + + public int getThreads() { + return threads; + } + + public void setThreads(int threads) { + this.threads = threads; + } + + public String getAdditionalParameters() { + return additionalParameters; + } + + public void setAdditionalParameters(String additionalParameters) { + this.additionalParameters = additionalParameters; + } + + public int getTopK() { + return topK; + } + + public void setTopK(int topK) { + this.topK = topK; + } + + public double getTopP() { + return topP; + } + + public void setTopP(double topP) { + this.topP = topP; + } + + public double getMinP() { + return minP; + } + + public void setMinP(double minP) { + this.minP = minP; + } + + public double getRepeatPenalty() { + return repeatPenalty; + } + + public void setRepeatPenalty(double repeatPenalty) { + this.repeatPenalty = repeatPenalty; + } + + private static Integer getRandomAvailablePortOrDefault() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } catch (IOException e) { + return 8080; + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LlamaSettingsState that = (LlamaSettingsState) o; + return runLocalServer == that.runLocalServer + && useCustomModel == that.useCustomModel + && contextSize == that.contextSize + && threads == that.threads + && topK == that.topK + && Double.compare(that.topP, topP) == 0 + && Double.compare(that.minP, minP) == 0 + && Double.compare(that.repeatPenalty, repeatPenalty) == 0 + && Objects.equals(customLlamaModelPath, that.customLlamaModelPath) + && huggingFaceModel == that.huggingFaceModel + && localModelPromptTemplate == that.localModelPromptTemplate + && remoteModelPromptTemplate == that.remoteModelPromptTemplate + && localModelInfillPromptTemplate == that.localModelInfillPromptTemplate + && remoteModelInfillPromptTemplate == that.remoteModelInfillPromptTemplate + && Objects.equals(baseHost, that.baseHost) + && Objects.equals(serverPort, that.serverPort) + && Objects.equals(additionalParameters, that.additionalParameters); + } + + @Override + public int hashCode() { + return Objects.hash(runLocalServer, useCustomModel, customLlamaModelPath, huggingFaceModel, + localModelPromptTemplate, remoteModelPromptTemplate, localModelInfillPromptTemplate, + remoteModelInfillPromptTemplate, baseHost, serverPort, contextSize, threads, + additionalParameters, topK, topP, minP, repeatPenalty); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/ui/BasePromptTemplatePanel.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/BasePromptTemplatePanel.java similarity index 97% rename from src/main/java/ee/carlrobert/codegpt/ui/BasePromptTemplatePanel.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/BasePromptTemplatePanel.java index 0b0de532..09553d39 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/BasePromptTemplatePanel.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/BasePromptTemplatePanel.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.ui; +package ee.carlrobert.codegpt.settings.service.llama.form; import com.intellij.icons.AllIcons.General; import com.intellij.ide.HelpTooltip; diff --git a/src/main/java/ee/carlrobert/codegpt/ui/ChatPromptTemplatePanel.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ChatPromptTemplatePanel.java similarity index 92% rename from src/main/java/ee/carlrobert/codegpt/ui/ChatPromptTemplatePanel.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ChatPromptTemplatePanel.java index db656350..425df417 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/ChatPromptTemplatePanel.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ChatPromptTemplatePanel.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.ui; +package ee.carlrobert.codegpt.settings.service.llama.form; import ee.carlrobert.codegpt.completions.llama.PromptTemplate; import ee.carlrobert.codegpt.conversations.message.Message; diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/DownloadModelAction.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/DownloadModelAction.java similarity index 98% rename from src/main/java/ee/carlrobert/codegpt/settings/service/DownloadModelAction.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/DownloadModelAction.java index 1f91dadb..87f6c236 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/DownloadModelAction.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/DownloadModelAction.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.llama.form; import static java.lang.String.format; diff --git a/src/main/java/ee/carlrobert/codegpt/ui/InfillPromptTemplatePanel.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/InfillPromptTemplatePanel.java similarity index 91% rename from src/main/java/ee/carlrobert/codegpt/ui/InfillPromptTemplatePanel.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/InfillPromptTemplatePanel.java index 66d56e10..e1c681fd 100644 --- a/src/main/java/ee/carlrobert/codegpt/ui/InfillPromptTemplatePanel.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/InfillPromptTemplatePanel.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.ui; +package ee.carlrobert.codegpt.settings.service.llama.form; import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate; diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaModelPreferencesForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaModelPreferencesForm.java similarity index 94% rename from src/main/java/ee/carlrobert/codegpt/settings/service/LlamaModelPreferencesForm.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaModelPreferencesForm.java index 8bf3554d..22531e27 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaModelPreferencesForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaModelPreferencesForm.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.llama.form; import static java.lang.String.format; import static java.util.stream.Collectors.toList; @@ -29,9 +29,8 @@ import ee.carlrobert.codegpt.completions.HuggingFaceModel; import ee.carlrobert.codegpt.completions.llama.LlamaModel; import ee.carlrobert.codegpt.completions.llama.LlamaServerAgent; import ee.carlrobert.codegpt.completions.llama.PromptTemplate; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.ui.ChatPromptTemplatePanel; -import ee.carlrobert.codegpt.ui.InfillPromptTemplatePanel; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettingsState; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Dimension; @@ -86,7 +85,7 @@ public class LlamaModelPreferencesForm { progressLabel.setBorder(JBUI.Borders.emptyLeft(2)); progressLabel.setFont(JBUI.Fonts.smallFont()); modelExistsIcon = new JBLabel(Actions.Checked); - var llamaSettings = LlamaSettingsState.getInstance(); + var llamaSettings = LlamaSettings.getCurrentState(); modelExistsIcon.setVisible(isModelExists(llamaSettings.getHuggingFaceModel())); helpIcon = new JBLabel(General.ContextHelp); huggingFaceComboBoxModel = new DefaultComboBoxModel<>(); @@ -152,6 +151,14 @@ public class LlamaModelPreferencesForm { return finalPanel; } + public void resetForm(LlamaSettingsState state) { + huggingFaceComboBoxModel.setSelectedItem(state.getHuggingFaceModel()); + browsableCustomModelTextField.setText(state.getCustomLlamaModelPath()); + customModelRadioButton.setSelected(state.isUseCustomModel()); + localPromptTemplatePanel.setPromptTemplate(state.getLocalModelPromptTemplate()); + infillPromptTemplatePanel.setPromptTemplate(state.getLocalModelInfillPromptTemplate()); + } + public void enableFields(boolean enabled) { modelComboBox.setEnabled(enabled); modelSizeComboBox.setEnabled(enabled); @@ -166,42 +173,22 @@ public class LlamaModelPreferencesForm { return huggingFaceModelComboBox; } - public void setSelectedModel(HuggingFaceModel model) { - huggingFaceComboBoxModel.setSelectedItem(model); - } - public HuggingFaceModel getSelectedModel() { return (HuggingFaceModel) huggingFaceComboBoxModel.getSelectedItem(); } - public void setCustomLlamaModelPath(String modelPath) { - browsableCustomModelTextField.setText(modelPath); - } - public String getCustomLlamaModelPath() { return browsableCustomModelTextField.getText(); } - public void setUseCustomLlamaModel(boolean useCustomLlamaModel) { - customModelRadioButton.setSelected(useCustomLlamaModel); - } - public boolean isUseCustomLlamaModel() { return customModelRadioButton.isSelected(); } - public void setPromptTemplate(PromptTemplate promptTemplate) { - localPromptTemplatePanel.setPromptTemplate(promptTemplate); - } - public PromptTemplate getPromptTemplate() { return localPromptTemplatePanel.getPromptTemplate(); } - public void setInfillPromptTemplate(InfillPromptTemplate promptTemplate) { - infillPromptTemplatePanel.setPromptTemplate(promptTemplate); - } - public InfillPromptTemplate getInfillPromptTemplate() { return infillPromptTemplatePanel.getPromptTemplate(); } @@ -479,9 +466,8 @@ public class LlamaModelPreferencesForm { actionLinkWrapper, huggingFaceComboBoxModel)); actionLinkWrapper.setVisible(false); - LlamaSettingsState.getInstance() - .setHuggingFaceModel( - (HuggingFaceModel) huggingFaceComboBoxModel.getSelectedItem()); + LlamaSettings.getCurrentState().setHuggingFaceModel( + (HuggingFaceModel) huggingFaceComboBoxModel.getSelectedItem()); }), (error) -> { throw new RuntimeException(error); diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaRequestPreferencesForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaRequestPreferencesForm.java similarity index 82% rename from src/main/java/ee/carlrobert/codegpt/settings/service/LlamaRequestPreferencesForm.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaRequestPreferencesForm.java index c5de34b7..b48e4109 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaRequestPreferencesForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaRequestPreferencesForm.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.llama.form; import com.intellij.openapi.ui.panel.ComponentPanelBuilder; import com.intellij.ui.components.JBTextField; @@ -6,7 +6,7 @@ import com.intellij.ui.components.fields.IntegerField; import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.JBUI; import ee.carlrobert.codegpt.CodeGPTBundle; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettingsState; import javax.swing.JLabel; import javax.swing.JPanel; @@ -17,8 +17,7 @@ public class LlamaRequestPreferencesForm { private final JBTextField minPField; private final JBTextField repeatPenaltyField; - public LlamaRequestPreferencesForm() { - var llamaSettings = LlamaSettingsState.getInstance(); + public LlamaRequestPreferencesForm(LlamaSettingsState llamaSettings) { topKField = new IntegerField(); topKField.setColumns(12); topKField.setValue(llamaSettings.getTopK()); @@ -56,38 +55,29 @@ public class LlamaRequestPreferencesForm { .getPanel(); } - public int getTopK() { - return topKField.getValue(); + public void resetForm(LlamaSettingsState state) { + topKField.setValue(state.getTopK()); + topPField.setText(String.valueOf((state.getTopP()))); + minPField.setText(String.valueOf((state.getMinP()))); + repeatPenaltyField.setText(String.valueOf((state.getRepeatPenalty()))); } - public void setTopK(int topK) { - topKField.setValue(topK); + public int getTopK() { + return topKField.getValue(); } public double getTopP() { return Double.parseDouble(topPField.getText()); } - public void setTopP(double topP) { - topPField.setText(String.valueOf(topP)); - } - public double getMinP() { return Double.parseDouble(minPField.getText()); } - public void setMinP(double minP) { - minPField.setText(String.valueOf(minP)); - } - public double getRepeatPenalty() { return Double.parseDouble(repeatPenaltyField.getText()); } - public void setRepeatPenalty(double repeatPenalty) { - repeatPenaltyField.setText(String.valueOf(repeatPenalty)); - } - private JLabel createComment(String messageKey) { var comment = ComponentPanelBuilder.createCommentComponent( CodeGPTBundle.get(messageKey), true); diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServerPreferencesForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaServerPreferencesForm.java similarity index 86% rename from src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServerPreferencesForm.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaServerPreferencesForm.java index 089a999f..15806804 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/LlamaServerPreferencesForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaServerPreferencesForm.java @@ -1,4 +1,4 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.llama.form; import static ee.carlrobert.codegpt.ui.UIUtil.createComment; import static ee.carlrobert.codegpt.ui.UIUtil.createForm; @@ -26,10 +26,8 @@ import ee.carlrobert.codegpt.completions.HuggingFaceModel; import ee.carlrobert.codegpt.completions.llama.LlamaServerAgent; import ee.carlrobert.codegpt.completions.llama.LlamaServerStartupParams; import ee.carlrobert.codegpt.completions.llama.PromptTemplate; -import ee.carlrobert.codegpt.credentials.LlamaCredentialsManager; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.ui.ChatPromptTemplatePanel; -import ee.carlrobert.codegpt.ui.InfillPromptTemplatePanel; +import ee.carlrobert.codegpt.credentials.LlamaCredentialManager; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettingsState; import ee.carlrobert.codegpt.ui.OverlayUtil; import ee.carlrobert.codegpt.ui.UIUtil; import ee.carlrobert.codegpt.ui.UIUtil.RadioButtonWithLayout; @@ -38,6 +36,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import javax.annotation.Nullable; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; @@ -61,42 +60,40 @@ public class LlamaServerPreferencesForm { private final ChatPromptTemplatePanel remotePromptTemplatePanel; private final InfillPromptTemplatePanel infillPromptTemplatePanel; - public LlamaServerPreferencesForm() { - var llamaSettings = LlamaSettingsState.getInstance(); - var llamaServerAgent = - ApplicationManager.getApplication().getService(LlamaServerAgent.class); + public LlamaServerPreferencesForm(LlamaSettingsState settings) { + var llamaServerAgent = ApplicationManager.getApplication().getService(LlamaServerAgent.class); var serverRunning = llamaServerAgent.isServerRunning(); - portField = new PortField(llamaSettings.getServerPort()); + portField = new PortField(settings.getServerPort()); portField.setEnabled(!serverRunning); maxTokensField = new IntegerField("max_tokens", 256, 4096); maxTokensField.setColumns(12); - maxTokensField.setValue(llamaSettings.getContextSize()); + maxTokensField.setValue(settings.getContextSize()); maxTokensField.setEnabled(!serverRunning); threadsField = new IntegerField("threads", 1, 256); threadsField.setColumns(12); - threadsField.setValue(llamaSettings.getThreads()); + threadsField.setValue(settings.getThreads()); threadsField.setEnabled(!serverRunning); - additionalParametersField = new JBTextField(llamaSettings.getAdditionalParameters(), 30); + additionalParametersField = new JBTextField(settings.getAdditionalParameters(), 30); additionalParametersField.setEnabled(!serverRunning); - baseHostField = new JBTextField(llamaSettings.getBaseHost(), 30); + baseHostField = new JBTextField(settings.getBaseHost(), 30); apiKeyField = new JBPasswordField(); apiKeyField.setColumns(30); - apiKeyField.setText(LlamaCredentialsManager.getInstance().getApiKey()); + apiKeyField.setText(LlamaCredentialManager.getInstance().getCredential()); llamaModelPreferencesForm = new LlamaModelPreferencesForm(); runLocalServerRadioButton = new JBRadioButton("Run local server", - llamaSettings.isRunLocalServer()); + settings.isRunLocalServer()); useExistingServerRadioButton = new JBRadioButton("Use remote server", - !llamaSettings.isRunLocalServer()); + !settings.isRunLocalServer()); remotePromptTemplatePanel = new ChatPromptTemplatePanel( - llamaSettings.getRemoteModelPromptTemplate(), true); + settings.getRemoteModelPromptTemplate(), true); infillPromptTemplatePanel = new InfillPromptTemplatePanel( - llamaSettings.getRemoteModelInfillPromptTemplate(), true + settings.getRemoteModelInfillPromptTemplate(), true ); } @@ -113,6 +110,22 @@ public class LlamaServerPreferencesForm { : USE_EXISTING_SERVER_FORM_CARD_CODE); } + public void resetForm(LlamaSettingsState state) { + llamaModelPreferencesForm.resetForm(state); + + remotePromptTemplatePanel.setPromptTemplate(state.getLocalModelPromptTemplate()); // ? + infillPromptTemplatePanel.setPromptTemplate(state.getLocalModelInfillPromptTemplate()); + runLocalServerRadioButton.setSelected(state.isRunLocalServer()); + baseHostField.setText(state.getBaseHost()); + portField.setNumber(state.getServerPort()); + maxTokensField.setValue(state.getContextSize()); + threadsField.setValue(state.getThreads()); + additionalParametersField.setText(state.getAdditionalParameters()); + remotePromptTemplatePanel.setPromptTemplate(state.getRemoteModelPromptTemplate()); // ? + infillPromptTemplatePanel.setPromptTemplate(state.getRemoteModelInfillPromptTemplate()); + apiKeyField.setText(LlamaCredentialManager.getInstance().getCredential()); + } + public JComponent createUseExistingServerForm() { var apiKeyFieldPanel = UI.PanelFactory.panel(apiKeyField) .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) @@ -230,7 +243,6 @@ public class LlamaServerPreferencesForm { return validateCustomModelPath() && validateSelectedModel(); } - private boolean validateCustomModelPath() { if (llamaModelPreferencesForm.isUseCustomLlamaModel()) { var customModelPath = llamaModelPreferencesForm.getCustomLlamaModelPath(); @@ -257,13 +269,11 @@ public class LlamaServerPreferencesForm { return true; } - private boolean isModelExists(HuggingFaceModel model) { return FileUtil.exists( CodeGPTPlugin.getLlamaModelsPath() + File.separator + model.getFileName()); } - private void enableForm(JButton serverButton, ServerProgressPanel progressPanel) { setFormEnabled(true); serverButton.setText( @@ -290,27 +300,14 @@ public class LlamaServerPreferencesForm { additionalParametersField.setEnabled(enabled); } - - public void setRunLocalServer(boolean runLocalServer) { - runLocalServerRadioButton.setSelected(runLocalServer); - } - public boolean isRunLocalServer() { return runLocalServerRadioButton.isSelected(); } - public void setBaseHost(String baseHost) { - baseHostField.setText(baseHost); - } - public String getBaseHost() { return baseHostField.getText(); } - public void setServerPort(int serverPort) { - portField.setNumber(serverPort); - } - public int getServerPort() { return portField.getNumber(); } @@ -319,15 +316,10 @@ public class LlamaServerPreferencesForm { return llamaModelPreferencesForm; } - public int getContextSize() { return maxTokensField.getValue(); } - public void setContextSize(int contextSize) { - maxTokensField.setValue(contextSize); - } - public void setThreads(int threads) { threadsField.setValue(threads); } @@ -336,10 +328,6 @@ public class LlamaServerPreferencesForm { return threadsField.getValue(); } - public void setAdditionalParameters(String additionalParameters) { - additionalParametersField.setText(additionalParameters); - } - public String getAdditionalParameters() { return additionalParametersField.getText(); } @@ -359,22 +347,14 @@ public class LlamaServerPreferencesForm { : remotePromptTemplatePanel.getPromptTemplate(); } - public void setApiKey(String apiKey) { - apiKeyField.setText(apiKey); - } - - public String getApiKey() { + public @Nullable String getApiKey() { + var apiKey = new String(apiKeyField.getPassword()); + if (apiKey.isEmpty()) { + return null; + } return new String(apiKeyField.getPassword()); } - public void setPromptTemplate(PromptTemplate promptTemplate) { - remotePromptTemplatePanel.setPromptTemplate(promptTemplate); - } - - public void setInfillPromptTemplate(InfillPromptTemplate promptTemplate) { - infillPromptTemplatePanel.setPromptTemplate(promptTemplate); - } - public InfillPromptTemplate getInfillPromptTemplate() { return infillPromptTemplatePanel.getPromptTemplate(); } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaSettingsForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaSettingsForm.java new file mode 100644 index 00000000..caa9de03 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/LlamaSettingsForm.java @@ -0,0 +1,71 @@ +package ee.carlrobert.codegpt.settings.service.llama.form; + +import static ee.carlrobert.codegpt.ui.UIUtil.withEmptyLeftBorder; + +import com.intellij.ui.TitledSeparator; +import com.intellij.util.ui.FormBuilder; +import ee.carlrobert.codegpt.CodeGPTBundle; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettingsState; +import java.awt.BorderLayout; +import javax.swing.JPanel; + +public class LlamaSettingsForm extends JPanel { + + private final LlamaServerPreferencesForm llamaServerPreferencesForm; + private final LlamaRequestPreferencesForm llamaRequestPreferencesForm; + + public LlamaSettingsForm(LlamaSettingsState settings) { + llamaServerPreferencesForm = new LlamaServerPreferencesForm(settings); + llamaRequestPreferencesForm = new LlamaRequestPreferencesForm(settings); + init(); + } + + public LlamaSettingsState getCurrentState() { + var state = new LlamaSettingsState(); + state.setTopK(llamaRequestPreferencesForm.getTopK()); + state.setTopP(llamaRequestPreferencesForm.getTopP()); + state.setMinP(llamaRequestPreferencesForm.getMinP()); + state.setRepeatPenalty(llamaRequestPreferencesForm.getRepeatPenalty()); + + state.setRemoteModelPromptTemplate(llamaServerPreferencesForm.getPromptTemplate()); + state.setRemoteModelInfillPromptTemplate(llamaServerPreferencesForm.getInfillPromptTemplate()); + state.setRunLocalServer(llamaServerPreferencesForm.isRunLocalServer()); + state.setBaseHost(llamaServerPreferencesForm.getBaseHost()); + state.setServerPort(llamaServerPreferencesForm.getServerPort()); + state.setContextSize(llamaServerPreferencesForm.getContextSize()); + state.setThreads(llamaServerPreferencesForm.getThreads()); + state.setAdditionalParameters(llamaServerPreferencesForm.getAdditionalParameters()); + + var modelPreferencesForm = llamaServerPreferencesForm.getLlamaModelPreferencesForm(); + state.setCustomLlamaModelPath(modelPreferencesForm.getCustomLlamaModelPath()); + state.setHuggingFaceModel(modelPreferencesForm.getSelectedModel()); + state.setUseCustomModel(modelPreferencesForm.isUseCustomLlamaModel()); + state.setLocalModelPromptTemplate(modelPreferencesForm.getPromptTemplate()); + state.setLocalModelInfillPromptTemplate(modelPreferencesForm.getInfillPromptTemplate()); + + return state; + } + + public void resetForm() { + var state = LlamaSettings.getCurrentState(); + llamaServerPreferencesForm.resetForm(state); + llamaRequestPreferencesForm.resetForm(state); + } + + public LlamaServerPreferencesForm getLlamaServerPreferencesForm() { + return llamaServerPreferencesForm; + } + + private void init() { + setLayout(new BorderLayout()); + add(FormBuilder.createFormBuilder() + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.service.llama.serverPreferences.title"))) + .addComponent(llamaServerPreferencesForm.getForm()) + .addComponent(new TitledSeparator("Request Preferences")) + .addComponent(withEmptyLeftBorder(llamaRequestPreferencesForm.getForm())) + .addComponentFillVertically(new JPanel(), 0) + .getPanel()); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/ServerProgressPanel.java b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ServerProgressPanel.java similarity index 86% rename from src/main/java/ee/carlrobert/codegpt/settings/service/ServerProgressPanel.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ServerProgressPanel.java index 4006059a..9a755003 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/ServerProgressPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ServerProgressPanel.java @@ -1,9 +1,7 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.llama.form; import com.intellij.ui.components.JBLabel; import com.intellij.util.ui.AsyncProcessIcon; -import java.awt.FlowLayout; -import javax.swing.Box; import javax.swing.JComponent; import javax.swing.JPanel; diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettings.java b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettings.java new file mode 100644 index 00000000..d75b2bd6 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettings.java @@ -0,0 +1,41 @@ +package ee.carlrobert.codegpt.settings.service.openai; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +@State(name = "CodeGPT_OpenAISettings_210", storages = @Storage("CodeGPT_OpenAISettings_210.xml")) +public class OpenAISettings implements PersistentStateComponent { + + private OpenAISettingsState state = new OpenAISettingsState(); + + @Override + @NotNull + public OpenAISettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull OpenAISettingsState state) { + this.state = state; + } + + public static OpenAISettingsState getCurrentState() { + return getInstance().getState(); + } + + public static OpenAISettings getInstance() { + return ApplicationManager.getApplication().getService(OpenAISettings.class); + } + + public boolean isModified(OpenAISettingsForm form) { + return !form.getCurrentState().equals(state) + || !StringUtils.equals( + form.getApiKey(), + OpenAICredentialManager.getInstance().getCredential()); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsForm.java new file mode 100644 index 00000000..bf160b9d --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsForm.java @@ -0,0 +1,108 @@ +package ee.carlrobert.codegpt.settings.service.openai; + +import static ee.carlrobert.codegpt.ui.UIUtil.withEmptyLeftBorder; + +import com.intellij.openapi.ui.ComboBox; +import com.intellij.ui.EnumComboBoxModel; +import com.intellij.ui.TitledSeparator; +import com.intellij.ui.components.JBPasswordField; +import com.intellij.ui.components.JBTextField; +import com.intellij.util.ui.FormBuilder; +import com.intellij.util.ui.UI; +import ee.carlrobert.codegpt.CodeGPTBundle; +import ee.carlrobert.codegpt.credentials.OpenAICredentialManager; +import ee.carlrobert.codegpt.ui.UIUtil; +import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; +import javax.swing.JPanel; + +public class OpenAISettingsForm { + + private final JBPasswordField openAIApiKeyField; + private final JBTextField openAIBaseHostField; + private final JBTextField openAIPathField; + private final JBTextField openAIOrganizationField; + private final ComboBox openAICompletionModelComboBox; + + public OpenAISettingsForm(OpenAISettingsState settings) { + openAIApiKeyField = new JBPasswordField(); + openAIApiKeyField.setColumns(30); + openAIApiKeyField.setText(OpenAICredentialManager.getInstance().getCredential()); + openAIBaseHostField = new JBTextField(settings.getBaseHost(), 30); + openAIPathField = new JBTextField(settings.getPath(), 30); + openAIOrganizationField = new JBTextField(settings.getOrganization(), 30); + openAICompletionModelComboBox = new ComboBox<>( + new EnumComboBoxModel<>(OpenAIChatCompletionModel.class)); + openAICompletionModelComboBox.setSelectedItem( + OpenAIChatCompletionModel.findByCode(settings.getModel())); + } + + public JPanel getForm() { + var requestConfigurationPanel = UI.PanelFactory.grid() + .add(UI.PanelFactory.panel(openAICompletionModelComboBox) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.shared.model.label")) + .resizeX(false)) + .add(UI.PanelFactory.panel(openAIOrganizationField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.service.openai.organization.label")) + .resizeX(false) + .withComment(CodeGPTBundle.get( + "settingsConfigurable.section.openai.organization.comment"))) + .add(UI.PanelFactory.panel(openAIBaseHostField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.shared.baseHost.label")) + .resizeX(false)) + .add(UI.PanelFactory.panel(openAIPathField) + .withLabel(CodeGPTBundle.get( + "settingsConfigurable.shared.path.label")) + .resizeX(false)) + .createPanel(); + + var apiKeyFieldPanel = UI.PanelFactory.panel(openAIApiKeyField) + .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) + .resizeX(false) + .withComment( + CodeGPTBundle.get("settingsConfigurable.service.openai.apiKey.comment")) + .withCommentHyperlinkListener(UIUtil::handleHyperlinkClicked) + .createPanel(); + + return FormBuilder.createFormBuilder() + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.shared.authentication.title"))) + .addComponent(withEmptyLeftBorder(apiKeyFieldPanel)) + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.shared.requestConfiguration.title"))) + .addComponent(withEmptyLeftBorder(requestConfigurationPanel)) + .addComponentFillVertically(new JPanel(), 0) + .getPanel(); + } + + public String getApiKey() { + return new String(openAIApiKeyField.getPassword()); + } + + public String getModel() { + return ((OpenAIChatCompletionModel) (openAICompletionModelComboBox.getModel() + .getSelectedItem())) + .getCode(); + } + + public OpenAISettingsState getCurrentState() { + var state = new OpenAISettingsState(); + state.setOrganization(openAIOrganizationField.getText()); + state.setBaseHost(openAIBaseHostField.getText()); + state.setPath(openAIPathField.getText()); + state.setModel(getModel()); + return state; + } + + public void resetForm() { + var state = OpenAISettings.getCurrentState(); + openAIApiKeyField.setText(OpenAICredentialManager.getInstance().getCredential()); + openAIOrganizationField.setText(state.getOrganization()); + openAIBaseHostField.setText(state.getBaseHost()); + openAIPathField.setText(state.getPath()); + openAICompletionModelComboBox.setSelectedItem( + OpenAIChatCompletionModel.findByCode(state.getModel())); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsState.java new file mode 100644 index 00000000..e321886f --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsState.java @@ -0,0 +1,70 @@ +package ee.carlrobert.codegpt.settings.service.openai; + +import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; +import java.util.Objects; + +public class OpenAISettingsState { + + private static final String BASE_PATH = "/v1/chat/completions"; + + private String organization = ""; + private String baseHost = "https://api.openai.com"; + private String path = BASE_PATH; + private String model = OpenAIChatCompletionModel.GPT_3_5.getCode(); + + public boolean isUsingCustomPath() { + return !BASE_PATH.equals(path); + } + + public String getOrganization() { + return organization; + } + + public void setOrganization(String organization) { + this.organization = organization; + } + + public String getBaseHost() { + return baseHost; + } + + public void setBaseHost(String openAIBaseHost) { + this.baseHost = openAIBaseHost; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OpenAISettingsState that = (OpenAISettingsState) o; + return Objects.equals(organization, that.organization) + && Objects.equals(baseHost, that.baseHost) + && Objects.equals(path, that.path) + && Objects.equals(model, that.model); + } + + @Override + public int hashCode() { + return Objects.hash(organization, baseHost, path, model); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettings.java b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettings.java new file mode 100644 index 00000000..a94cec1b --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettings.java @@ -0,0 +1,40 @@ +package ee.carlrobert.codegpt.settings.service.you; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import ee.carlrobert.codegpt.credentials.YouCredentialManager; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +@State(name = "CodeGPT_YouSettings", storages = @Storage("CodeGPT_YouSettings.xml")) +public class YouSettings implements PersistentStateComponent { + + private YouSettingsState state = new YouSettingsState(); + + @Override + @NotNull + public YouSettingsState getState() { + return state; + } + + @Override + public void loadState(@NotNull YouSettingsState state) { + this.state = state; + } + + public static YouSettingsState getCurrentState() { + return getInstance().getState(); + } + + public static YouSettings getInstance() { + return ApplicationManager.getApplication().getService(YouSettings.class); + } + + public boolean isModified(YouSettingsForm form) { + var password = YouCredentialManager.getInstance().getCredential(); + return !form.getCurrentState().equals(state) + || !StringUtils.equals(form.getPassword(), password); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/YouServiceSelectionForm.java b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsForm.java similarity index 73% rename from src/main/java/ee/carlrobert/codegpt/settings/service/YouServiceSelectionForm.java rename to src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsForm.java index 51d1bd12..d0b1e920 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/YouServiceSelectionForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsForm.java @@ -1,4 +1,6 @@ -package ee.carlrobert.codegpt.settings.service; +package ee.carlrobert.codegpt.settings.service.you; + +import static ee.carlrobert.codegpt.ui.UIUtil.withEmptyLeftBorder; import com.intellij.openapi.Disposable; import com.intellij.openapi.ui.ComponentValidator; @@ -6,6 +8,7 @@ import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.JBColor; import com.intellij.ui.TitledSeparator; +import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBPasswordField; import com.intellij.ui.components.JBTextField; @@ -20,8 +23,7 @@ import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationError; import ee.carlrobert.codegpt.completions.you.auth.YouAuthenticationService; import ee.carlrobert.codegpt.completions.you.auth.response.YouAuthenticationResponse; import ee.carlrobert.codegpt.completions.you.auth.response.YouUser; -import ee.carlrobert.codegpt.credentials.YouCredentialsManager; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.credentials.YouCredentialManager; import ee.carlrobert.codegpt.ui.UIUtil; import java.awt.BorderLayout; import java.awt.FlowLayout; @@ -34,28 +36,31 @@ import javax.swing.JTextPane; import javax.swing.SwingUtilities; import org.jetbrains.annotations.Nullable; -public class YouServiceSelectionForm extends JPanel { +public class YouSettingsForm extends JPanel { private final JBTextField emailField; private final JBPasswordField passwordField; private final JButton signInButton; private final JTextPane signUpTextPane; private final AsyncProcessIcon loadingSpinner; + private final JBCheckBox displayWebSearchResultsCheckBox; - public YouServiceSelectionForm(Disposable parentDisposable) { + public YouSettingsForm(YouSettingsState settings, Disposable parentDisposable) { super(new BorderLayout()); - var settings = SettingsState.getInstance(); emailField = new JBTextField(settings.getEmail(), 25); passwordField = new JBPasswordField(); passwordField.setColumns(25); if (!settings.getEmail().isEmpty()) { - passwordField.setText(YouCredentialsManager.getInstance().getAccountPassword()); + passwordField.setText(YouCredentialManager.getInstance().getCredential()); } signInButton = new JButton(CodeGPTBundle.get("settingsConfigurable.service.you.signIn.label")); signUpTextPane = createSignUpTextPane(); loadingSpinner = new AsyncProcessIcon("sign_in_spinner"); loadingSpinner.setBorder(JBUI.Borders.emptyLeft(8)); loadingSpinner.setVisible(false); + displayWebSearchResultsCheckBox = new JBCheckBox( + CodeGPTBundle.get("settingsConfigurable.service.you.displayResults.label"), + YouSettings.getCurrentState().isDisplayWebSearchResults()); var emailValidator = createInputValidator(parentDisposable, emailField); var passwordValidator = createInputValidator(parentDisposable, passwordField); @@ -74,13 +79,29 @@ public class YouServiceSelectionForm extends JPanel { new UserAuthenticationHandler()); } }); + add(createForm()); + } - if (YouUserManager.getInstance().getAuthenticationResponse() == null) { - add(createUserAuthenticationPanel(emailField, passwordField, null)); + private JPanel createForm() { + var formBuilder = FormBuilder.createFormBuilder(); + var authResponse = YouUserManager.getInstance().getAuthenticationResponse(); + if (authResponse == null) { + formBuilder.addComponent(createUserAuthenticationPanel(emailField, passwordField, null)); } else { - add(createUserInformationPanel( - YouUserManager.getInstance().getAuthenticationResponse().getData().getUser())); + formBuilder.addComponent(createUserInformationPanel(authResponse.getData().getUser())); } + return formBuilder + .addComponent(new TitledSeparator( + CodeGPTBundle.get("settingsConfigurable.service.you.chatPreferences.title"))) + .addComponent(withEmptyLeftBorder(displayWebSearchResultsCheckBox)) + .addComponentFillVertically(new JPanel(), 0) + .getPanel(); + } + + public void resetForm() { + var state = YouSettings.getCurrentState(); + setDisplayWebSearchResults(state.isDisplayWebSearchResults()); + setEmail(state.getEmail()); } public String getEmail() { @@ -91,8 +112,20 @@ public class YouServiceSelectionForm extends JPanel { emailField.setText(email); } - public String getPassword() { - return new String(passwordField.getPassword()); + public @Nullable String getPassword() { + var password = new String(passwordField.getPassword()); + if (password.isEmpty()) { + return null; + } + return password; + } + + public void setDisplayWebSearchResults(boolean displayWebSearchResults) { + displayWebSearchResultsCheckBox.setSelected(displayWebSearchResults); + } + + public boolean isDisplayWebSearchResults() { + return displayWebSearchResultsCheckBox.isSelected(); } private ComponentValidator createInputValidator( @@ -177,6 +210,7 @@ public class YouServiceSelectionForm extends JPanel { .addComponent(new TitledSeparator( CodeGPTBundle.get("settingsConfigurable.service.you.authentication.title"))) .addComponent(contentPanel) + .addComponentFillVertically(new JPanel(), 0) .getPanel(); } @@ -202,9 +236,17 @@ public class YouServiceSelectionForm extends JPanel { .addComponent(signOutButton) .getPanel()) .withBorder(JBUI.Borders.emptyLeft(16))) + .addComponentFillVertically(new JPanel(), 0) .getPanel(); } + public YouSettingsState getCurrentState() { + var state = new YouSettingsState(); + state.setEmail(getEmail()); + state.setDisplayWebSearchResults(isDisplayWebSearchResults()); + return state; + } + class UserAuthenticationHandler implements AuthenticationHandler { @Override @@ -212,26 +254,27 @@ public class YouServiceSelectionForm extends JPanel { SwingUtilities.invokeLater(() -> { var email = emailField.getText(); var password = passwordField.getPassword(); - SettingsState.getInstance().setEmail(email); - YouCredentialsManager.getInstance().setAccountPassword(new String(password)); + YouSettings.getCurrentState().setEmail(email); + YouCredentialManager.getInstance().setCredential(new String(password)); refreshView(createUserInformationPanel(authenticationResponse.getData().getUser())); }); } @Override public void handleGenericError() { - SwingUtilities.invokeLater(() -> refreshView(createUserAuthenticationPanel( - emailField, - passwordField, - new YouAuthenticationError("unknown", "Something went wrong.")))); + SwingUtilities.invokeLater(() -> refresh(null)); } @Override public void handleError(YouAuthenticationError error) { - SwingUtilities.invokeLater(() -> refreshView(createUserAuthenticationPanel( - emailField, - passwordField, - error))); + SwingUtilities.invokeLater(() -> refresh(error)); + } + + private void refresh(@Nullable YouAuthenticationError error) { + if (error == null) { + error = new YouAuthenticationError("unknown", "Something went wrong."); + } + refreshView(createUserAuthenticationPanel(emailField, passwordField, error)); } } diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java new file mode 100644 index 00000000..3aba0682 --- /dev/null +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/you/YouSettingsState.java @@ -0,0 +1,53 @@ +package ee.carlrobert.codegpt.settings.service.you; + +import java.util.Objects; + +public class YouSettingsState { + + private String email = ""; + private boolean displayWebSearchResults = true; + private boolean useGPT4Model; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isDisplayWebSearchResults() { + return displayWebSearchResults; + } + + public void setDisplayWebSearchResults(boolean displayWebSearchResults) { + this.displayWebSearchResults = displayWebSearchResults; + } + + public boolean isUseGPT4Model() { + return useGPT4Model; + } + + public void setUseGPT4Model(boolean useGPT4Model) { + this.useGPT4Model = useGPT4Model; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + YouSettingsState that = (YouSettingsState) o; + return displayWebSearchResults == that.displayWebSearchResults + && useGPT4Model == that.useGPT4Model + && Objects.equals(email, that.email); + } + + @Override + public int hashCode() { + return Objects.hash(displayWebSearchResults, useGPT4Model, email); + } +} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/AzureSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/state/AzureSettingsState.java deleted file mode 100644 index ad5ba9dc..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/AzureSettingsState.java +++ /dev/null @@ -1,143 +0,0 @@ -package ee.carlrobert.codegpt.settings.state; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import ee.carlrobert.codegpt.credentials.AzureCredentialsManager; -import ee.carlrobert.codegpt.settings.service.ServiceSelectionForm; -import org.jetbrains.annotations.NotNull; - -@State(name = "CodeGPT_AzureSettings_210", storages = @Storage("CodeGPT_AzureSettings_210.xml")) -public class AzureSettingsState implements PersistentStateComponent { - - private static final String BASE_PATH = "/openai/deployments/%s/chat/completions?api-version=%s"; - - private String resourceName = ""; - private String deploymentId = ""; - private String apiVersion = ""; - private String baseHost = "https://%s.openai.azure.com"; - private String path = BASE_PATH; - private boolean useAzureApiKeyAuthentication = true; - private boolean useAzureActiveDirectoryAuthentication; - - public static AzureSettingsState getInstance() { - return ApplicationManager.getApplication().getService(AzureSettingsState.class); - } - - @Override - public AzureSettingsState getState() { - return this; - } - - @Override - public void loadState(@NotNull AzureSettingsState state) { - XmlSerializerUtil.copyBean(state, this); - } - - public boolean isModified(ServiceSelectionForm serviceSelectionForm) { - var credentialsManager = AzureCredentialsManager.getInstance(); - return serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected() - != isUseAzureActiveDirectoryAuthentication() - || serviceSelectionForm.isAzureApiKeyAuthenticationSelected() - != isUseAzureApiKeyAuthentication() - || !serviceSelectionForm.getAzureActiveDirectoryToken() - .equals(credentialsManager.getAzureActiveDirectoryToken()) - || !serviceSelectionForm.getAzureOpenAIApiKey() - .equals(credentialsManager.getAzureOpenAIApiKey()) - || !serviceSelectionForm.getAzureResourceName().equals(resourceName) - || !serviceSelectionForm.getAzureDeploymentId().equals(deploymentId) - || !serviceSelectionForm.getAzureApiVersion().equals(apiVersion) - || !serviceSelectionForm.getAzureBaseHost().equals(baseHost) - || !serviceSelectionForm.getAzurePath().equals(path); - } - - public void apply(ServiceSelectionForm serviceSelectionForm) { - useAzureActiveDirectoryAuthentication = - serviceSelectionForm.isAzureActiveDirectoryAuthenticationSelected(); - useAzureApiKeyAuthentication = serviceSelectionForm.isAzureApiKeyAuthenticationSelected(); - - resourceName = serviceSelectionForm.getAzureResourceName(); - deploymentId = serviceSelectionForm.getAzureDeploymentId(); - apiVersion = serviceSelectionForm.getAzureApiVersion(); - baseHost = serviceSelectionForm.getAzureBaseHost(); - path = serviceSelectionForm.getAzurePath(); - } - - public void reset(ServiceSelectionForm serviceSelectionForm) { - serviceSelectionForm.setAzureApiKey( - AzureCredentialsManager.getInstance().getAzureOpenAIApiKey()); - serviceSelectionForm.setAzureActiveDirectoryToken( - AzureCredentialsManager.getInstance().getAzureActiveDirectoryToken()); - serviceSelectionForm.setAzureApiKeyAuthenticationSelected(useAzureApiKeyAuthentication); - serviceSelectionForm.setAzureActiveDirectoryAuthenticationSelected( - useAzureActiveDirectoryAuthentication); - serviceSelectionForm.setAzureResourceName(resourceName); - serviceSelectionForm.setAzureDeploymentId(deploymentId); - serviceSelectionForm.setAzureApiVersion(apiVersion); - serviceSelectionForm.setAzureBaseHost(baseHost); - serviceSelectionForm.setAzurePath(path); - } - - public boolean isUsingCustomPath() { - return !BASE_PATH.equals(path); - } - - public String getResourceName() { - return resourceName; - } - - public void setResourceName(String resourceName) { - this.resourceName = resourceName; - } - - public String getDeploymentId() { - return deploymentId; - } - - public void setDeploymentId(String deploymentId) { - this.deploymentId = deploymentId; - } - - public String getApiVersion() { - return apiVersion; - } - - public void setApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - } - - public String getBaseHost() { - return baseHost; - } - - public void setBaseHost(String baseHost) { - this.baseHost = baseHost; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isUseAzureApiKeyAuthentication() { - return useAzureApiKeyAuthentication; - } - - public void setUseAzureApiKeyAuthentication(boolean useAzureApiKeyAuthentication) { - this.useAzureApiKeyAuthentication = useAzureApiKeyAuthentication; - } - - public boolean isUseAzureActiveDirectoryAuthentication() { - return useAzureActiveDirectoryAuthentication; - } - - public void setUseAzureActiveDirectoryAuthentication( - boolean useAzureActiveDirectoryAuthentication) { - this.useAzureActiveDirectoryAuthentication = useAzureActiveDirectoryAuthentication; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/IncludedFilesSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/state/IncludedFilesSettingsState.java deleted file mode 100644 index 3c5f6f2c..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/IncludedFilesSettingsState.java +++ /dev/null @@ -1,57 +0,0 @@ -package ee.carlrobert.codegpt.settings.state; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; - -@State( - name = "CodeGPT_IncludedFilesSettings", - storages = @Storage("CodeGPT_IncludedFilesSettings.xml")) -public class IncludedFilesSettingsState implements - PersistentStateComponent { - - public static final String DEFAULT_PROMPT_TEMPLATE = - "Use the following context to answer question at the end:\n\n" - + "{REPEATABLE_CONTEXT}\n\n" - + "Question: {QUESTION}"; - public static final String DEFAULT_REPEATABLE_CONTEXT = - "File Path: {FILE_PATH}\n" - + "File Content:\n" - + "{FILE_CONTENT}"; - - private String promptTemplate = DEFAULT_PROMPT_TEMPLATE; - private String repeatableContext = DEFAULT_REPEATABLE_CONTEXT; - - public static IncludedFilesSettingsState getInstance() { - return ApplicationManager.getApplication().getService(IncludedFilesSettingsState.class); - } - - @Override - public IncludedFilesSettingsState getState() { - return this; - } - - @Override - public void loadState(@NotNull IncludedFilesSettingsState state) { - XmlSerializerUtil.copyBean(state, this); - } - - public String getPromptTemplate() { - return promptTemplate; - } - - public void setPromptTemplate(String promptTemplate) { - this.promptTemplate = promptTemplate; - } - - public String getRepeatableContext() { - return repeatableContext; - } - - public void setRepeatableContext(String repeatableContext) { - this.repeatableContext = repeatableContext; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/LlamaSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/state/LlamaSettingsState.java deleted file mode 100644 index 384f5e39..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/LlamaSettingsState.java +++ /dev/null @@ -1,277 +0,0 @@ -package ee.carlrobert.codegpt.settings.state; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate; -import ee.carlrobert.codegpt.completions.HuggingFaceModel; -import ee.carlrobert.codegpt.completions.llama.PromptTemplate; -import ee.carlrobert.codegpt.credentials.LlamaCredentialsManager; -import ee.carlrobert.codegpt.settings.service.ServiceSelectionForm; -import java.io.IOException; -import java.net.ServerSocket; -import org.jetbrains.annotations.NotNull; - -@State(name = "CodeGPT_LlamaSettings", storages = @Storage("CodeGPT_CodeGPT_LlamaSettings.xml")) -public class LlamaSettingsState implements PersistentStateComponent { - - private boolean runLocalServer = true; - private boolean useCustomModel; - private String customLlamaModelPath = ""; - private HuggingFaceModel huggingFaceModel = HuggingFaceModel.CODE_LLAMA_7B_Q4; - private PromptTemplate localModelPromptTemplate = PromptTemplate.LLAMA; - private PromptTemplate remoteModelPromptTemplate = PromptTemplate.LLAMA; - private InfillPromptTemplate localModelInfillPromptTemplate = InfillPromptTemplate.LLAMA; - private InfillPromptTemplate remoteModelInfillPromptTemplate = InfillPromptTemplate.LLAMA; - private String baseHost = "http://localhost:8080"; - private Integer serverPort = getRandomAvailablePortOrDefault(); - private int contextSize = 2048; - private int threads = 8; - private String additionalParameters = ""; - private int topK = 40; - private double topP = 0.9; - private double minP = 0.05; - private double repeatPenalty = 1.1; - - public LlamaSettingsState() { - } - - public static LlamaSettingsState getInstance() { - return ApplicationManager.getApplication().getService(LlamaSettingsState.class); - } - - @Override - public LlamaSettingsState getState() { - return this; - } - - @Override - public void loadState(@NotNull LlamaSettingsState state) { - XmlSerializerUtil.copyBean(state, this); - } - - public boolean isModified(ServiceSelectionForm serviceSelectionForm) { - var modelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm(); - var requestPreferencesForm = serviceSelectionForm.getLlamaRequestPreferencesForm(); - var serverPreferencesForm = serviceSelectionForm.getLlamaServerPreferencesForm(); - - return !serviceSelectionForm.getLlamaServerPreferencesForm().getApiKey() - .equals(LlamaCredentialsManager.getInstance().getApiKey()) - || runLocalServer != serviceSelectionForm.isLlamaRunLocalServer() - || !localModelPromptTemplate.equals(modelPreferencesForm.getPromptTemplate()) - || !remoteModelPromptTemplate.equals(serviceSelectionForm.getLlamaPromptTemplate()) - || localModelInfillPromptTemplate != modelPreferencesForm.getInfillPromptTemplate() - || remoteModelInfillPromptTemplate != serverPreferencesForm.getInfillPromptTemplate() - || !baseHost.equals(serviceSelectionForm.getLlamaBaseHost()) - || serverPort != serviceSelectionForm.getLlamaServerPort() - || contextSize != serviceSelectionForm.getContextSize() - || threads != serviceSelectionForm.getThreads() - || !additionalParameters.equals(serviceSelectionForm.getAdditionalParameters()) - || huggingFaceModel != modelPreferencesForm.getSelectedModel() - || topK != requestPreferencesForm.getTopK() - || topP != requestPreferencesForm.getTopP() - || minP != requestPreferencesForm.getMinP() - || repeatPenalty != requestPreferencesForm.getRepeatPenalty() - || useCustomModel != modelPreferencesForm.isUseCustomLlamaModel() - || !customLlamaModelPath.equals(modelPreferencesForm.getCustomLlamaModelPath()); - } - - public void apply(ServiceSelectionForm serviceSelectionForm) { - var modelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm(); - customLlamaModelPath = modelPreferencesForm.getCustomLlamaModelPath(); - customLlamaModelPath = modelPreferencesForm.getCustomLlamaModelPath(); - huggingFaceModel = modelPreferencesForm.getSelectedModel(); - useCustomModel = modelPreferencesForm.isUseCustomLlamaModel(); - localModelPromptTemplate = modelPreferencesForm.getPromptTemplate(); - remoteModelPromptTemplate = serviceSelectionForm.getLlamaPromptTemplate(); - localModelInfillPromptTemplate = modelPreferencesForm.getInfillPromptTemplate(); - remoteModelInfillPromptTemplate = - serviceSelectionForm.getLlamaServerPreferencesForm().getInfillPromptTemplate(); - var requestPreferencesForm = serviceSelectionForm.getLlamaRequestPreferencesForm(); - topK = requestPreferencesForm.getTopK(); - topP = requestPreferencesForm.getTopP(); - minP = requestPreferencesForm.getMinP(); - repeatPenalty = requestPreferencesForm.getRepeatPenalty(); - runLocalServer = serviceSelectionForm.isLlamaRunLocalServer(); - baseHost = serviceSelectionForm.getLlamaBaseHost(); - serverPort = serviceSelectionForm.getLlamaServerPort(); - contextSize = serviceSelectionForm.getContextSize(); - threads = serviceSelectionForm.getThreads(); - additionalParameters = serviceSelectionForm.getAdditionalParameters(); - } - - public void reset(ServiceSelectionForm serviceSelectionForm) { - var modelPreferencesForm = serviceSelectionForm.getLlamaModelPreferencesForm(); - modelPreferencesForm.setSelectedModel(huggingFaceModel); - modelPreferencesForm.setCustomLlamaModelPath(customLlamaModelPath); - modelPreferencesForm.setUseCustomLlamaModel(useCustomModel); - modelPreferencesForm.setPromptTemplate(localModelPromptTemplate); - modelPreferencesForm.setInfillPromptTemplate(localModelInfillPromptTemplate); - var requestPreferencesForm = serviceSelectionForm.getLlamaRequestPreferencesForm(); - requestPreferencesForm.setTopK(topK); - requestPreferencesForm.setTopP(topP); - requestPreferencesForm.setMinP(minP); - requestPreferencesForm.setRepeatPenalty(repeatPenalty); - serviceSelectionForm.setLlamaRunLocalServer(runLocalServer); - serviceSelectionForm.setLlamaBaseHost(baseHost); - serviceSelectionForm.setLlamaServerPort(serverPort); - serviceSelectionForm.setLlamaPromptTemplate(remoteModelPromptTemplate); - serviceSelectionForm.setContextSize(contextSize); - serviceSelectionForm.setThreads(threads); - serviceSelectionForm.setAdditionalParameters(additionalParameters); - - var llamaServerPreferencesForm = serviceSelectionForm.getLlamaServerPreferencesForm(); - llamaServerPreferencesForm.setInfillPromptTemplate(remoteModelInfillPromptTemplate); - llamaServerPreferencesForm.setApiKey(LlamaCredentialsManager.getInstance().getApiKey()); - } - - public boolean isUseCustomModel() { - return useCustomModel; - } - - public void setUseCustomModel(boolean useCustomModel) { - this.useCustomModel = useCustomModel; - } - - public String getCustomLlamaModelPath() { - return customLlamaModelPath; - } - - public void setCustomLlamaModelPath(String customLlamaModelPath) { - this.customLlamaModelPath = customLlamaModelPath; - } - - public HuggingFaceModel getHuggingFaceModel() { - return huggingFaceModel; - } - - public void setHuggingFaceModel(HuggingFaceModel huggingFaceModel) { - this.huggingFaceModel = huggingFaceModel; - } - - public PromptTemplate getLocalModelPromptTemplate() { - return localModelPromptTemplate; - } - - public void setLocalModelPromptTemplate( - PromptTemplate localModelPromptTemplate) { - this.localModelPromptTemplate = localModelPromptTemplate; - } - - public InfillPromptTemplate getLocalModelInfillPromptTemplate() { - return localModelInfillPromptTemplate; - } - - public void setLocalModelInfillPromptTemplate( - InfillPromptTemplate localModelInfillPromptTemplate) { - this.localModelInfillPromptTemplate = localModelInfillPromptTemplate; - } - - public InfillPromptTemplate getRemoteModelInfillPromptTemplate() { - return remoteModelInfillPromptTemplate; - } - - public void setRemoteModelInfillPromptTemplate( - InfillPromptTemplate remoteModelInfillPromptTemplate) { - this.remoteModelInfillPromptTemplate = remoteModelInfillPromptTemplate; - } - - public boolean isRunLocalServer() { - return runLocalServer; - } - - public void setRunLocalServer(boolean runLocalServer) { - this.runLocalServer = runLocalServer; - } - - public String getBaseHost() { - return baseHost; - } - - public void setBaseHost(String baseHost) { - this.baseHost = baseHost; - } - - public PromptTemplate getRemoteModelPromptTemplate() { - return remoteModelPromptTemplate; - } - - public void setRemoteModelPromptTemplate( - PromptTemplate remoteModelPromptTemplate) { - this.remoteModelPromptTemplate = remoteModelPromptTemplate; - } - - public Integer getServerPort() { - return serverPort; - } - - public void setServerPort(Integer serverPort) { - this.serverPort = serverPort; - } - - public int getContextSize() { - return contextSize; - } - - public void setContextSize(int contextSize) { - this.contextSize = contextSize; - } - - public int getThreads() { - return threads; - } - - public void setThreads(int threads) { - this.threads = threads; - } - - public String getAdditionalParameters() { - return additionalParameters; - } - - public void setAdditionalParameters(String additionalParameters) { - this.additionalParameters = additionalParameters; - } - - public int getTopK() { - return topK; - } - - public void setTopK(int topK) { - this.topK = topK; - } - - public double getTopP() { - return topP; - } - - public void setTopP(double topP) { - this.topP = topP; - } - - public double getMinP() { - return minP; - } - - public void setMinP(double minP) { - this.minP = minP; - } - - public double getRepeatPenalty() { - return repeatPenalty; - } - - public void setRepeatPenalty(double repeatPenalty) { - this.repeatPenalty = repeatPenalty; - } - - private static Integer getRandomAvailablePortOrDefault() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } catch (IOException e) { - return 8080; - } - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/OpenAISettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/state/OpenAISettingsState.java deleted file mode 100644 index d21cd3e2..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/OpenAISettingsState.java +++ /dev/null @@ -1,105 +0,0 @@ -package ee.carlrobert.codegpt.settings.state; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import ee.carlrobert.codegpt.credentials.OpenAICredentialsManager; -import ee.carlrobert.codegpt.settings.service.ServiceSelectionForm; -import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; -import org.jetbrains.annotations.NotNull; - -@State(name = "CodeGPT_OpenAISettings_210", storages = @Storage("CodeGPT_OpenAISettings_210.xml")) -public class OpenAISettingsState implements PersistentStateComponent { - - private static final String BASE_PATH = "/v1/chat/completions"; - - private String organization = ""; - private String baseHost = "https://api.openai.com"; - private String path = BASE_PATH; - private String model = OpenAIChatCompletionModel.GPT_3_5.getCode(); - private boolean openAIQuotaExceeded; - - public static OpenAISettingsState getInstance() { - return ApplicationManager.getApplication().getService(OpenAISettingsState.class); - } - - @Override - public OpenAISettingsState getState() { - return this; - } - - @Override - public void loadState(@NotNull OpenAISettingsState state) { - XmlSerializerUtil.copyBean(state, this); - } - - public boolean isModified(ServiceSelectionForm serviceSelectionForm) { - return !serviceSelectionForm.getOpenAIApiKey() - .equals(OpenAICredentialsManager.getInstance().getApiKey()) - || !serviceSelectionForm.getOpenAIOrganization().equals(organization) - || !serviceSelectionForm.getOpenAIBaseHost().equals(baseHost) - || !serviceSelectionForm.getOpenAIPath().equals(path) - || !serviceSelectionForm.getOpenAIModel().equals(model); - } - - public void apply(ServiceSelectionForm serviceSelectionForm) { - organization = serviceSelectionForm.getOpenAIOrganization(); - baseHost = serviceSelectionForm.getOpenAIBaseHost(); - path = serviceSelectionForm.getOpenAIPath(); - model = serviceSelectionForm.getOpenAIModel(); - } - - public void reset(ServiceSelectionForm serviceSelectionForm) { - serviceSelectionForm.setOpenAIApiKey(OpenAICredentialsManager.getInstance().getApiKey()); - serviceSelectionForm.setOpenAIOrganization(organization); - serviceSelectionForm.setOpenAIBaseHost(baseHost); - serviceSelectionForm.setOpenAIPath(path); - serviceSelectionForm.setOpenAIModel(model); - } - - public boolean isUsingCustomPath() { - return !BASE_PATH.equals(path); - } - - public String getOrganization() { - return organization; - } - - public void setOrganization(String organization) { - this.organization = organization; - } - - public String getBaseHost() { - return baseHost; - } - - public void setBaseHost(String openAIBaseHost) { - this.baseHost = openAIBaseHost; - } - - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isOpenAIQuotaExceeded() { - return openAIQuotaExceeded; - } - - public void setOpenAIQuotaExceeded(boolean openAIQuotaExceeded) { - this.openAIQuotaExceeded = openAIQuotaExceeded; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/settings/state/YouSettingsState.java b/src/main/java/ee/carlrobert/codegpt/settings/state/YouSettingsState.java deleted file mode 100644 index d91201b4..00000000 --- a/src/main/java/ee/carlrobert/codegpt/settings/state/YouSettingsState.java +++ /dev/null @@ -1,45 +0,0 @@ -package ee.carlrobert.codegpt.settings.state; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; - -@State(name = "CodeGPT_YouSettings", storages = @Storage("CodeGPT_YouSettings.xml")) -public class YouSettingsState implements PersistentStateComponent { - - private boolean displayWebSearchResults = true; - private boolean useGPT4Model; - - public static YouSettingsState getInstance() { - return ApplicationManager.getApplication().getService(YouSettingsState.class); - } - - @Override - public YouSettingsState getState() { - return this; - } - - @Override - public void loadState(@NotNull YouSettingsState state) { - XmlSerializerUtil.copyBean(state, this); - } - - public boolean isDisplayWebSearchResults() { - return displayWebSearchResults; - } - - public void setDisplayWebSearchResults(boolean displayWebSearchResults) { - this.displayWebSearchResults = displayWebSearchResults; - } - - public boolean isUseGPT4Model() { - return useGPT4Model; - } - - public void setUseGPT4Model(boolean useGPT4Model) { - this.useGPT4Model = useGPT4Model; - } -} diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java index f5ee5ba2..58afb1f2 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowTabPanel.java @@ -22,8 +22,8 @@ import ee.carlrobert.codegpt.completions.ConversationType; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.message.Message; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; -import ee.carlrobert.codegpt.settings.state.SettingsState; import ee.carlrobert.codegpt.telemetry.TelemetryAction; import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowPanel; @@ -280,7 +280,7 @@ public abstract class ChatToolWindowTabPanel implements Disposable { gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridy = 1; rootPanel.add( - createUserPromptPanel(SettingsState.getInstance().getSelectedService()), gbc); + createUserPromptPanel(GeneralSettings.getCurrentState().getSelectedService()), gbc); return rootPanel; } } \ No newline at end of file diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java index 794f23d5..346854ab 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ToolWindowCompletionResponseEventListener.java @@ -10,10 +10,7 @@ import ee.carlrobert.codegpt.completions.CompletionResponseEventListener; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.message.Message; -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.settings.state.YouSettingsState; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.telemetry.TelemetryAction; import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatMessageResponseBody; import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; @@ -85,9 +82,6 @@ abstract class ToolWindowCompletionResponseEventListener implements SwingUtilities.invokeLater(() -> { try { if ("insufficient_quota".equals(error.getCode())) { - if (SettingsState.getInstance().getSelectedService() == ServiceType.OPENAI) { - OpenAISettingsState.getInstance().setOpenAIQuotaExceeded(true); - } responseContainer.displayQuotaExceeded(); } else { responseContainer.displayError(error.getMessage()); @@ -128,7 +122,7 @@ abstract class ToolWindowCompletionResponseEventListener implements if (containsResults) { message.setSerpResults(serpResults); } - var displayResults = YouSettingsState.getInstance().isDisplayWebSearchResults(); + var displayResults = YouSettings.getCurrentState().isDisplayWebSearchResults(); SwingUtilities.invokeLater(() -> { try { diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/contextual/ContextualChatToolWindowLandingPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/contextual/ContextualChatToolWindowLandingPanel.java index 5cf2cd39..2398c90e 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/contextual/ContextualChatToolWindowLandingPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/contextual/ContextualChatToolWindowLandingPanel.java @@ -10,7 +10,7 @@ import ee.carlrobert.codegpt.CodeGPTPlugin; import ee.carlrobert.codegpt.indexes.CodebaseIndexingCompletedNotifier; import ee.carlrobert.codegpt.indexes.CodebaseIndexingTask; import ee.carlrobert.codegpt.indexes.FolderStructureTreePanel; -import ee.carlrobert.codegpt.settings.SettingsConfigurable; +import ee.carlrobert.codegpt.settings.GeneralSettingsConfigurable; import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; import ee.carlrobert.codegpt.ui.OverlayUtil; import ee.carlrobert.codegpt.ui.UIUtil; @@ -80,7 +80,8 @@ class ContextualChatToolWindowLandingPanel extends ResponsePanel { if (event.getURL() == null) { switch (event.getDescription()) { case "LOGIN": - ShowSettingsUtil.getInstance().showSettingsDialog(project, SettingsConfigurable.class); + ShowSettingsUtil.getInstance() + .showSettingsDialog(project, GeneralSettingsConfigurable.class); break; case "LIST_DEPENDENCIES": actionEvent.handleAction("List all the dependencies that the project uses"); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/ModelComboBoxAction.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/ModelComboBoxAction.java index 9284ac5a..eae944a8 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/ModelComboBoxAction.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/ModelComboBoxAction.java @@ -12,10 +12,12 @@ import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.completions.llama.LlamaModel; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.ConversationsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; +import ee.carlrobert.codegpt.settings.GeneralSettingsState; import ee.carlrobert.codegpt.settings.service.ServiceType; -import ee.carlrobert.codegpt.settings.state.LlamaSettingsState; -import ee.carlrobert.codegpt.settings.state.OpenAISettingsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; +import ee.carlrobert.codegpt.settings.service.openai.OpenAISettingsState; import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; import java.util.List; import javax.swing.Icon; @@ -25,13 +27,13 @@ import org.jetbrains.annotations.NotNull; public class ModelComboBoxAction extends ComboBoxAction { private final Runnable onAddNewTab; - private final SettingsState settings; + private final GeneralSettingsState settings; private final OpenAISettingsState openAISettings; public ModelComboBoxAction(Runnable onAddNewTab, ServiceType selectedService) { this.onAddNewTab = onAddNewTab; - settings = SettingsState.getInstance(); - openAISettings = OpenAISettingsState.getInstance(); + settings = GeneralSettings.getCurrentState(); + openAISettings = OpenAISettings.getCurrentState(); updateTemplatePresentation(selectedService); } @@ -113,7 +115,7 @@ public class ModelComboBoxAction extends ComboBoxAction { } private String getSelectedHuggingFace() { - var huggingFaceModel = LlamaSettingsState.getInstance().getHuggingFaceModel(); + var huggingFaceModel = LlamaSettings.getCurrentState().getHuggingFaceModel(); return format( "%s %dB (Q%d)", LlamaModel.findByHuggingFaceModel(huggingFaceModel).getLabel(), diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java index 79913f7b..eab81f22 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowLandingPanel.java @@ -5,7 +5,7 @@ import static java.lang.String.format; import com.intellij.ui.components.ActionLink; import com.intellij.util.ui.JBUI; import ee.carlrobert.codegpt.Icons; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; import ee.carlrobert.codegpt.ui.UIUtil; import java.awt.BorderLayout; @@ -35,7 +35,7 @@ class StandardChatToolWindowLandingPanel extends ResponsePanel { "

" + "Welcome %s, I'm your intelligent code companion, here to be" + " your partner-in-crime for getting things done in a flash." - + "

", SettingsState.getInstance().getDisplayName()) + + "

", GeneralSettings.getCurrentState().getDisplayName()) + "

" + "Feel free to ask me anything you'd like, but my true superpower lies in assisting " + "you with your code! Here are a few examples of how I can assist you:" diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java index ba55b47c..ef340acf 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabPanel.java @@ -7,7 +7,7 @@ import com.intellij.openapi.project.Project; import ee.carlrobert.codegpt.completions.ConversationType; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.settings.state.YouSettingsState; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowTabPanel; import ee.carlrobert.codegpt.toolwindow.chat.ui.ChatMessageResponseBody; import ee.carlrobert.codegpt.toolwindow.chat.ui.ResponsePanel; @@ -61,7 +61,7 @@ public class StandardChatToolWindowTabPanel extends ChatToolWindowTabPanel { new ChatMessageResponseBody(project, this).withResponse(message.getResponse()); var serpResults = message.getSerpResults(); - if (YouSettingsState.getInstance().isDisplayWebSearchResults() + if (YouSettings.getCurrentState().isDisplayWebSearchResults() && serpResults != null && !serpResults.isEmpty()) { messageResponseBody.displaySerpResults(serpResults); } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java index 775d1612..d623b032 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/standard/StandardChatToolWindowTabbedPane.java @@ -10,7 +10,7 @@ import com.intellij.ui.components.JBTabbedPane; import com.intellij.util.ui.JBUI; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.ConversationsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -106,7 +106,7 @@ public class StandardChatToolWindowTabbedPane extends JBTabbedPane { var conversation = toolWindowPanel.getConversation(); if (conversation != null) { ConversationsState.getInstance().setCurrentConversation(conversation); - SettingsState.getInstance().sync(conversation); + GeneralSettings.getInstance().sync(conversation); } } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java index 99b3a76d..afb39e1a 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/ChatMessageResponseBody.java @@ -16,7 +16,7 @@ import com.intellij.util.ui.JBUI; import com.vladsch.flexmark.ast.FencedCodeBlock; import com.vladsch.flexmark.parser.Parser; import ee.carlrobert.codegpt.actions.ActionType; -import ee.carlrobert.codegpt.settings.SettingsConfigurable; +import ee.carlrobert.codegpt.settings.GeneralSettingsConfigurable; import ee.carlrobert.codegpt.telemetry.TelemetryAction; import ee.carlrobert.codegpt.toolwindow.chat.StreamParser; import ee.carlrobert.codegpt.toolwindow.chat.editor.ResponseEditorPanel; @@ -93,7 +93,8 @@ public class ChatMessageResponseBody extends JPanel { format("

%s

", message)); currentlyProcessedTextPane.addHyperlinkListener(e -> { if (e.getEventType() == ACTIVATED) { - ShowSettingsUtil.getInstance().showSettingsDialog(project, SettingsConfigurable.class); + ShowSettingsUtil.getInstance() + .showSettingsDialog(project, GeneralSettingsConfigurable.class); } }); currentlyProcessedTextPane.getCaret().setVisible(false); @@ -108,7 +109,8 @@ public class ChatMessageResponseBody extends JPanel { currentlyProcessedTextPane.addHyperlinkListener(e -> { if (e.getEventType() == ACTIVATED) { - ShowSettingsUtil.getInstance().showSettingsDialog(project, SettingsConfigurable.class); + ShowSettingsUtil.getInstance() + .showSettingsDialog(project, GeneralSettingsConfigurable.class); TelemetryAction.IDE_ACTION.createActionMessage() .property("action", ActionType.CHANGE_PROVIDER.name()) .send(); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/UserMessagePanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/UserMessagePanel.java index 84a2a08f..5e723ed4 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/UserMessagePanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/UserMessagePanel.java @@ -9,7 +9,7 @@ import com.intellij.util.ui.JBFont; import com.intellij.util.ui.JBUI; import ee.carlrobert.codegpt.Icons; import ee.carlrobert.codegpt.conversations.message.Message; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; import java.awt.BorderLayout; import javax.swing.JPanel; import javax.swing.SwingConstants; @@ -48,7 +48,7 @@ public class UserMessagePanel extends JPanel { private JBLabel createDisplayNameLabel() { return new JBLabel( - SettingsState.getInstance().getDisplayName(), + GeneralSettings.getCurrentState().getDisplayName(), Icons.User, SwingConstants.LEADING) .setAllowAutoWrapping(true) diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/YouProCheckbox.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/YouProCheckbox.java index 34105216..1205c6e5 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/YouProCheckbox.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/YouProCheckbox.java @@ -3,13 +3,13 @@ package ee.carlrobert.codegpt.toolwindow.chat.ui.textarea; import com.intellij.ui.components.JBCheckBox; import ee.carlrobert.codegpt.CodeGPTBundle; import ee.carlrobert.codegpt.completions.you.YouUserManager; -import ee.carlrobert.codegpt.settings.state.YouSettingsState; +import ee.carlrobert.codegpt.settings.service.you.YouSettings; public class YouProCheckbox extends JBCheckBox { public YouProCheckbox() { super(CodeGPTBundle.get("toolwindow.chat.youProCheckBox.text")); - var youSettings = YouSettingsState.getInstance(); + var youSettings = YouSettings.getCurrentState(); var youUserManager = YouUserManager.getInstance(); setOpaque(false); setEnabled(youUserManager.isSubscribed()); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java index 9d058066..4e82f767 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/conversations/ConversationPanel.java @@ -8,7 +8,7 @@ import com.intellij.util.ui.JBUI; import ee.carlrobert.codegpt.actions.toolwindow.DeleteConversationAction; import ee.carlrobert.codegpt.conversations.Conversation; import ee.carlrobert.codegpt.conversations.ConversationsState; -import ee.carlrobert.codegpt.settings.state.SettingsState; +import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.toolwindow.chat.standard.StandardChatToolWindowContentManager; import ee.carlrobert.codegpt.ui.IconActionButton; import ee.carlrobert.codegpt.ui.ModelIconLabel; @@ -42,7 +42,7 @@ class ConversationPanel extends JPanel { addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - SettingsState.getInstance().sync(conversation); + GeneralSettings.getInstance().sync(conversation); toolWindowContentManager.displayConversation(conversation); } }); diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 8933e738..3b950884 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -15,7 +15,7 @@ + instance="ee.carlrobert.codegpt.settings.GeneralSettingsConfigurable"/> - - - - - - + + + + + + - +