feat: add support for placeholders in prompts (#458)

* fixes #432 adds support for Placeholders in Prompts

- activate gradle plugin Git4Idea
- adds PlaceholderUtil
- adds DATE_ISO_8601 PlaceholderReplacer
- adds BRANCH_NAME PlaceholderReplacer

* convert to kotlin, improve ui and add int. test

* fix: do not reuse projects from previous test runs

---------

Co-authored-by: Carl-Robert Linnupuu <carlrobertoh@gmail.com>
This commit is contained in:
René 2024-04-17 10:41:21 +02:00 committed by GitHub
parent f6a5113216
commit 2221d72430
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 204 additions and 44 deletions

View file

@ -28,6 +28,7 @@ import ee.carlrobert.codegpt.EncodingManager;
import ee.carlrobert.codegpt.Icons;
import ee.carlrobert.codegpt.completions.CompletionRequestService;
import ee.carlrobert.codegpt.settings.GeneralSettings;
import ee.carlrobert.codegpt.settings.configuration.CommitMessageTemplate;
import ee.carlrobert.codegpt.ui.OverlayUtil;
import ee.carlrobert.llm.client.openai.completion.ErrorDetails;
import ee.carlrobert.llm.completion.CompletionEventListener;
@ -94,7 +95,10 @@ public class GenerateGitCommitMessageAction extends AnAction {
if (editor != null) {
((EditorEx) editor).setCaretVisible(false);
CompletionRequestService.getInstance()
.generateCommitMessageAsync(gitDiff, getEventListener(project, editor.getDocument()));
.generateCommitMessageAsync(
project.getService(CommitMessageTemplate.class).getSystemPrompt(),
gitDiff,
getEventListener(project, editor.getDocument()));
}
}

View file

@ -1,6 +1,5 @@
package ee.carlrobert.codegpt.completions;
import static ee.carlrobert.codegpt.completions.ConversationType.DEFAULT;
import static ee.carlrobert.codegpt.completions.ConversationType.FIX_COMPILE_ERRORS;
import static ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.CUSTOM_SERVICE_API_KEY;
import static ee.carlrobert.codegpt.util.file.FileUtil.getResourceContent;
@ -59,7 +58,6 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -77,8 +75,6 @@ public class CompletionRequestProvider {
public static final String FIX_COMPILE_ERRORS_SYSTEM_PROMPT = getResourceContent(
"/prompts/fix-compile-errors.txt");
private static final Set<ConversationType> OPENAI_SYSTEM_CONVERSATION_TYPES = Set.of(
DEFAULT, FIX_COMPILE_ERRORS);
private final EncodingManager encodingManager = EncodingManager.getInstance();
private final Conversation conversation;
@ -157,7 +153,7 @@ public class CompletionRequestProvider {
}
var systemPrompt = conversationType == FIX_COMPILE_ERRORS
? FIX_COMPILE_ERRORS_SYSTEM_PROMPT : ConfigurationSettings.getSystemPrompt();
? FIX_COMPILE_ERRORS_SYSTEM_PROMPT : ConfigurationSettings.getSystemPrompt();
var prompt = promptTemplate.buildPrompt(
systemPrompt,
@ -287,10 +283,13 @@ public class CompletionRequestProvider {
private List<OpenAIChatCompletionMessage> buildMessages(CallParameters callParameters) {
var message = callParameters.getMessage();
var messages = new ArrayList<OpenAIChatCompletionMessage>();
if (OPENAI_SYSTEM_CONVERSATION_TYPES.contains(callParameters.getConversationType())) {
String content = DEFAULT == callParameters.getConversationType()
? ConfigurationSettings.getSystemPrompt() : FIX_COMPILE_ERRORS_SYSTEM_PROMPT;
messages.add(new OpenAIChatCompletionStandardMessage("system", content));
if (callParameters.getConversationType() == ConversationType.DEFAULT) {
String systemPrompt = ConfigurationSettings.getCurrentState().getSystemPrompt();
messages.add(new OpenAIChatCompletionStandardMessage("system", systemPrompt));
}
if (callParameters.getConversationType() == ConversationType.FIX_COMPILE_ERRORS) {
messages.add(
new OpenAIChatCompletionStandardMessage("system", FIX_COMPILE_ERRORS_SYSTEM_PROMPT));
}
for (var prevMessage : conversation.getMessages()) {

View file

@ -93,7 +93,6 @@ public final class CompletionRequestService {
callParameters.getMessage(),
callParameters.getConversationType()),
eventListener);
default -> throw new IllegalArgumentException();
};
}
@ -115,13 +114,13 @@ public final class CompletionRequestService {
}
public void generateCommitMessageAsync(
String prompt,
String systemPrompt,
String gitDiff,
CompletionEventListener<String> eventListener) {
var configuration = ConfigurationSettings.getCurrentState();
var commitMessagePrompt = configuration.getCommitMessagePrompt();
var openaiRequest = new OpenAIChatCompletionRequest.Builder(List.of(
new OpenAIChatCompletionStandardMessage("system", commitMessagePrompt),
new OpenAIChatCompletionStandardMessage("user", prompt)))
new OpenAIChatCompletionStandardMessage("system", systemPrompt),
new OpenAIChatCompletionStandardMessage("user", gitDiff)))
.setModel(OpenAISettings.getCurrentState().getModel())
.build();
var selectedService = GeneralSettings.getCurrentState().getSelectedService();
@ -134,18 +133,18 @@ public final class CompletionRequestService {
var httpClient = CompletionClientProvider.getDefaultClientBuilder().build();
EventSources.createFactory(httpClient).newEventSource(
CompletionRequestProvider.buildCustomOpenAICompletionRequest(
commitMessagePrompt,
prompt),
systemPrompt,
gitDiff),
new OpenAIChatCompletionEventSourceListener(eventListener));
break;
case ANTHROPIC:
var anthropicSettings = AnthropicSettings.getCurrentState();
var claudeRequest = new ClaudeCompletionRequest();
claudeRequest.setSystem(commitMessagePrompt);
claudeRequest.setSystem(systemPrompt);
claudeRequest.setStream(true);
claudeRequest.setMaxTokens(configuration.getMaxTokens());
claudeRequest.setModel(anthropicSettings.getModel());
claudeRequest.setMessages(List.of(new ClaudeCompletionStandardMessage("user", prompt)));
claudeRequest.setMessages(List.of(new ClaudeCompletionStandardMessage("user", gitDiff)));
CompletionClientProvider.getClaudeClient()
.getCompletionAsync(claudeRequest, eventListener);
break;
@ -164,7 +163,7 @@ public final class CompletionRequestService {
} else {
promptTemplate = settings.getRemoteModelPromptTemplate();
}
var finalPrompt = promptTemplate.buildPrompt(commitMessagePrompt, prompt, List.of());
var finalPrompt = promptTemplate.buildPrompt(systemPrompt, gitDiff, List.of());
CompletionClientProvider.getLlamaClient().getChatCompletionAsync(
new LlamaCompletionRequest.Builder(finalPrompt)
.setN_predict(configuration.getMaxTokens())

View file

@ -16,7 +16,6 @@ import com.intellij.ui.TitledSeparator;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBTextArea;
import com.intellij.ui.components.JBTextField;
import com.intellij.ui.components.fields.IntegerField;
import com.intellij.ui.table.JBTable;
@ -29,6 +28,7 @@ import ee.carlrobert.codegpt.ui.UIUtil;
import java.awt.Dimension;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
@ -93,7 +93,7 @@ public class ConfigurationComponent {
maxTokensField.setColumns(12);
maxTokensField.setValue(configuration.getMaxTokens());
systemPromptTextArea = new JTextArea();
systemPromptTextArea = new JTextArea(3, 60);
if (configuration.getSystemPrompt().isBlank()) {
// for backward compatibility
systemPromptTextArea.setText(COMPLETION_SYSTEM_PROMPT);
@ -101,13 +101,12 @@ public class ConfigurationComponent {
systemPromptTextArea.setText(configuration.getSystemPrompt());
}
systemPromptTextArea.setLineWrap(true);
systemPromptTextArea.setWrapStyleWord(true);
systemPromptTextArea.setBorder(JBUI.Borders.empty(8, 4));
systemPromptTextArea.setColumns(60);
systemPromptTextArea.setRows(3);
commitMessagePromptTextArea = new JBTextArea(configuration.getCommitMessagePrompt(),
3, 60);
commitMessagePromptTextArea = new JTextArea(configuration.getCommitMessagePrompt(), 3, 60);
commitMessagePromptTextArea.setLineWrap(true);
commitMessagePromptTextArea.setWrapStyleWord(true);
commitMessagePromptTextArea.setBorder(JBUI.Borders.empty(8, 4));
checkForPluginUpdatesCheckBox = new JBCheckBox(
@ -247,20 +246,19 @@ public class ConfigurationComponent {
}
private JPanel createCommitMessageConfigurationForm() {
var formBuilder = FormBuilder.createFormBuilder();
addAssistantFormLabeledComponent(
formBuilder,
"configurationConfigurable.section.commitMessage.systemPromptField.label",
"configurationConfigurable.section.commitMessage.systemPromptField.comment",
JBUI.Panels
.simplePanel(commitMessagePromptTextArea)
.withBorder(JBUI.Borders.customLine(
JBUI.CurrentTheme.CustomFrameDecorations.separatorForeground())));
formBuilder.addVerticalGap(8);
var form = formBuilder.getPanel();
form.setBorder(JBUI.Borders.emptyLeft(16));
return form;
return FormBuilder.createFormBuilder()
.setFormLeftIndent(16)
.addLabeledComponent(
new JBLabel(CodeGPTBundle.get(
"configurationConfigurable.section.commitMessage.systemPromptField.label"))
.withBorder(JBUI.Borders.emptyLeft(2)),
UI.PanelFactory.panel(commitMessagePromptTextArea)
.resizeX(false)
.withComment(CommitMessageTemplate.Companion.getHtmlDescription())
.createPanel(),
true
)
.getPanel();
}
private ComponentValidator createTemperatureInputValidator(