feat: improved popup suggestions and personas support (#638)

* feat: support personas

* fix: replace previous system prompts with personas

* feat: add persona toolbar label

* refactor: rename properties

* refactor: clean up

* fix: personas settings configurable state

* refactor: code cleanup

* feat: list item auto highlightning

* feat: replace personas toolbar label with action link

* refactor: code cleanup

* fix: manual items not being able to delete

* fix: personas settings configurable state

* refactor: clean up code

* fix: folder selection
This commit is contained in:
Carl-Robert 2024-07-25 23:50:31 +03:00 committed by GitHub
parent db0df84a64
commit d68b356b42
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 4266 additions and 368 deletions

View file

@ -21,6 +21,7 @@ import ee.carlrobert.codegpt.conversations.message.Message;
import ee.carlrobert.codegpt.credentials.CredentialsStore;
import ee.carlrobert.codegpt.settings.IncludedFilesSettings;
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings;
import ee.carlrobert.codegpt.settings.persona.PersonaSettings;
import ee.carlrobert.codegpt.settings.service.anthropic.AnthropicSettings;
import ee.carlrobert.codegpt.settings.service.custom.CustomServiceChatCompletionSettingsState;
import ee.carlrobert.codegpt.settings.service.custom.CustomServiceSettings;
@ -71,9 +72,6 @@ import org.jetbrains.annotations.Nullable;
public class CompletionRequestProvider {
public static final String COMPLETION_SYSTEM_PROMPT =
getResourceContent("/prompts/default-completion.txt");
public static final String GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT =
getResourceContent("/prompts/generate-commit-message.txt");
@ -197,7 +195,7 @@ public class CompletionRequestProvider {
}
var systemPrompt = conversationType == FIX_COMPILE_ERRORS
? FIX_COMPILE_ERRORS_SYSTEM_PROMPT : ConfigurationSettings.getSystemPrompt();
? FIX_COMPILE_ERRORS_SYSTEM_PROMPT : PersonaSettings.getSystemPrompt();
var prompt = promptTemplate.buildPrompt(
systemPrompt,
@ -302,7 +300,7 @@ public class CompletionRequestProvider {
request.setModel(settings.getModel());
request.setMaxTokens(configuration.getMaxTokens());
request.setStream(true);
request.setSystem(ConfigurationSettings.getSystemPrompt());
request.setSystem(PersonaSettings.getSystemPrompt());
List<ClaudeCompletionMessage> messages = conversation.getMessages().stream()
.filter(prevMessage -> prevMessage.getResponse() != null
&& !prevMessage.getResponse().isEmpty())
@ -345,8 +343,8 @@ public class CompletionRequestProvider {
var message = callParameters.getMessage();
var messages = new ArrayList<OllamaChatCompletionMessage>();
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
String systemPrompt = ConfigurationSettings.getCurrentState().getSystemPrompt();
messages.add(new OllamaChatCompletionMessage("system", systemPrompt, null));
messages.add(
new OllamaChatCompletionMessage("system", PersonaSettings.getSystemPrompt(), null));
}
if (callParameters.getConversationType() == ConversationType.FIX_COMPILE_ERRORS) {
messages.add(
@ -397,8 +395,8 @@ public class CompletionRequestProvider {
var message = callParameters.getMessage();
var messages = new ArrayList<OpenAIChatCompletionMessage>();
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
String systemPrompt = ConfigurationSettings.getCurrentState().getSystemPrompt();
messages.add(new OpenAIChatCompletionStandardMessage("system", systemPrompt));
messages.add(
new OpenAIChatCompletionStandardMessage("system", PersonaSettings.getSystemPrompt()));
}
if (callParameters.getConversationType() == ConversationType.FIX_COMPILE_ERRORS) {
messages.add(
@ -474,8 +472,7 @@ public class CompletionRequestProvider {
// Gemini API does not support direct 'system' prompts:
// see https://www.reddit.com/r/Bard/comments/1b90i8o/does_gemini_have_a_system_prompt_option_while/
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
String systemPrompt = ConfigurationSettings.getCurrentState().getSystemPrompt();
messages.add(new GoogleCompletionContent("user", List.of(systemPrompt)));
messages.add(new GoogleCompletionContent("user", List.of(PersonaSettings.getSystemPrompt())));
messages.add(new GoogleCompletionContent("model", List.of("Understood.")));
}
if (callParameters.getConversationType() == ConversationType.FIX_COMPILE_ERRORS) {

View file

@ -1,7 +1,6 @@
package ee.carlrobert.codegpt.settings.configuration;
import static ee.carlrobert.codegpt.actions.editor.EditorActionsUtil.DEFAULT_ACTIONS_ARRAY;
import static ee.carlrobert.codegpt.completions.CompletionRequestProvider.COMPLETION_SYSTEM_PROMPT;
import com.intellij.icons.AllIcons;
import com.intellij.icons.AllIcons.Nodes;
@ -49,7 +48,6 @@ public class ConfigurationComponent {
private final JBCheckBox autoFormattingCheckBox;
private final JBCheckBox autocompletionPostProcessingCheckBox;
private final JBCheckBox autocompletionContextAwareCheckBox;
private final JTextArea systemPromptTextArea;
private final JTextArea commitMessagePromptTextArea;
private final IntegerField maxTokensField;
private final JBTextField temperatureField;
@ -94,17 +92,6 @@ public class ConfigurationComponent {
maxTokensField.setColumns(12);
maxTokensField.setValue(configuration.getMaxTokens());
systemPromptTextArea = new JTextArea(3, 60);
if (configuration.getSystemPrompt().isBlank()) {
// for backward compatibility
systemPromptTextArea.setText(COMPLETION_SYSTEM_PROMPT);
} else {
systemPromptTextArea.setText(configuration.getSystemPrompt());
}
systemPromptTextArea.setLineWrap(true);
systemPromptTextArea.setWrapStyleWord(true);
systemPromptTextArea.setBorder(JBUI.Borders.empty(8, 4));
commitMessagePromptTextArea = new JTextArea(configuration.getCommitMessagePrompt(), 3, 60);
commitMessagePromptTextArea.setLineWrap(true);
commitMessagePromptTextArea.setWrapStyleWord(true);
@ -164,7 +151,6 @@ public class ConfigurationComponent {
state.setTableData(getTableData());
state.setMaxTokens(maxTokensField.getValue());
state.setTemperature(Double.parseDouble(temperatureField.getText()));
state.setSystemPrompt(systemPromptTextArea.getText());
state.setCommitMessagePrompt(commitMessagePromptTextArea.getText());
state.setCheckForPluginUpdates(checkForPluginUpdatesCheckBox.isSelected());
state.setCheckForNewScreenshots(checkForNewScreenshotsCheckBox.isSelected());
@ -181,7 +167,6 @@ public class ConfigurationComponent {
setTableData(configuration.getTableData());
maxTokensField.setValue(configuration.getMaxTokens());
temperatureField.setText(String.valueOf(configuration.getTemperature()));
systemPromptTextArea.setText(configuration.getSystemPrompt());
commitMessagePromptTextArea.setText(configuration.getCommitMessagePrompt());
checkForPluginUpdatesCheckBox.setSelected(configuration.isCheckForPluginUpdates());
checkForNewScreenshotsCheckBox.setSelected(configuration.isCheckForNewScreenshots());
@ -242,15 +227,6 @@ public class ConfigurationComponent {
private JPanel createAssistantConfigurationForm() {
var formBuilder = FormBuilder.createFormBuilder();
addAssistantFormLabeledComponent(
formBuilder,
"configurationConfigurable.section.assistant.systemPromptField.label",
"configurationConfigurable.section.assistant.systemPromptField.comment",
JBUI.Panels
.simplePanel(systemPromptTextArea)
.withBorder(JBUI.Borders.customLine(
JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground())));
formBuilder.addVerticalGap(8);
addAssistantFormLabeledComponent(
formBuilder,
"configurationConfigurable.section.assistant.temperatureField.label",

View file

@ -31,8 +31,4 @@ public class ConfigurationSettings implements PersistentStateComponent<Configura
public static ConfigurationSettings getInstance() {
return ApplicationManager.getApplication().getService(ConfigurationSettings.class);
}
public static String getSystemPrompt() {
return getCurrentState().getSystemPrompt();
}
}

View file

@ -1,6 +1,5 @@
package ee.carlrobert.codegpt.settings.configuration;
import static ee.carlrobert.codegpt.completions.CompletionRequestProvider.COMPLETION_SYSTEM_PROMPT;
import static ee.carlrobert.codegpt.completions.CompletionRequestProvider.GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT;
import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil;
@ -9,7 +8,6 @@ import java.util.Objects;
public class ConfigurationState {
private String systemPrompt = COMPLETION_SYSTEM_PROMPT;
private String commitMessagePrompt = GENERATE_COMMIT_MESSAGE_SYSTEM_PROMPT;
private int maxTokens = 2048;
private double temperature = 0.1;
@ -24,18 +22,10 @@ public class ConfigurationState {
private boolean autocompletionContextAwareEnabled = false;
private Map<String, String> tableData = EditorActionsUtil.DEFAULT_ACTIONS;
public String getSystemPrompt() {
return systemPrompt;
}
public String getCommitMessagePrompt() {
return commitMessagePrompt;
}
public void setSystemPrompt(String systemPrompt) {
this.systemPrompt = systemPrompt;
}
public void setCommitMessagePrompt(String commitMessagePrompt) {
this.commitMessagePrompt = commitMessagePrompt;
}
@ -155,14 +145,13 @@ public class ConfigurationState {
&& autoFormattingEnabled == that.autoFormattingEnabled
&& autocompletionPostProcessingEnabled == that.autocompletionPostProcessingEnabled
&& autocompletionContextAwareEnabled == that.autocompletionContextAwareEnabled
&& Objects.equals(systemPrompt, that.systemPrompt)
&& Objects.equals(commitMessagePrompt, that.commitMessagePrompt)
&& Objects.equals(tableData, that.tableData);
}
@Override
public int hashCode() {
return Objects.hash(systemPrompt, commitMessagePrompt, maxTokens, temperature,
return Objects.hash(commitMessagePrompt, maxTokens, temperature,
checkForPluginUpdates, checkForNewScreenshots, createNewChatOnEachAction,
ignoreGitCommitTokenLimit, methodNameGenerationEnabled, captureCompileErrors,
autoFormattingEnabled, autocompletionPostProcessingEnabled,

View file

@ -7,8 +7,13 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultCompactActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Disposer;
@ -23,6 +28,8 @@ import ee.carlrobert.codegpt.actions.toolwindow.OpenInEditorAction;
import ee.carlrobert.codegpt.conversations.ConversationService;
import ee.carlrobert.codegpt.conversations.ConversationsState;
import ee.carlrobert.codegpt.settings.GeneralSettings;
import ee.carlrobert.codegpt.settings.persona.PersonaSettings;
import ee.carlrobert.codegpt.settings.persona.PersonasConfigurable;
import ee.carlrobert.codegpt.settings.service.ProviderChangeNotifier;
import ee.carlrobert.codegpt.settings.service.ServiceType;
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTUserDetailsNotifier;
@ -35,6 +42,7 @@ import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.jetbrains.annotations.NotNull;
@ -165,6 +173,8 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel {
new ClearChatWindowAction(() -> tabbedPane.resetCurrentlyActiveTabPanel(project)));
actionGroup.addSeparator();
actionGroup.add(new OpenInEditorAction());
actionGroup.addSeparator();
actionGroup.add(new SelectedPersonaActionLink(project));
var toolbar = ActionManager.getInstance()
.createActionToolbar("NAVIGATION_BAR_TOOLBAR", actionGroup, true);
@ -186,4 +196,47 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel {
.syncPublisher(IncludeFilesInContextNotifier.FILES_INCLUDED_IN_CONTEXT_TOPIC)
.filesIncluded(emptyList());
}
private static class SelectedPersonaActionLink extends DumbAwareAction implements
CustomComponentAction {
private final Project project;
SelectedPersonaActionLink(Project project) {
this.project = project;
}
@Override
@NotNull
public JComponent createCustomComponent(
@NotNull Presentation presentation,
@NotNull String place) {
var link = new ActionLink(getSelectedPersonaName(), (e) -> {
ShowSettingsUtil.getInstance()
.showSettingsDialog(project, PersonasConfigurable.class);
});
link.setExternalLinkIcon();
link.setFont(JBUI.Fonts.smallFont());
link.setBorder(JBUI.Borders.empty(0, 4));
return link;
}
@Override
public void updateCustomComponent(
@NotNull JComponent component,
@NotNull Presentation presentation) {
((ActionLink) component).setText(getSelectedPersonaName());
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
}
private String getSelectedPersonaName() {
return ApplicationManager.getApplication().getService(PersonaSettings.class)
.getState()
.getSelectedPersona()
.getName();
}
}
}

View file

@ -1,7 +1,7 @@
package ee.carlrobert.codegpt.toolwindow.chat.ui.textarea;
import ee.carlrobert.codegpt.EncodingManager;
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings;
import ee.carlrobert.codegpt.settings.persona.PersonaSettings;
public class TotalTokensDetails {
@ -12,7 +12,7 @@ public class TotalTokensDetails {
private int referencedFilesTokens;
public TotalTokensDetails(EncodingManager encodingManager) {
systemPromptTokens = encodingManager.countTokens(ConfigurationSettings.getSystemPrompt());
systemPromptTokens = encodingManager.countTokens(PersonaSettings.getSystemPrompt());
}
public int getSystemPromptTokens() {