Skip to content

Commit

Permalink
Server configuration UX improved (#15)
Browse files Browse the repository at this point in the history
* Improving UX on server settings changes

* BaseServerConfigurable refactored

* Placeholder padding updated
  • Loading branch information
damiano1996 authored Dec 9, 2024
1 parent 28c28d4 commit a800bcd
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
Project project = anActionEvent.getProject();
if (project == null) return;

log.debug("Performing code completion action for project: {}", project.getName());
CodeCompletionService.getInstance(project).actionPerformed(anActionEvent);
}

Expand All @@ -24,7 +23,6 @@ public void beforeActionPerformed(@NotNull AnAction action, @NotNull AnActionEve
Project project = event.getProject();
if (project == null) return;

log.debug("Performing code completion action for project: {}", project.getName());
CodeCompletionService.getInstance(project).beforeActionPerformed(action, event);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.github.damiano1996.jetbrains.incoder.language.model.client.prompt.PromptType;
import com.github.damiano1996.jetbrains.incoder.language.model.server.LanguageModelServer;
import com.github.damiano1996.jetbrains.incoder.language.model.server.ServerFactoryUtils;
import com.github.damiano1996.jetbrains.incoder.language.model.server.ServerSettings;
import com.github.damiano1996.jetbrains.incoder.settings.PluginSettings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.Service;
Expand Down Expand Up @@ -39,15 +40,24 @@ public static LanguageModelService getInstance(@NotNull Project project) {
}

public void init() throws LanguageModelException {
log.debug("Initializing {}...", LanguageModelService.class.getSimpleName());
init(
ServerFactoryUtils.findByName(
ServerSettings.getInstance().getState().activeServerName)
.createServer());
}

var serverName = ChatSettings.getInstance().getState().serverName;
public void init(LanguageModelServer server) throws LanguageModelException {
log.debug("Initializing {}...", LanguageModelService.class.getSimpleName());

server = ServerFactoryUtils.findByName(serverName).createServer();
this.server = server;

client = server.createClient();
client = this.server.createClient();
log.debug("Client created successfully!");

log.debug("Verifying server connection.");
client.checkServerConnection();
log.debug("Server connection verified.");

PluginSettings.getInstance().getState().isPluginConfigured = true;
log.debug("Client and server started. Plugin can be considered configured.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ public void loadState(@NotNull State state) {

@ToString
public static class State {
public String serverName = "";

public int maxMessages = 10;

public String systemMessageInstructionsWithCode =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.github.damiano1996.jetbrains.incoder.language.model.client.chat.settings;

import com.github.damiano1996.jetbrains.incoder.language.model.server.ServerFactory;
import com.github.damiano1996.jetbrains.incoder.language.model.server.ServerFactoryUtils;
import com.github.damiano1996.jetbrains.incoder.ui.components.DescriptionLabel;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBTextArea;
Expand All @@ -15,21 +12,11 @@
public class ChatSettingsComponent {

private final JPanel mainPanel;
private final ComboBox<String> serverTypeComboBox;
private final JSpinner maxMessages;
private final JBTextArea systemMessageInstructionsWithCodeField;
private final JBTextArea systemMessageInstructionsField;

public ChatSettingsComponent() {

serverTypeComboBox =
new ComboBox<>(
ServerFactoryUtils.getServerFactories().stream()
.map(ServerFactory::getName)
.toList()
.toArray(new String[0]));
serverTypeComboBox.addItem("");

SpinnerNumberModel maxMessagesModel = new SpinnerNumberModel(10, 0, 50, 1);
maxMessages = new JSpinner(maxMessagesModel);

Expand All @@ -44,13 +31,6 @@ public ChatSettingsComponent() {
mainPanel =
FormBuilder.createFormBuilder()
.setFormLeftIndent(20)
.addLabeledComponent(
new JBLabel("Server type:"), serverTypeComboBox, 1, false)
.addComponent(
new DescriptionLabel(
"Select the server to be used for interaction with language"
+ " models."))
.addVerticalGap(20)
.addLabeledComponent(new JBLabel("Max messages:"), maxMessages, 1, false)
.addComponent(new DescriptionLabel("Number of messages to keep in memory."))
.addVerticalGap(20)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package com.github.damiano1996.jetbrains.incoder.language.model.client.chat.settings;

import com.github.damiano1996.jetbrains.incoder.language.model.LanguageModelException;
import com.github.damiano1996.jetbrains.incoder.language.model.LanguageModelService;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import java.util.Objects;
import javax.swing.*;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
Expand Down Expand Up @@ -46,8 +41,7 @@ public JComponent createComponent() {
public boolean isModified() {
var state = getState();

return !chatSettingsComponent.getServerTypeComboBox().getItem().equals(state.serverName)
|| !chatSettingsComponent.getMaxMessages().getValue().equals(state.maxMessages)
return !chatSettingsComponent.getMaxMessages().getValue().equals(state.maxMessages)
|| !chatSettingsComponent
.getSystemMessageInstructionsWithCodeField()
.getText()
Expand All @@ -59,30 +53,20 @@ public boolean isModified() {
}

@Override
public void apply() throws ConfigurationException {
public void apply() {
var state = getState();

state.serverName = chatSettingsComponent.getServerTypeComboBox().getItem();
state.maxMessages = (int) chatSettingsComponent.getMaxMessages().getValue();
state.systemMessageInstructionsWithCode =
chatSettingsComponent.getSystemMessageInstructionsWithCodeField().getText();
state.systemMessageInstructions =
chatSettingsComponent.getSystemMessageInstructionsField().getText();

try {
LanguageModelService.getInstance(Objects.requireNonNull(ProjectUtil.getActiveProject()))
.init();
} catch (LanguageModelException e) {
throw new ConfigurationException(
e.getMessage(), "Unable to Initialize the Language Model Service");
}
}

@Override
public void reset() {
var state = getState();

chatSettingsComponent.getServerTypeComboBox().setItem(state.serverName);
chatSettingsComponent.getMaxMessages().setValue(state.maxMessages);
chatSettingsComponent
.getSystemMessageInstructionsWithCodeField()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.github.damiano1996.jetbrains.incoder.language.model.server;

import com.github.damiano1996.jetbrains.incoder.language.model.LanguageModelException;
import com.github.damiano1996.jetbrains.incoder.language.model.LanguageModelService;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.ThrowableComputable;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;

@Slf4j
Expand All @@ -20,35 +24,70 @@ public abstract class BaseServerConfigurable implements Configurable {

@Override
public final void apply() throws ConfigurationException {
updateState();

var serverName = getServerFactory().getName();

if (ServerSettings.getInstance().getState().activeServerName.equals(serverName)) {
log.debug(
"{} is already the active server. Just restarting the Language Model"
+ " Service...",
serverName);
restartLanguageModelService(serverName);
return;
}

log.debug("{} is not the active server. Showing the dialog to the user...", serverName);
showDialogToSetThisAsDefaultServer(serverName);
}

private void showDialogToSetThisAsDefaultServer(String serverName)
throws ConfigurationException {
//noinspection DialogTitleCapitalization
int result =
Messages.showYesNoDialog(
"Do you want to set %s as the default server?".formatted(serverName),
"Set %s as Default".formatted(serverName),
Messages.getQuestionIcon());

if (result == Messages.YES) {
log.info("User chose to set {} as default.", serverName);
ServerSettings.getInstance().getState().activeServerName = getServerFactory().getName();

restartLanguageModelService(serverName);

} else {
log.info("User chose not to set {} as default.", serverName);
}
}

private void restartLanguageModelService(String serverName) throws ConfigurationException {
//noinspection DialogTitleCapitalization
ProgressManager.getInstance()
.runProcessWithProgressSynchronously(
(ThrowableComputable<Void, ConfigurationException>)
() -> {
updateState();
verifySettings();
return null;
try {
log.debug("Restarting Language Model Service");
LanguageModelService.getInstance(
Objects.requireNonNull(
ProjectUtil.getActiveProject()))
.init(getServerFactory().createServer());
return null;
} catch (LanguageModelException e) {
//noinspection DialogTitleCapitalization
throw new ConfigurationException(
e.getMessage(),
"Unable to Initialize the Language Model Service with New Settings for %s"
.formatted(serverName));
}
},
"Verifying %s Settings".formatted(getDisplayName()),
"Restarting the Language Model Service with the New Settings for %s"
.formatted(getDisplayName()),
false,
null);
}

/** Updates the server state based on the current configuration. */
protected abstract void updateState();

/**
* Verifies the configured settings and throws a {@link ConfigurationException} if any issues
* are found.
*
* @throws ConfigurationException if the settings are invalid.
*/
private void verifySettings() throws ConfigurationException {
try {
log.debug("Creating server and client to verify configurations");
getServerFactory().createServer().createClient().checkServerConnection();
} catch (LanguageModelException e) {
throw new ConfigurationException(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.damiano1996.jetbrains.incoder.language.model.LanguageModelException;
import com.github.damiano1996.jetbrains.incoder.language.model.client.LanguageModelClient;
import java.util.List;
import org.jetbrains.annotations.NotNull;

public interface LanguageModelServer {

Expand All @@ -12,5 +13,6 @@ public interface LanguageModelServer {

String getSelectedModelName();

@NotNull
LanguageModelClient createClient() throws LanguageModelException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.github.damiano1996.jetbrains.incoder.language.model.server;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import lombok.Getter;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;

@Getter
@Service(Service.Level.APP)
@State(
name = "ServerSettings",
storages = {@Storage("InCoderSettings.xml")})
public final class ServerSettings implements PersistentStateComponent<ServerSettings.State> {

@NotNull private State state = new State();

public static ServerSettings getInstance() {
return ApplicationManager.getApplication().getService(ServerSettings.class);
}

@Override
public void loadState(@NotNull ServerSettings.State state) {
this.state = state;
}

@ToString
public static class State {
public String activeServerName = "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public AnthropicComponent() {
new AnthropicLanguageModelServer()
.getAvailableModels()
.toArray(new String[0]));
modelNameField.addItem("");
modelNameField.setPreferredSize(new Dimension(300, 30));

mainPanel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public OllamaComponent() {
new OllamaLanguageModelServer()
.getAvailableModels()
.toArray(new String[0]));
modelNameField.addItem("");
modelNameField.setPreferredSize(new Dimension(300, 30));

refreshButton = new JButton(AllIcons.Actions.Refresh);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,16 @@ public boolean isModified() {
var state = getState();

return !settingsComponent.getBaseUrlField().getText().equals(state.baseUrl)
|| !getModelName().equals(state.modelName)
|| !settingsComponent.getModelNameField().getItem().equals(state.modelName)
|| !settingsComponent.getTemperatureField().getValue().equals(state.temperature);
}

private @NotNull String getModelName() {
var selectedModelName = settingsComponent.getModelNameField().getItem();
return (selectedModelName == null) ? "" : selectedModelName;
}

@Override
public void updateState() {
var state = getState();

state.baseUrl = settingsComponent.getBaseUrlField().getText();
state.modelName = getModelName();
state.modelName = settingsComponent.getModelNameField().getItem();
state.temperature = (Double) settingsComponent.getTemperatureField().getValue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import lombok.Getter;
import lombok.ToString;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Getter
@Service(Service.Level.APP)
Expand All @@ -32,7 +31,7 @@ public void loadState(@NotNull State state) {
public static class State {

public String baseUrl = "http://localhost:11434/";
@Nullable public String modelName = null;
public String modelName = "";
public Double temperature = 0.2;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public OpenAiComponent() {
new OpenAiLanguageModelServer()
.getAvailableModels()
.toArray(new String[0]));
modelNameField.addItem("");
modelNameField.setPreferredSize(new Dimension(300, 30));

mainPanel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void createUIComponents() {
mainPanel = new JPanel();
mainPanel.setBackground(JBColor.namedColor("ToolWindow.background"));

prompt = new PlaceholderTextField("Enter a prompt...", 10, 6);
prompt = new PlaceholderTextField("Enter a prompt...", 12, 8);
generating = new JProgressBar();
isGenerating(false);
}
Expand Down
Loading

0 comments on commit a800bcd

Please sign in to comment.