refactor: implement ConfigurationSettings as a Kotlin service (#634)

This commit is contained in:
Carl-Robert Linnupuu 2024-08-21 13:39:48 +03:00
parent 42568b1c59
commit 083c11f923
20 changed files with 108 additions and 254 deletions

View file

@ -38,7 +38,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen
int errors,
int warnings,
@NotNull CompileContext compileContext) {
var success = !ConfigurationSettings.getCurrentState().isCaptureCompileErrors()
var success = !ConfigurationSettings.getState().getCaptureCompileErrors()
|| (!aborted && errors == 0 && warnings == 0);
if (success) {
return;
@ -53,7 +53,7 @@ public class ProjectCompilationStatusListener implements CompilationStatusListen
.sendMessage(getMultiFileMessage(compileContext), FIX_COMPILE_ERRORS)))
.addAction(NotificationAction.createSimpleExpiring(
CodeGPTBundle.get("shared.notification.doNotShowAgain"),
() -> ConfigurationSettings.getCurrentState().setCaptureCompileErrors(false)))
() -> ConfigurationSettings.getState().setCaptureCompileErrors(false)))
.notify(project);
}
}

View file

@ -51,7 +51,7 @@ public class EditorActionsUtil {
group.add(new CustomPromptAction());
group.addSeparator();
var configuredActions = ConfigurationSettings.getCurrentState().getTableData();
var configuredActions = ConfigurationSettings.getState().getTableData();
configuredActions.forEach((label, prompt) -> {
// using label as action description to prevent com.intellij.diagnostic.PluginException
// https://github.com/carlrobertoh/CodeGPT/issues/95

View file

@ -134,7 +134,7 @@ public class CompletionRequestProvider {
new OpenAIChatCompletionStandardMessage("user", context)))
.setModel(model)
.setStream(true)
.setMaxTokens(ConfigurationSettings.getCurrentState().getMaxTokens())
.setMaxTokens(ConfigurationSettings.getState().getMaxTokens())
.build();
}
@ -202,7 +202,7 @@ public class CompletionRequestProvider {
systemPrompt,
message.getPrompt(),
conversation.getMessages());
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
return new LlamaCompletionRequest.Builder(prompt)
.setN_predict(configuration.getMaxTokens())
.setTemperature(configuration.getTemperature())
@ -217,7 +217,7 @@ public class CompletionRequestProvider {
public OpenAIChatCompletionRequest buildOpenAIChatCompletionRequest(
@Nullable String model,
CallParameters callParameters) {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
var requestBuilder = new OpenAIChatCompletionRequest.Builder(
buildOpenAIMessages(model, callParameters))
.setModel(model)
@ -242,7 +242,7 @@ public class CompletionRequestProvider {
public GoogleCompletionRequest buildGoogleChatCompletionRequest(
@Nullable String model,
CallParameters callParameters) {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
return new GoogleCompletionRequest.Builder(buildGoogleMessages(model, callParameters))
.generationConfig(new GoogleGenerationConfig.Builder()
.maxOutputTokens(configuration.getMaxTokens())
@ -309,7 +309,7 @@ public class CompletionRequestProvider {
public ClaudeCompletionRequest buildAnthropicChatCompletionRequest(
CallParameters callParameters) {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
var settings = AnthropicSettings.getCurrentState();
var request = new ClaudeCompletionRequest();
request.setModel(settings.getModel());
@ -342,14 +342,14 @@ public class CompletionRequestProvider {
public OllamaChatCompletionRequest buildOllamaChatCompletionRequest(
CallParameters callParameters
) {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
var settings = ApplicationManager.getApplication().getService(OllamaSettings.class).getState();
return new OllamaChatCompletionRequest
.Builder(settings.getModel(), buildOllamaMessages(callParameters))
.setStream(true)
.setOptions(new OllamaParameters.Builder()
.numPredict(configuration.getMaxTokens())
.temperature(configuration.getTemperature())
.temperature((double) configuration.getTemperature())
.build())
.build();
}
@ -474,7 +474,7 @@ public class CompletionRequestProvider {
int totalUsage = messages.parallelStream()
.mapToInt(encodingManager::countMessageTokens)
.sum() + ConfigurationSettings.getCurrentState().getMaxTokens();
.sum() + ConfigurationSettings.getState().getMaxTokens();
int modelMaxTokens;
try {
modelMaxTokens = OpenAIChatCompletionModel.findByCode(model).getMaxTokens();
@ -550,7 +550,7 @@ public class CompletionRequestProvider {
int totalUsage = messages.parallelStream()
.mapToInt(message -> encodingManager.countMessageTokens(message.getRole(),
String.join(",", message.getParts().stream().map(GoogleContentPart::getText).toList())))
.sum() + ConfigurationSettings.getCurrentState().getMaxTokens();
.sum() + ConfigurationSettings.getState().getMaxTokens();
int modelMaxTokens;
try {
modelMaxTokens = GoogleModel.findByCode(model).getMaxTokens();

View file

@ -133,7 +133,7 @@ public final class CompletionRequestService {
String systemPrompt,
String gitDiff,
CompletionEventListener<String> eventListener) {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
var openaiRequestBuilder = new Builder(List.of(
new OpenAIChatCompletionStandardMessage("system", systemPrompt),
new OpenAIChatCompletionStandardMessage("user", gitDiff)))

View file

@ -18,8 +18,8 @@ public class MethodNameLookupListener implements LookupManagerListener {
@Override
public void activeLookupChanged(@Nullable Lookup oldLookup, @Nullable Lookup newLookup) {
if (!ConfigurationSettings.getCurrentState().isMethodNameGenerationEnabled()
|| !CompletionRequestService.getInstance().isRequestAllowed()
if (!ConfigurationSettings.getState().getMethodNameGenerationEnabled()
|| !CompletionRequestService.isRequestAllowed()
|| !(newLookup instanceof LookupImpl lookup)) {
return;
}

View file

@ -52,7 +52,9 @@ public class ConfigurationComponent {
private final IntegerField maxTokensField;
private final JBTextField temperatureField;
public ConfigurationComponent(Disposable parentDisposable, ConfigurationState configuration) {
public ConfigurationComponent(
Disposable parentDisposable,
ConfigurationSettingsState configuration) {
table = new JBTable(new DefaultTableModel(
EditorActionsUtil.toArray(configuration.getTableData()),
new String[]{
@ -99,26 +101,26 @@ public class ConfigurationComponent {
checkForPluginUpdatesCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.checkForPluginUpdates.label"),
configuration.isCheckForPluginUpdates());
configuration.getCheckForPluginUpdates());
checkForNewScreenshotsCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.checkForNewScreenshots.label"),
configuration.isCheckForNewScreenshots());
configuration.getCheckForNewScreenshots());
openNewTabCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.openNewTabCheckBox.label"),
configuration.isCreateNewChatOnEachAction());
configuration.getCreateNewChatOnEachAction());
methodNameGenerationCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.enableMethodNameGeneration.label"),
configuration.isMethodNameGenerationEnabled());
configuration.getMethodNameGenerationEnabled());
autoFormattingCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.autoFormatting.label"),
configuration.isAutoFormattingEnabled());
configuration.getAutoFormattingEnabled());
autocompletionPostProcessingCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.autocompletionPostProcessing.label"),
configuration.isAutocompletionPostProcessingEnabled()
configuration.getAutocompletionPostProcessingEnabled()
);
autocompletionContextAwareCheckBox = new JBCheckBox(
CodeGPTBundle.get("configurationConfigurable.autocompletionContextAwareCheckBox.label"),
configuration.isAutocompletionPostProcessingEnabled()
configuration.getAutocompletionContextAwareEnabled()
);
mainPanel = FormBuilder.createFormBuilder()
@ -146,11 +148,11 @@ public class ConfigurationComponent {
return mainPanel;
}
public ConfigurationState getCurrentFormState() {
var state = new ConfigurationState();
public ConfigurationSettingsState getCurrentFormState() {
var state = new ConfigurationSettingsState();
state.setTableData(getTableData());
state.setMaxTokens(maxTokensField.getValue());
state.setTemperature(Double.parseDouble(temperatureField.getText()));
state.setTemperature(Float.parseFloat(temperatureField.getText()));
state.setCommitMessagePrompt(commitMessagePromptTextArea.getText());
state.setCheckForPluginUpdates(checkForPluginUpdatesCheckBox.isSelected());
state.setCheckForNewScreenshots(checkForNewScreenshotsCheckBox.isSelected());
@ -163,20 +165,20 @@ public class ConfigurationComponent {
}
public void resetForm() {
var configuration = ConfigurationSettings.getCurrentState();
var configuration = ConfigurationSettings.getState();
setTableData(configuration.getTableData());
maxTokensField.setValue(configuration.getMaxTokens());
temperatureField.setText(String.valueOf(configuration.getTemperature()));
commitMessagePromptTextArea.setText(configuration.getCommitMessagePrompt());
checkForPluginUpdatesCheckBox.setSelected(configuration.isCheckForPluginUpdates());
checkForNewScreenshotsCheckBox.setSelected(configuration.isCheckForNewScreenshots());
openNewTabCheckBox.setSelected(configuration.isCreateNewChatOnEachAction());
methodNameGenerationCheckBox.setSelected(configuration.isMethodNameGenerationEnabled());
autoFormattingCheckBox.setSelected(configuration.isAutoFormattingEnabled());
checkForPluginUpdatesCheckBox.setSelected(configuration.getCheckForPluginUpdates());
checkForNewScreenshotsCheckBox.setSelected(configuration.getCheckForNewScreenshots());
openNewTabCheckBox.setSelected(configuration.getCreateNewChatOnEachAction());
methodNameGenerationCheckBox.setSelected(configuration.getMethodNameGenerationEnabled());
autoFormattingCheckBox.setSelected(configuration.getAutoFormattingEnabled());
autocompletionPostProcessingCheckBox.setSelected(
configuration.isAutocompletionPostProcessingEnabled());
configuration.getAutocompletionPostProcessingEnabled());
autocompletionContextAwareCheckBox.setSelected(
configuration.isAutocompletionContextAwareEnabled());
configuration.getAutocompletionContextAwareEnabled());
}
private Map<String, String> getTableData() {

View file

@ -1,6 +1,7 @@
package ee.carlrobert.codegpt.settings.configuration;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.util.Disposer;
import ee.carlrobert.codegpt.CodeGPTBundle;
@ -27,19 +28,19 @@ public class ConfigurationConfigurable implements Configurable {
parentDisposable = Disposer.newDisposable();
component = new ConfigurationComponent(
parentDisposable,
ConfigurationSettings.getCurrentState());
ConfigurationSettings.getState());
return component.getPanel();
}
@Override
public boolean isModified() {
return !component.getCurrentFormState()
.equals(ConfigurationSettings.getCurrentState());
return !component.getCurrentFormState().equals(ConfigurationSettings.getState());
}
@Override
public void apply() {
ConfigurationSettings.getInstance().loadState(component.getCurrentFormState());
ApplicationManager.getApplication().getService(ConfigurationSettings.class)
.loadState(component.getCurrentFormState());
EditorActionsUtil.refreshActions();
}

View file

@ -1,34 +0,0 @@
package ee.carlrobert.codegpt.settings.configuration;
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_ConfigurationSettings_210",
storages = @Storage("CodeGPT_ConfigurationSettings_210.xml"))
public class ConfigurationSettings implements PersistentStateComponent<ConfigurationState> {
private ConfigurationState state = new ConfigurationState();
@Override
@NotNull
public ConfigurationState getState() {
return state;
}
@Override
public void loadState(@NotNull ConfigurationState state) {
this.state = state;
}
public static ConfigurationState getCurrentState() {
return getInstance().getState();
}
public static ConfigurationSettings getInstance() {
return ApplicationManager.getApplication().getService(ConfigurationSettings.class);
}
}

View file

@ -1,160 +0,0 @@
package ee.carlrobert.codegpt.settings.configuration;
import static ee.carlrobert.codegpt.completions.CompletionRequestProvider.GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
import java.util.Map;
import java.util.Objects;
public class ConfigurationState {
private String commitMessagePrompt = GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT;
private int maxTokens = 2048;
private double temperature = 0.1;
private boolean checkForPluginUpdates = true;
private boolean checkForNewScreenshots = false;
private boolean createNewChatOnEachAction;
private boolean ignoreGitCommitTokenLimit;
private boolean methodNameGenerationEnabled = true;
private boolean captureCompileErrors = true;
private boolean autoFormattingEnabled = true;
private boolean autocompletionPostProcessingEnabled = false;
private boolean autocompletionContextAwareEnabled = false;
private Map<String, String> tableData = EditorActionsUtil.DEFAULT_ACTIONS;
public String getCommitMessagePrompt() {
return commitMessagePrompt;
}
public void setCommitMessagePrompt(String commitMessagePrompt) {
this.commitMessagePrompt = commitMessagePrompt;
}
public int getMaxTokens() {
return maxTokens;
}
public void setMaxTokens(int maxTokens) {
this.maxTokens = maxTokens;
}
public double getTemperature() {
return temperature;
}
public void setTemperature(double temperature) {
this.temperature = temperature;
}
public boolean isCreateNewChatOnEachAction() {
return createNewChatOnEachAction;
}
public void setCreateNewChatOnEachAction(boolean createNewChatOnEachAction) {
this.createNewChatOnEachAction = createNewChatOnEachAction;
}
public boolean isCheckForNewScreenshots() {
return checkForNewScreenshots;
}
public void setCheckForNewScreenshots(boolean checkForNewScreenshots) {
this.checkForNewScreenshots = checkForNewScreenshots;
}
public Map<String, String> getTableData() {
return tableData;
}
public void setTableData(Map<String, String> tableData) {
this.tableData = tableData;
}
public boolean isCheckForPluginUpdates() {
return checkForPluginUpdates;
}
public void setCheckForPluginUpdates(boolean checkForPluginUpdates) {
this.checkForPluginUpdates = checkForPluginUpdates;
}
public boolean isIgnoreGitCommitTokenLimit() {
return ignoreGitCommitTokenLimit;
}
public void setIgnoreGitCommitTokenLimit(boolean ignoreGitCommitTokenLimit) {
this.ignoreGitCommitTokenLimit = ignoreGitCommitTokenLimit;
}
public boolean isMethodNameGenerationEnabled() {
return methodNameGenerationEnabled;
}
public void setMethodNameGenerationEnabled(boolean methodNameGenerationEnabled) {
this.methodNameGenerationEnabled = methodNameGenerationEnabled;
}
public boolean isCaptureCompileErrors() {
return captureCompileErrors;
}
public void setCaptureCompileErrors(boolean captureCompileErrors) {
this.captureCompileErrors = captureCompileErrors;
}
public boolean isAutoFormattingEnabled() {
return autoFormattingEnabled;
}
public void setAutoFormattingEnabled(boolean autoFormattingEnabled) {
this.autoFormattingEnabled = autoFormattingEnabled;
}
public boolean isAutocompletionPostProcessingEnabled() {
return autocompletionPostProcessingEnabled;
}
public void setAutocompletionPostProcessingEnabled(boolean autocompletionPostProcessingEnabled) {
this.autocompletionPostProcessingEnabled = autocompletionPostProcessingEnabled;
}
public boolean isAutocompletionContextAwareEnabled() {
return autocompletionContextAwareEnabled;
}
public void setAutocompletionContextAwareEnabled(boolean autocompletionContextAwareEnabled) {
this.autocompletionContextAwareEnabled = autocompletionContextAwareEnabled;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof ConfigurationState that)) {
return false;
}
return maxTokens == that.maxTokens
&& Double.compare(temperature, that.temperature) == 0
&& checkForPluginUpdates == that.checkForPluginUpdates
&& checkForNewScreenshots == that.checkForNewScreenshots
&& createNewChatOnEachAction == that.createNewChatOnEachAction
&& ignoreGitCommitTokenLimit == that.ignoreGitCommitTokenLimit
&& methodNameGenerationEnabled == that.methodNameGenerationEnabled
&& captureCompileErrors == that.captureCompileErrors
&& autoFormattingEnabled == that.autoFormattingEnabled
&& autocompletionPostProcessingEnabled == that.autocompletionPostProcessingEnabled
&& autocompletionContextAwareEnabled == that.autocompletionContextAwareEnabled
&& Objects.equals(commitMessagePrompt, that.commitMessagePrompt)
&& Objects.equals(tableData, that.tableData);
}
@Override
public int hashCode() {
return Objects.hash(commitMessagePrompt, maxTokens, temperature,
checkForPluginUpdates, checkForNewScreenshots, createNewChatOnEachAction,
ignoreGitCommitTokenLimit, methodNameGenerationEnabled, captureCompileErrors,
autoFormattingEnabled, autocompletionPostProcessingEnabled,
autocompletionContextAwareEnabled, tableData);
}
}

View file

@ -38,7 +38,7 @@ public final class ChatToolWindowContentManager {
public void sendMessage(Message message, ConversationType conversationType) {
getToolWindow().show();
if (ConfigurationSettings.getCurrentState().isCreateNewChatOnEachAction()
if (ConfigurationSettings.getState().getCreateNewChatOnEachAction()
|| ConversationsState.getCurrentConversation() == null) {
createNewTabPanel().sendMessage(message, conversationType);
return;
@ -113,11 +113,11 @@ public final class ChatToolWindowContentManager {
var toolWindow = toolWindowManager.getToolWindow("CodeGPT");
// https://intellij-support.jetbrains.com/hc/en-us/community/posts/11533368171026/comments/11538403084562
return Objects.requireNonNullElseGet(toolWindow, () -> toolWindowManager
.registerToolWindow(RegisterToolWindowTask.closable(
"CodeGPT",
() -> "CodeGPT",
Icons.DefaultSmall,
ToolWindowAnchor.RIGHT)));
.registerToolWindow(RegisterToolWindowTask.closable(
"CodeGPT",
() -> "CodeGPT",
Icons.DefaultSmall,
ToolWindowAnchor.RIGHT)));
}
private Optional<Content> tryFindFirstChatTabContent() {

View file

@ -138,7 +138,7 @@ public class OverlayUtil {
@Override
public void rememberChoice(boolean isSelected, int exitCode) {
if (isSelected) {
ConfigurationSettings.getCurrentState().setIgnoreGitCommitTokenLimit(true);
ConfigurationSettings.getState().setIgnoreGitCommitTokenLimit(true);
}
}