diff --git a/codegpt-treesitter/src/main/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParser.java b/codegpt-treesitter/src/main/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParser.java index a3f0c50d..33248059 100644 --- a/codegpt-treesitter/src/main/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParser.java +++ b/codegpt-treesitter/src/main/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParser.java @@ -1,7 +1,6 @@ package ee.carlrobert.codegpt.treesitter; import org.treesitter.TSLanguage; -import org.treesitter.TSNode; import org.treesitter.TSParser; import org.treesitter.TSTree; @@ -16,7 +15,7 @@ public class CodeCompletionParser { public String parse(String prefix, String suffix, String output) { var result = new StringBuilder(output); while (!result.isEmpty()) { - if (containsSyntaxErrors(prefix + result + suffix)) { + if (containsError(prefix + result + suffix)) { result.deleteCharAt(result.length() - 1); } else { return result.toString(); @@ -30,21 +29,11 @@ public class CodeCompletionParser { return output; } - private boolean containsSyntaxErrors(String input) { - return containsSyntaxErrors(getTree(input).getRootNode()); - } - - private boolean containsSyntaxErrors(TSNode node) { - if (node.isMissing() || node.hasError()) { - return true; - } - - for (int i = 0; i < node.getChildCount(); i++) { - if (containsSyntaxErrors(node.getChild(i))) { - return true; - } - } - return false; + private boolean containsError(String input) { + var treeString = getTree(input).getRootNode().toString(); + return treeString.contains("ERROR") + || treeString.contains("MISSING \"}\"") + || treeString.contains("MISSING \")\""); } private TSTree getTree(String input) { diff --git a/codegpt-treesitter/src/test/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParserTest.java b/codegpt-treesitter/src/test/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParserTest.java index d6dc2bba..4f5535c2 100644 --- a/codegpt-treesitter/src/test/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParserTest.java +++ b/codegpt-treesitter/src/test/java/ee/carlrobert/codegpt/treesitter/CodeCompletionParserTest.java @@ -9,17 +9,17 @@ public class CodeCompletionParserTest { @Test public void shouldGetValidReturnValue() { var prefix = """ - class Main { - public int getRandomNumber() { - return\s"""; + class Main { + public int getRandomNumber() { + return\s"""; var suffix = """ - } - }"""; + } + }"""; var output = """ - 10;} - } - public int getRandomNumber(int k) {"""; + 10;} + } + public int getRandomNumber(int k) {"""; var parsedResponse = CodeCompletionParserFactory .getParserForFileExtension("java") @@ -31,16 +31,16 @@ public class CodeCompletionParserTest { @Test public void shouldGetValidParenthesisValue() { var prefix = """ - class Main { - public int getRandomNumber(int\s"""; + class Main { + public int getRandomNumber(int\s"""; var suffix = """ - ) { - return 10; - } - }"""; + ) { + return 10; + } + }"""; var output = """ - prevNumber) { - if() {"""; + prevNumber) { + if() {"""; var parsedResponse = CodeCompletionParserFactory .getParserForFileExtension("java") @@ -49,41 +49,16 @@ public class CodeCompletionParserTest { assertThat(parsedResponse).isEqualTo("prevNumber"); } - @Test - public void shouldHandleFieldDeclaration() { - var prefix = """ - class Main { - \t - private i"""; - var suffix = """ - - - public int getRandomNumber(int prevNumber) { - return Math.of() - } - }"""; - var output = """ - nt randomNumber; - \s - public void get() {"""; - - var result = CodeCompletionParserFactory - .getParserForFileExtension("java") - .parse(prefix, suffix, output); - - assertThat(result).isEqualTo("nt randomNumber;"); - } - @Test public void shouldHandleFormalParameters() { var prefix = """ - class Main { - public int getRandomNumber("""; + class Main { + public int getRandomNumber("""; var suffix = """ - ) { - return 10; - } - }"""; + ) { + return 10; + } + }"""; var output = "int prevNumber) }"; var result = CodeCompletionParserFactory diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6669e3a0..f06f6c07 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ jsoup = "1.17.2" jtokkit = "1.0.0" junit = "5.10.2" kotlin = "1.9.24" -llm-client = "0.8.3" +llm-client = "0.8.4" okio = "3.9.0" tree-sitter = "0.22.5" diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java index 26c6be61..5e1f3bf1 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationComponent.java @@ -47,6 +47,7 @@ public class ConfigurationComponent { private final JBCheckBox openNewTabCheckBox; private final JBCheckBox methodNameGenerationCheckBox; private final JBCheckBox autoFormattingCheckBox; + private final JBCheckBox autocompletionPostProcessingCheckBox; private final JTextArea systemPromptTextArea; private final JTextArea commitMessagePromptTextArea; private final IntegerField maxTokensField; @@ -123,6 +124,10 @@ public class ConfigurationComponent { autoFormattingCheckBox = new JBCheckBox( CodeGPTBundle.get("configurationConfigurable.autoFormatting.label"), configuration.isAutoFormattingEnabled()); + autocompletionPostProcessingCheckBox = new JBCheckBox( + CodeGPTBundle.get("configurationConfigurable.autocompletionPostProcessing.label"), + configuration.isAutocompletionPostProcessingEnabled() + ); mainPanel = FormBuilder.createFormBuilder() .addComponent(tablePanel) @@ -132,6 +137,7 @@ public class ConfigurationComponent { .addComponent(openNewTabCheckBox) .addComponent(methodNameGenerationCheckBox) .addComponent(autoFormattingCheckBox) + .addComponent(autocompletionPostProcessingCheckBox) .addVerticalGap(4) .addComponent(new TitledSeparator( CodeGPTBundle.get("configurationConfigurable.section.assistant.title"))) @@ -159,6 +165,7 @@ public class ConfigurationComponent { state.setCreateNewChatOnEachAction(openNewTabCheckBox.isSelected()); state.setMethodNameGenerationEnabled(methodNameGenerationCheckBox.isSelected()); state.setAutoFormattingEnabled(autoFormattingCheckBox.isSelected()); + state.setAutocompletionPostProcessingEnabled(autocompletionPostProcessingCheckBox.isSelected()); return state; } @@ -174,6 +181,8 @@ public class ConfigurationComponent { openNewTabCheckBox.setSelected(configuration.isCreateNewChatOnEachAction()); methodNameGenerationCheckBox.setSelected(configuration.isMethodNameGenerationEnabled()); autoFormattingCheckBox.setSelected(configuration.isAutoFormattingEnabled()); + autocompletionPostProcessingCheckBox.setSelected( + configuration.isAutocompletionPostProcessingEnabled()); } private Map getTableData() { diff --git a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java index 4704acec..7c0bc046 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/configuration/ConfigurationState.java @@ -20,6 +20,7 @@ public class ConfigurationState { private boolean methodNameGenerationEnabled = true; private boolean captureCompileErrors = true; private boolean autoFormattingEnabled = true; + private boolean autocompletionPostProcessingEnabled = true; private Map tableData = EditorActionsUtil.DEFAULT_ACTIONS; public String getSystemPrompt() { @@ -118,6 +119,14 @@ public class ConfigurationState { this.autoFormattingEnabled = autoFormattingEnabled; } + public boolean isAutocompletionPostProcessingEnabled() { + return autocompletionPostProcessingEnabled; + } + + public void setAutocompletionPostProcessingEnabled(boolean autocompletionPostProcessingEnabled) { + this.autocompletionPostProcessingEnabled = autocompletionPostProcessingEnabled; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -135,6 +144,7 @@ public class ConfigurationState { && methodNameGenerationEnabled == that.methodNameGenerationEnabled && captureCompileErrors == that.captureCompileErrors && autoFormattingEnabled == that.autoFormattingEnabled + && autocompletionPostProcessingEnabled == that.autocompletionPostProcessingEnabled && Objects.equals(systemPrompt, that.systemPrompt) && Objects.equals(commitMessagePrompt, that.commitMessagePrompt) && Objects.equals(tableData, that.tableData); @@ -145,6 +155,6 @@ public class ConfigurationState { return Objects.hash(systemPrompt, commitMessagePrompt, maxTokens, temperature, checkForPluginUpdates, checkForNewScreenshots, createNewChatOnEachAction, ignoreGitCommitTokenLimit, methodNameGenerationEnabled, captureCompileErrors, - autoFormattingEnabled, tableData); + autoFormattingEnabled, autocompletionPostProcessingEnabled, tableData); } } 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 index bff9b890..8204c721 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/llama/LlamaSettingsState.java @@ -29,7 +29,6 @@ public class LlamaSettingsState { private double minP = 0.05; private double repeatPenalty = 1.1; private boolean codeCompletionsEnabled = true; - private int codeCompletionMaxTokens = 128; public boolean isUseCustomModel() { return useCustomModel; @@ -187,14 +186,6 @@ public class LlamaSettingsState { this.codeCompletionsEnabled = codeCompletionsEnabled; } - public int getCodeCompletionMaxTokens() { - return codeCompletionMaxTokens; - } - - public void setCodeCompletionMaxTokens(int codeCompletionMaxTokens) { - this.codeCompletionMaxTokens = codeCompletionMaxTokens; - } - private static Integer getRandomAvailablePortOrDefault() { try (ServerSocket socket = new ServerSocket(0)) { return socket.getLocalPort(); @@ -230,8 +221,7 @@ public class LlamaSettingsState { && Objects.equals(serverPort, that.serverPort) && Objects.equals(additionalParameters, that.additionalParameters) && Objects.equals(additionalBuildParameters, that.additionalBuildParameters) - && codeCompletionsEnabled == that.codeCompletionsEnabled - && codeCompletionMaxTokens == that.codeCompletionMaxTokens; + && codeCompletionsEnabled == that.codeCompletionsEnabled; } @Override @@ -240,6 +230,6 @@ public class LlamaSettingsState { localModelPromptTemplate, remoteModelPromptTemplate, localModelInfillPromptTemplate, remoteModelInfillPromptTemplate, baseHost, serverPort, contextSize, threads, additionalParameters, additionalBuildParameters, topK, topP, minP, repeatPenalty, - codeCompletionsEnabled, codeCompletionMaxTokens); + codeCompletionsEnabled); } } 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 index da415871..950d2650 100644 --- 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 @@ -22,7 +22,6 @@ public class LlamaSettingsForm extends JPanel { llamaRequestPreferencesForm = new LlamaRequestPreferencesForm(settings); codeCompletionConfigurationForm = new CodeCompletionConfigurationForm( settings.isCodeCompletionsEnabled(), - settings.getCodeCompletionMaxTokens(), null); init(); } @@ -50,9 +49,7 @@ public class LlamaSettingsForm extends JPanel { state.setUseCustomModel(modelPreferencesForm.isUseCustomLlamaModel()); state.setLocalModelPromptTemplate(modelPreferencesForm.getPromptTemplate()); state.setLocalModelInfillPromptTemplate(modelPreferencesForm.getInfillPromptTemplate()); - state.setCodeCompletionsEnabled(codeCompletionConfigurationForm.isCodeCompletionsEnabled()); - state.setCodeCompletionMaxTokens(codeCompletionConfigurationForm.getMaxTokens()); return state; } @@ -61,7 +58,6 @@ public class LlamaSettingsForm extends JPanel { llamaServerPreferencesForm.resetForm(state); llamaRequestPreferencesForm.resetForm(state); codeCompletionConfigurationForm.setCodeCompletionsEnabled(state.isCodeCompletionsEnabled()); - codeCompletionConfigurationForm.setMaxTokens(state.getCodeCompletionMaxTokens()); } public LlamaServerPreferencesForm getLlamaServerPreferencesForm() { 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 index ac65ef41..d76353e8 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsForm.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsForm.java @@ -1,20 +1,17 @@ package ee.carlrobert.codegpt.settings.service.openai; import static ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.OPENAI_API_KEY; -import static ee.carlrobert.codegpt.ui.UIUtil.withEmptyLeftBorder; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.ComboBox; import com.intellij.ui.EnumComboBoxModel; -import com.intellij.ui.TitledSeparator; +import com.intellij.ui.components.JBCheckBox; 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.CredentialsStore; import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey; -import ee.carlrobert.codegpt.settings.service.CodeCompletionConfigurationForm; import ee.carlrobert.codegpt.ui.UIUtil; import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; import javax.swing.JPanel; @@ -26,7 +23,7 @@ public class OpenAISettingsForm { private final JBPasswordField apiKeyField; private final JBTextField organizationField; private final ComboBox completionModelComboBox; - private final CodeCompletionConfigurationForm codeCompletionConfigurationForm; + private final JBCheckBox codeCompletionsEnabledCheckBox; public OpenAISettingsForm(OpenAISettingsState settings) { apiKeyField = new JBPasswordField(); @@ -40,34 +37,28 @@ public class OpenAISettingsForm { new EnumComboBoxModel<>(OpenAIChatCompletionModel.class)); completionModelComboBox.setSelectedItem( OpenAIChatCompletionModel.findByCode(settings.getModel())); - codeCompletionConfigurationForm = new CodeCompletionConfigurationForm( - settings.isCodeCompletionsEnabled(), - settings.getCodeCompletionMaxTokens(), - null); + codeCompletionsEnabledCheckBox = new JBCheckBox( + CodeGPTBundle.get("codeCompletionsForm.enableFeatureText"), + settings.isCodeCompletionsEnabled()); } public JPanel getForm() { - var configurationGrid = UI.PanelFactory.grid() - .add(UI.PanelFactory.panel(apiKeyField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get("settingsConfigurable.service.openai.apiKey.comment")) - .withCommentHyperlinkListener(UIUtil::handleHyperlinkClicked)) - .add(UI.PanelFactory.panel(organizationField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.service.openai.organization.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get( - "settingsConfigurable.section.openai.organization.comment"))) - .add(UI.PanelFactory.panel(completionModelComboBox) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.model.label")) - .resizeX(false)) - .createPanel(); - return FormBuilder.createFormBuilder() - .addComponent(new TitledSeparator(CodeGPTBundle.get("shared.configuration"))) - .addComponent(withEmptyLeftBorder(configurationGrid)) - .addComponent(new TitledSeparator(CodeGPTBundle.get("shared.codeCompletions"))) - .addComponent(withEmptyLeftBorder(codeCompletionConfigurationForm.getForm())) + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label"), apiKeyField) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.openai.apiKey.comment") + ) + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.service.openai.organization.label"), + organizationField) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.section.openai.organization.comment") + ) + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.shared.model.label"), completionModelComboBox) + .addVerticalGap(4) + .addComponent(codeCompletionsEnabledCheckBox) .addComponentFillVertically(new JPanel(), 0) .getPanel(); } @@ -87,8 +78,7 @@ public class OpenAISettingsForm { var state = new OpenAISettingsState(); state.setModel(getModel()); state.setOrganization(organizationField.getText()); - state.setCodeCompletionsEnabled(codeCompletionConfigurationForm.isCodeCompletionsEnabled()); - state.setCodeCompletionMaxTokens(codeCompletionConfigurationForm.getMaxTokens()); + state.setCodeCompletionsEnabled(codeCompletionsEnabledCheckBox.isSelected()); return state; } @@ -98,7 +88,6 @@ public class OpenAISettingsForm { completionModelComboBox.setSelectedItem( OpenAIChatCompletionModel.findByCode(state.getModel())); organizationField.setText(state.getOrganization()); - codeCompletionConfigurationForm.setCodeCompletionsEnabled(state.isCodeCompletionsEnabled()); - codeCompletionConfigurationForm.setMaxTokens(state.getCodeCompletionMaxTokens()); + codeCompletionsEnabledCheckBox.setSelected(state.isCodeCompletionsEnabled()); } } 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 index b13df7d1..ef4d697f 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsState.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettingsState.java @@ -8,7 +8,6 @@ public class OpenAISettingsState { private String organization = ""; private String model = OpenAIChatCompletionModel.GPT_3_5_0125_16k.getCode(); private boolean codeCompletionsEnabled = true; - private int codeCompletionMaxTokens = 128; public String getOrganization() { return organization; @@ -34,14 +33,6 @@ public class OpenAISettingsState { this.codeCompletionsEnabled = codeCompletionsEnabled; } - public int getCodeCompletionMaxTokens() { - return codeCompletionMaxTokens; - } - - public void setCodeCompletionMaxTokens(int codeCompletionMaxTokens) { - this.codeCompletionMaxTokens = codeCompletionMaxTokens; - } - @Override public boolean equals(Object o) { if (this == o) { @@ -53,12 +44,11 @@ public class OpenAISettingsState { OpenAISettingsState that = (OpenAISettingsState) o; return Objects.equals(organization, that.organization) && Objects.equals(model, that.model) - && codeCompletionsEnabled == that.codeCompletionsEnabled - && codeCompletionMaxTokens == that.codeCompletionMaxTokens; + && codeCompletionsEnabled == that.codeCompletionsEnabled; } @Override public int hashCode() { - return Objects.hash(organization, model, codeCompletionsEnabled, codeCompletionMaxTokens); + return Objects.hash(organization, model, codeCompletionsEnabled); } } diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java index f94f0f8f..798afa4c 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/ModelComboBoxAction.java @@ -5,7 +5,6 @@ import static ee.carlrobert.codegpt.settings.service.ServiceType.CUSTOM_OPENAI; import static ee.carlrobert.codegpt.settings.service.ServiceType.OLLAMA; import static ee.carlrobert.codegpt.settings.service.ServiceType.OPENAI; import static ee.carlrobert.codegpt.settings.service.ServiceType.YOU; -import static ee.carlrobert.llm.client.codegpt.CodeGPTAvailableModels.AVAILABLE_CHAT_MODELS; import static java.lang.String.format; import com.intellij.openapi.actionSystem.ActionUpdateThread; @@ -25,13 +24,14 @@ import ee.carlrobert.codegpt.credentials.CredentialsStore; import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey; import ee.carlrobert.codegpt.settings.GeneralSettings; import ee.carlrobert.codegpt.settings.service.ServiceType; +import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTAvailableModels; +import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTModel; import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings; import ee.carlrobert.codegpt.settings.service.custom.CustomServiceSettings; import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings; import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings; import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings; import ee.carlrobert.codegpt.settings.service.you.YouSettings; -import ee.carlrobert.llm.client.codegpt.CodeGPTModel; import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; import ee.carlrobert.llm.client.you.completion.YouCompletionCustomModel; import ee.carlrobert.llm.client.you.completion.YouCompletionMode; @@ -67,9 +67,9 @@ public class ModelComboBoxAction extends ComboBoxAction { private AnAction[] getCodeGPTModelActions(Presentation presentation) { var apiKey = CredentialsStore.getCredential(CredentialKey.CODEGPT_API_KEY); - return AVAILABLE_CHAT_MODELS.stream() + return CodeGPTAvailableModels.getCHAT_MODELS().stream() .map(model -> { - var enabled = "codellama/CodeLlama-13b-Instruct-hf".equals(model.getCode()) + var enabled = "meta-llama/Llama-3-8b-chat-hf".equals(model.getCode()) || (apiKey != null && !apiKey.isEmpty()); return createCodeGPTModelAction(model, enabled, presentation); }) @@ -174,7 +174,7 @@ public class ModelComboBoxAction extends ComboBoxAction { .getState() .getChatCompletionSettings() .getModel(); - var modelName = AVAILABLE_CHAT_MODELS.stream() + var modelName = CodeGPTAvailableModels.getCHAT_MODELS().stream() .filter(it -> it.getCode().equals(model)) .map(CodeGPTModel::getName) .findFirst().orElse("Unknown"); diff --git a/src/main/kotlin/ee/carlrobert/codegpt/actions/CodeCompletionFeatureToggleActions.kt b/src/main/kotlin/ee/carlrobert/codegpt/actions/CodeCompletionFeatureToggleActions.kt index 6a0b29d0..1e0095ce 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/actions/CodeCompletionFeatureToggleActions.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/actions/CodeCompletionFeatureToggleActions.kt @@ -20,7 +20,8 @@ abstract class CodeCompletionFeatureToggleActions( override fun actionPerformed(e: AnActionEvent) { when (GeneralSettings.getCurrentState().selectedService) { CODEGPT -> - service().state.codeCompletionSettings.codeCompletionsEnabled + service().state.codeCompletionSettings.codeCompletionsEnabled = + enableFeatureAction OPENAI -> OpenAISettings.getCurrentState().isCodeCompletionsEnabled = enableFeatureAction diff --git a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestFactory.kt index 3fe627dc..1b1a777a 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionRequestFactory.kt @@ -31,7 +31,7 @@ object CodeCompletionRequestFactory { .setSuffix(details.suffix) .setStream(true) .setModel(settings.model) - .setMaxTokens(settings.maxTokens) + .setMaxTokens(getMaxTokens(details.prefix, details.suffix)) .setTemperature(0.4) .build() } @@ -41,7 +41,7 @@ object CodeCompletionRequestFactory { return OpenAITextCompletionRequest.Builder(details.prefix) .setSuffix(details.suffix) .setStream(true) - .setMaxTokens(OpenAISettings.getCurrentState().codeCompletionMaxTokens) + .setMaxTokens(getMaxTokens(details.prefix, details.suffix)) .setTemperature(0.4) .build() } @@ -99,7 +99,7 @@ object CodeCompletionRequestFactory { val promptTemplate = getLlamaInfillPromptTemplate(settings) val prompt = promptTemplate.buildPrompt(details.prefix, details.suffix) return LlamaCompletionRequest.Builder(prompt) - .setN_predict(settings.codeCompletionMaxTokens) + .setN_predict(getMaxTokens(details.prefix, details.suffix)) .setStream(true) .setTemperature(0.4) .setStop(promptTemplate.stopTokens) @@ -115,7 +115,7 @@ object CodeCompletionRequestFactory { .setOptions( OllamaParameters.Builder() .stop(settings.fimTemplate.stopTokens) - .numPredict(settings.codeCompletionMaxTokens) + .numPredict(getMaxTokens(details.prefix, details.suffix)) .build() ) .setRaw(true) @@ -145,4 +145,13 @@ object CodeCompletionRequestFactory { else -> value } } + + private fun getMaxTokens(prefix: String, suffix: String): Int { + if (isBoundaryCharacter(prefix[prefix.length - 1]) || isBoundaryCharacter(suffix[0])) { + return 16 + } + return 36 + } + + private fun isBoundaryCharacter(c: Char): Boolean = c in "()[]{}<>~!@#$%^&*-+=|\\;:'\",./?" } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionService.kt b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionService.kt index a2093b31..1e806e92 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionService.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionService.kt @@ -5,6 +5,7 @@ import com.intellij.openapi.components.service import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildCodeGPTRequest import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildCustomRequest import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildLlamaRequest +import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildOllamaRequest import ee.carlrobert.codegpt.codecompletions.CodeCompletionRequestFactory.buildOpenAIRequest import ee.carlrobert.codegpt.completions.CompletionClientProvider import ee.carlrobert.codegpt.settings.GeneralSettings @@ -51,6 +52,9 @@ class CodeCompletionService { OpenAITextCompletionEventSourceListener(eventListener) ) + OLLAMA -> CompletionClientProvider.getOllamaClient() + .getCompletionAsync(buildOllamaRequest(requestDetails), eventListener) + LLAMA_CPP -> CompletionClientProvider.getLlamaClient() .getChatCompletionAsync(buildLlamaRequest(requestDetails), eventListener) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt index 1a817d29..18c62f8e 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeGPTInlineCompletionProvider.kt @@ -6,14 +6,17 @@ import com.intellij.notification.NotificationType import com.intellij.openapi.application.EDT import com.intellij.openapi.components.service import com.intellij.openapi.diagnostic.thisLogger +import com.intellij.openapi.util.TextRange import ee.carlrobert.codegpt.CodeGPTKeys import ee.carlrobert.codegpt.settings.GeneralSettings +import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings import ee.carlrobert.codegpt.settings.service.ServiceType import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings import ee.carlrobert.codegpt.settings.service.custom.CustomServiceSettings import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings +import ee.carlrobert.codegpt.treesitter.CodeCompletionParserFactory import ee.carlrobert.codegpt.ui.OverlayUtil.showNotification import ee.carlrobert.llm.client.openai.completion.ErrorDetails import ee.carlrobert.llm.completion.CompletionEventListener @@ -46,18 +49,48 @@ class CodeGPTInlineCompletionProvider : InlineCompletionProvider { val infillRequest = withContext(Dispatchers.EDT) { InfillRequestDetails.fromInlineCompletionRequest(request) } + val (prefix, suffix) = withContext(Dispatchers.EDT) { + val caretOffset = request.editor.caretModel.offset + val prefix = + request.document.getText(TextRange(0, caretOffset)) + val suffix = + request.document.getText( + TextRange( + caretOffset, + request.document.textLength + ) + ) + Pair(prefix, suffix) + } + currentCall.set( project.service().getCodeCompletionAsync( infillRequest, CodeCompletionEventListener { - val inlineText = it.takeWhile { message -> message != '\n' }.toString() - request.editor.putUserData(CodeGPTKeys.PREVIOUS_INLAY_TEXT, inlineText) - launch { - try { - trySend(InlineCompletionGrayTextElement(inlineText)) - } catch (e: Exception) { - logger.error("Failed to send inline completion suggestion", e) + val settings = service().state + try { + var inlineText = it.toString() + if (settings.isAutocompletionPostProcessingEnabled) { + inlineText = CodeCompletionParserFactory + .getParserForFileExtension(request.file.virtualFile.extension) + .parse( + prefix, + suffix, + inlineText + ) } + + request.editor.putUserData(CodeGPTKeys.PREVIOUS_INLAY_TEXT, inlineText) + launch { + try { + trySend(InlineCompletionGrayTextElement(inlineText)) + } catch (e: Exception) { + logger.error("Failed to send inline completion suggestion", e) + } + } + } catch (t: Throwable) { + logger.error(t) + settings.isAutocompletionPostProcessingEnabled = false } } ) @@ -91,12 +124,6 @@ class CodeGPTInlineCompletionProvider : InlineCompletionProvider { private val completed: (StringBuilder) -> Unit ) : CompletionEventListener { - override fun onMessage(message: String?, eventSource: EventSource?) { - if (message != null && message.contains('\n')) { - eventSource?.cancel() - } - } - override fun onComplete(messageBuilder: StringBuilder) { completed(messageBuilder) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/CodeCompletionConfigurationForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/CodeCompletionConfigurationForm.kt index ddf60b53..9579e9f9 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/CodeCompletionConfigurationForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/CodeCompletionConfigurationForm.kt @@ -3,11 +3,9 @@ package ee.carlrobert.codegpt.settings.service import com.intellij.icons.AllIcons.General import com.intellij.ide.HelpTooltip import com.intellij.openapi.ui.ComboBox -import com.intellij.openapi.ui.panel.ComponentPanelBuilder import com.intellij.ui.EnumComboBoxModel import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBLabel -import com.intellij.ui.components.fields.IntegerField import com.intellij.util.ui.FormBuilder import ee.carlrobert.codegpt.CodeGPTBundle import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate @@ -18,7 +16,6 @@ import javax.swing.JPanel class CodeCompletionConfigurationForm( codeCompletionsEnabled: Boolean, - maxTokens: Int, fimTemplate: InfillPromptTemplate? ) { @@ -26,11 +23,6 @@ class CodeCompletionConfigurationForm( CodeGPTBundle.get("codeCompletionsForm.enableFeatureText"), codeCompletionsEnabled ) - private val codeCompletionMaxTokensField = - IntegerField("completion_max_tokens", 8, 4096).apply { - columns = 12 - value = maxTokens - } private val promptTemplateComboBox = ComboBox(EnumComboBoxModel(InfillPromptTemplate::class.java)).apply { item = fimTemplate @@ -43,7 +35,6 @@ class CodeCompletionConfigurationForm( fun getForm(): JPanel { val formBuilder = FormBuilder.createFormBuilder() .addComponent(codeCompletionsEnabledCheckBox) - .addVerticalGap(4); if (fimTemplate != null) { formBuilder.addVerticalGap(4) .addLabeledComponent( @@ -54,16 +45,7 @@ class CodeCompletionConfigurationForm( add(promptTemplateHelpText) }) } - return formBuilder.addLabeledComponent( - CodeGPTBundle.get("codeCompletionsForm.maxTokensLabel"), - codeCompletionMaxTokensField - ) - .addComponentToRightColumn( - ComponentPanelBuilder.createCommentComponent( - CodeGPTBundle.get("codeCompletionsForm.maxTokensComment"), true, 48, true - ) - ) - .panel + return formBuilder.panel } var isCodeCompletionsEnabled: Boolean @@ -72,12 +54,6 @@ class CodeCompletionConfigurationForm( codeCompletionsEnabledCheckBox.isSelected = enabled } - var maxTokens: Int - get() = codeCompletionMaxTokensField.value - set(maxTokens) { - codeCompletionMaxTokensField.value = maxTokens - } - var fimTemplate: InfillPromptTemplate? get() = promptTemplateComboBox.item set(template) { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ServiceConfigurableComponent.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ServiceConfigurableComponent.kt index 0e96250e..56314f1e 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ServiceConfigurableComponent.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ServiceConfigurableComponent.kt @@ -43,7 +43,7 @@ class ServiceConfigurableComponent { .addComponent(JBLabel("All available providers that can be used with CodeGPT:")) .addVerticalGap(8) .addComponent(FormBuilder.createFormBuilder() - .setFormLeftIndent(16).apply { + .setFormLeftIndent(20).apply { addLinks(this) } .panel) diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt new file mode 100644 index 00000000..50a10a86 --- /dev/null +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt @@ -0,0 +1,31 @@ +package ee.carlrobert.codegpt.settings.service.codegpt + +object CodeGPTAvailableModels { + + @JvmStatic + val CHAT_MODELS: List = listOf( + CodeGPTModel("Llama 3 (70B)", "meta-llama/Llama-3-70b-chat-hf"), + CodeGPTModel("Llama 3 (8B)", "meta-llama/Llama-3-8b-chat-hf"), + CodeGPTModel("Code Llama (70B)", "codellama/CodeLlama-70b-Instruct-hf"), + CodeGPTModel("Mixtral (8x22B)", "mistralai/Mixtral-8x22B-Instruct-v0.1"), + CodeGPTModel("DBRX (132B)", "databricks/dbrx-instruct"), + CodeGPTModel("DeepSeek Coder (33B)", "deepseek-ai/deepseek-coder-33b-instruct"), + CodeGPTModel("WizardLM-2 (8x22B)", "microsoft/WizardLM-2-8x22B") + ) + + @JvmStatic + val CODE_MODELS: List = listOf( + CodeGPTModel("StarCoder (16B)", "starcoder-16b"), + CodeGPTModel("Code Llama (70B)", "codellama/CodeLlama-70b-hf"), + CodeGPTModel("Code Llama Python (70B)", "codellama/CodeLlama-70b-Python-hf"), + CodeGPTModel("WizardCoder Python (34B)", "WizardLM/WizardCoder-Python-34B-V1.0"), + CodeGPTModel("Phind Code LLaMA v2 (34B)", "Phind/Phind-CodeLlama-34B-v2") + ) + + @JvmStatic + fun findByCode(code: String?): CodeGPTModel? { + return CHAT_MODELS.union(CODE_MODELS).firstOrNull { it.code == code } + } +} + +data class CodeGPTModel(val name: String, val code: String) \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceForm.kt index 2bb4870d..f9152fac 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceForm.kt @@ -2,21 +2,15 @@ package ee.carlrobert.codegpt.settings.service.codegpt import com.intellij.openapi.components.service import com.intellij.openapi.ui.ComboBox -import com.intellij.openapi.ui.panel.ComponentPanelBuilder -import com.intellij.ui.TitledSeparator +import com.intellij.ui.DocumentAdapter import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBPasswordField -import com.intellij.ui.components.fields.IntegerField import com.intellij.util.ui.FormBuilder import ee.carlrobert.codegpt.CodeGPTBundle import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.CODEGPT_API_KEY import ee.carlrobert.codegpt.credentials.CredentialsStore.getCredential import ee.carlrobert.codegpt.credentials.CredentialsStore.setCredential import ee.carlrobert.codegpt.ui.UIUtil -import ee.carlrobert.llm.client.codegpt.CodeGPTAvailableModels -import ee.carlrobert.llm.client.codegpt.CodeGPTAvailableModels.AVAILABLE_CHAT_MODELS -import ee.carlrobert.llm.client.codegpt.CodeGPTAvailableModels.AVAILABLE_CODE_MODELS -import ee.carlrobert.llm.client.codegpt.CodeGPTModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import org.jdesktop.swingx.combobox.ListComboBoxModel @@ -24,6 +18,7 @@ import java.awt.Component import javax.swing.DefaultListCellRenderer import javax.swing.JList import javax.swing.JPanel +import javax.swing.event.DocumentEvent class CodeGPTServiceForm { @@ -32,7 +27,7 @@ class CodeGPTServiceForm { } private val chatCompletionModelComboBox = - ComboBox(ListComboBoxModel(AVAILABLE_CHAT_MODELS)).apply { + ComboBox(ListComboBoxModel(CodeGPTAvailableModels.CHAT_MODELS)).apply { selectedItem = CodeGPTAvailableModels.findByCode(service().state.chatCompletionSettings.model) renderer = CustomComboBoxRenderer() @@ -44,54 +39,47 @@ class CodeGPTServiceForm { ) private val codeCompletionModelComboBox = - ComboBox(ListComboBoxModel(AVAILABLE_CODE_MODELS)).apply { + ComboBox(ListComboBoxModel(CodeGPTAvailableModels.CODE_MODELS)).apply { selectedItem = CodeGPTAvailableModels.findByCode(service().state.codeCompletionSettings.model) renderer = CustomComboBoxRenderer() } - private val codeCompletionMaxTokensField = - IntegerField("completion_max_tokens", 8, 4096).apply { - columns = 12 - value = service().state.codeCompletionSettings.maxTokens - } + private fun updateCodeCompletionForm(enabled: Boolean) { + codeCompletionModelComboBox.isEnabled = enabled + codeCompletionsEnabledCheckBox.isEnabled = enabled + } init { apiKeyField.text = runBlocking(Dispatchers.IO) { getCredential(CODEGPT_API_KEY) } + updateCodeCompletionForm(apiKeyField.password.isNotEmpty()) + apiKeyField.document.addDocumentListener(object : DocumentAdapter() { + override fun textChanged(e: DocumentEvent) { + updateCodeCompletionForm(apiKeyField.password.isNotEmpty()) + } + }) } fun getForm(): JPanel = FormBuilder.createFormBuilder() - .addComponent(TitledSeparator(CodeGPTBundle.get("shared.configuration"))) - .addComponent( - FormBuilder.createFormBuilder() - .setFormLeftIndent(16) - .addLabeledComponent( - CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label"), - apiKeyField - ) - .addComponentToRightColumn( - UIUtil.createComment("settingsConfigurable.service.codegpt.apiKey.comment") - ) - .addLabeledComponent("Model:", chatCompletionModelComboBox) - .addVerticalGap(4) - .panel + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label"), + apiKeyField ) - .addComponent(TitledSeparator("Code Completions")) - .addComponent( - FormBuilder.createFormBuilder() - .setFormLeftIndent(16) - .addComponent(codeCompletionsEnabledCheckBox) - .addLabeledComponent("Model:", codeCompletionModelComboBox) - .addLabeledComponent("Max tokens:", codeCompletionMaxTokensField) - .addComponentToRightColumn( - ComponentPanelBuilder.createCommentComponent( - CodeGPTBundle.get("codeCompletionsForm.maxTokensComment"), true, 48, true - ) - ) - .panel + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.codegpt.apiKey.comment") ) + .addLabeledComponent("Chat model:", chatCompletionModelComboBox) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.codegpt.chatCompletionModel.comment") + ) + .addLabeledComponent("Code model:", codeCompletionModelComboBox) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.codegpt.codeCompletionModel.comment") + ) + .addVerticalGap(4) + .addComponent(codeCompletionsEnabledCheckBox) .addComponentFillVertically(JPanel(), 0) .panel @@ -100,7 +88,6 @@ class CodeGPTServiceForm { fun isModified() = service().state.run { (chatCompletionModelComboBox.selectedItem as CodeGPTModel).code != chatCompletionSettings.model || (codeCompletionModelComboBox.selectedItem as CodeGPTModel).code != codeCompletionSettings.model - || codeCompletionMaxTokensField.value != codeCompletionSettings.maxTokens || codeCompletionsEnabledCheckBox.isSelected != codeCompletionSettings.codeCompletionsEnabled || getApiKey() != getCredential(CODEGPT_API_KEY) } @@ -111,7 +98,6 @@ class CodeGPTServiceForm { (chatCompletionModelComboBox.selectedItem as CodeGPTModel).code codeCompletionSettings.codeCompletionsEnabled = codeCompletionsEnabledCheckBox.isSelected - codeCompletionSettings.maxTokens = codeCompletionMaxTokensField.value codeCompletionSettings.model = (codeCompletionModelComboBox.selectedItem as CodeGPTModel).code } @@ -122,7 +108,6 @@ class CodeGPTServiceForm { service().state.run { chatCompletionModelComboBox.selectedItem = chatCompletionSettings.model codeCompletionModelComboBox.selectedItem = codeCompletionSettings.model - codeCompletionMaxTokensField.value = codeCompletionSettings.maxTokens codeCompletionsEnabledCheckBox.isSelected = codeCompletionSettings.codeCompletionsEnabled } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceSettings.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceSettings.kt index 7aa9bd62..8c3bf09a 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceSettings.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceSettings.kt @@ -22,5 +22,4 @@ class CodeGPTServiceChatCompletionSettingsState : BaseState() { class CodeGPTServiceCodeCompletionSettingsState : BaseState() { var codeCompletionsEnabled by property(true) var model by string("codellama/CodeLlama-70b-hf") - var maxTokens by property(128) } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettingsForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettingsForm.kt index a04a26d9..46554746 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettingsForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettingsForm.kt @@ -3,10 +3,8 @@ package ee.carlrobert.codegpt.settings.service.google import com.intellij.openapi.components.service 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.util.ui.FormBuilder -import com.intellij.util.ui.UI import ee.carlrobert.codegpt.CodeGPTBundle import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.GOOGLE_API_KEY import ee.carlrobert.codegpt.credentials.CredentialsStore.getCredential @@ -15,7 +13,6 @@ import ee.carlrobert.llm.client.google.models.GoogleModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import javax.swing.JPanel -import javax.swing.event.HyperlinkEvent class GoogleSettingsForm { @@ -34,40 +31,25 @@ class GoogleSettingsForm { completionModelComboBox.selectedItem = GoogleModel.findByCode(state.model) } - fun getForm(): JPanel = FormBuilder.createFormBuilder() - .addComponent(TitledSeparator(CodeGPTBundle.get("shared.configuration"))) - .addComponent( - UIUtil.withEmptyLeftBorder( - UI.PanelFactory.grid() - .add( - UI.PanelFactory.panel(apiKeyField) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get("settingsConfigurable.service.google.apiKey.comment")) - .withCommentHyperlinkListener { event: HyperlinkEvent? -> - UIUtil.handleHyperlinkClicked( - event - ) - }) - .add( - UI.PanelFactory.panel(completionModelComboBox) - .withLabel(CodeGPTBundle.get("settingsConfigurable.shared.model.label")) - .resizeX(false) - .withComment(CodeGPTBundle.get("settingsConfigurable.service.google.model.comment")) - .withCommentHyperlinkListener { event: HyperlinkEvent? -> - UIUtil.handleHyperlinkClicked( - event - ) - } - ) - .createPanel() - ) + fun getForm(): JPanel = FormBuilder.createFormBuilder() + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label"), + apiKeyField + ) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.google.apiKey.comment") + ) + .addLabeledComponent( + CodeGPTBundle.get("settingsConfigurable.shared.model.label"), + completionModelComboBox + ) + .addComponentToRightColumn( + UIUtil.createComment("settingsConfigurable.service.google.model.comment") ) .addComponentFillVertically(JPanel(), 0) .panel - fun getApiKey(): String? = String(apiKeyField.password).ifEmpty { null } fun getModel(): String = (completionModelComboBox.model diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettings.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettings.kt index 9743c808..64c03ba1 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettings.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettings.kt @@ -14,7 +14,6 @@ class OllamaSettingsState : BaseState() { var host by string("http://localhost:11434") var model by string() var codeCompletionsEnabled by property(true) - var codeCompletionMaxTokens by property(128) var fimTemplate by enum(InfillPromptTemplate.CODE_LLAMA) var availableModels by list() } \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt index 71df61e4..9825a2ca 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsForm.kt @@ -39,7 +39,6 @@ class OllamaSettingsForm { val settings = service().state codeCompletionConfigurationForm = CodeCompletionConfigurationForm( settings.codeCompletionsEnabled, - settings.codeCompletionMaxTokens, settings.fimTemplate ) val emptyModelsComboBoxModel = @@ -93,7 +92,6 @@ class OllamaSettingsForm { hostField.text = host modelComboBox.item = model codeCompletionConfigurationForm.isCodeCompletionsEnabled = codeCompletionsEnabled - codeCompletionConfigurationForm.maxTokens = codeCompletionMaxTokens codeCompletionConfigurationForm.fimTemplate = fimTemplate } } @@ -103,7 +101,6 @@ class OllamaSettingsForm { host = hostField.text model = modelComboBox.item codeCompletionsEnabled = codeCompletionConfigurationForm.isCodeCompletionsEnabled - codeCompletionMaxTokens = codeCompletionConfigurationForm.maxTokens fimTemplate = codeCompletionConfigurationForm.fimTemplate!! } } @@ -112,11 +109,10 @@ class OllamaSettingsForm { hostField.text != host || modelComboBox.item != model || codeCompletionConfigurationForm.isCodeCompletionsEnabled != codeCompletionsEnabled - || codeCompletionConfigurationForm.maxTokens != codeCompletionMaxTokens || codeCompletionConfigurationForm.fimTemplate != fimTemplate } - fun refreshModels() { + private fun refreshModels() { disableModelComboBoxWithPlaceholder(DefaultComboBoxModel(arrayOf("Loading"))) try { val models = runBlocking(Dispatchers.IO) { diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index fdf406b8..7fb9d6d0 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -19,6 +19,8 @@ settings.openaiQuotaExceeded=OpenAI quota exceeded. settingsConfigurable.displayName.label=Display name: settingsConfigurable.service.label=Selected provider: settingsConfigurable.service.codegpt.apiKey.comment=You can find the API key in your User settings. +settingsConfigurable.service.codegpt.chatCompletionModel.comment=Choose a model optimized for conversational interactions, including assistance with general queries and explanations. +settingsConfigurable.service.codegpt.codeCompletionModel.comment=Choose a model tailored for code completion-related tasks. settingsConfigurable.service.custom.openai.apiKey.comment=A secret value stored in the system's Keychain or KeePass, depending on your OS. This approach is recommended over storing the secret in the header as plain text. settingsConfigurable.service.openai.apiKey.comment=You can find the API key in your User settings. settingsConfigurable.service.openai.customModel.label=Custom model: @@ -97,6 +99,7 @@ configurationConfigurable.checkForNewScreenshots.label=Check for new screenshots configurationConfigurable.openNewTabCheckBox.label=Open a new chat on each action configurationConfigurable.enableMethodNameGeneration.label=Enable method name lookup suggestions configurationConfigurable.autoFormatting.label=Enable automatic code formatting +configurationConfigurable.autocompletionPostProcessing.label=Enable code completion post processing configurationConfigurable.section.assistant.title=Assistant Configuration configurationConfigurable.section.assistant.systemPromptField.label=System prompt: configurationConfigurable.section.assistant.systemPromptField.comment=The system message helps to set the behaviour of the assistant