diff --git a/src/main/java/com/devoxx/genie/model/Constant.java b/src/main/java/com/devoxx/genie/model/Constant.java index 2e7fde45..dcb8df05 100644 --- a/src/main/java/com/devoxx/genie/model/Constant.java +++ b/src/main/java/com/devoxx/genie/model/Constant.java @@ -6,6 +6,14 @@ private Constant() { } // The fixed command prompts + public static final String SYSTEM_PROMPT = """ + You are a software developer with expert knowledge in any programming language. + Always return the response in Markdown. + The Devoxx Genie plugin supports the following commands: /test: write unit tests on selected code\\n/explain: explain the selected code\\n/review: review selected code\\n/custom: set custom prompt in settings + The Devoxx Genie is open source and available at https://github.com/devoxx/DevoxxGenieIDEAPlugin. + Do not include any more info which might be incorrect, like discord, twitter, documentation or website info. Only provide info that is correct and relevant to the code or plugin. + """; + public static final String TEST_PROMPT = "Write a unit test for this code using JUnit."; public static final String REVIEW_PROMPT = "Review the selected code, can it be improved or are there any bugs?"; public static final String EXPLAIN_PROMPT = "Break down the code in simple terms to help a junior developer grasp its functionality."; diff --git a/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java b/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java index e76a3ad4..02e90b21 100644 --- a/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java +++ b/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java @@ -6,6 +6,7 @@ import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; +import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.data.message.UserMessage; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import org.jetbrains.annotations.NotNull; @@ -36,7 +37,7 @@ public void executePrompt(@NotNull ChatMessageContext chatMessageContext, new Task.Backgroundable(chatMessageContext.getProject(), "Working...", true) { @Override public void run(@NotNull ProgressIndicator progressIndicator) { - if (chatMessageContext.getContext().toLowerCase().contains("search")) { + if (chatMessageContext.getContext() != null && chatMessageContext.getContext().toLowerCase().contains("search")) { webSearchPrompt(chatMessageContext, promptOutputPanel, enableButtons); } else { if (SettingsStateService.getInstance().getStreamMode()) { @@ -99,7 +100,7 @@ private void setupStreaming(@NotNull ChatMessageContext chatMessageContext, MessageCreationService messageCreationService = MessageCreationService.getInstance(); if (chatMemoryService.isEmpty()) { - chatMemoryService.add(messageCreationService.createSystemMessage(chatMessageContext)); + chatMemoryService.add(new SystemMessage(SettingsStateService.getInstance().getSystemPrompt())); } UserMessage userMessage = messageCreationService.createUserMessage(chatMessageContext); diff --git a/src/main/java/com/devoxx/genie/service/MessageCreationService.java b/src/main/java/com/devoxx/genie/service/MessageCreationService.java index f8d0422b..11312829 100644 --- a/src/main/java/com/devoxx/genie/service/MessageCreationService.java +++ b/src/main/java/com/devoxx/genie/service/MessageCreationService.java @@ -1,20 +1,17 @@ package com.devoxx.genie.service; import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.model.request.EditorInfo; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.data.message.UserMessage; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import static com.devoxx.genie.action.AddSnippetAction.SELECTED_TEXT_KEY; @@ -24,17 +21,6 @@ */ public class MessageCreationService { - public static final String YOU_ARE_A_SOFTWARE_DEVELOPER_WITH_EXPERT_KNOWLEDGE_IN = - "You are a software developer with expert knowledge in "; - public static final String PROGRAMMING_LANGUAGE = " programming language."; - public static final String ALWAYS_RETURN_THE_RESPONSE_IN_MARKDOWN = - "Always return the response in Markdown."; - public static final String COMMANDS_INFO = - "The Devoxx Genie plugin supports the following commands: /test: write unit tests on selected code\n/explain: explain the selected code\n/review: review selected code\n/custom: set custom prompt in settings"; - public static final String MORE_INFO = - "The Devoxx Genie is open source and available at https://github.com/devoxx/DevoxxGenieIDEAPlugin."; - public static final String NO_HALLUCINATIONS = - "Do not include any more info which might be incorrect, like discord, twitter, documentation or website info. Only provide info that is correct and relevant to the code or plugin."; public static final String QUESTION = "Answer the user question: "; public static final String CONTEXT_PROMPT = "Question context: \n"; @@ -44,25 +30,6 @@ public static MessageCreationService getInstance() { return ApplicationManager.getApplication().getService(MessageCreationService.class); } - /** - * Create a system message. - * @param chatMessageContext the language text pair - * @return the system message - */ - public @NotNull SystemMessage createSystemMessage(@NotNull ChatMessageContext chatMessageContext) { - String language = Optional.ofNullable(chatMessageContext.getEditorInfo()) - .map(EditorInfo::getLanguage) - .orElse("programming"); - - return new SystemMessage( - YOU_ARE_A_SOFTWARE_DEVELOPER_WITH_EXPERT_KNOWLEDGE_IN + - language + PROGRAMMING_LANGUAGE + - ALWAYS_RETURN_THE_RESPONSE_IN_MARKDOWN + "\n" + - COMMANDS_INFO + "\n" + - MORE_INFO + "\n" + - NO_HALLUCINATIONS); - } - /** * Create a user message with context. * @param chatMessageContext the chat message context diff --git a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java index e6e1c71e..3ffebbac 100644 --- a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java +++ b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java @@ -4,6 +4,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.data.message.UserMessage; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.output.Response; @@ -48,7 +49,7 @@ static PromptExecutionService getInstance() { MessageCreationService messageCreationService = MessageCreationService.getInstance(); if (ChatMemoryService.getInstance().isEmpty()) { - ChatMemoryService.getInstance().add(messageCreationService.createSystemMessage(chatMessageContext)); + ChatMemoryService.getInstance().add(new SystemMessage(SettingsStateService.getInstance().getSystemPrompt())); } UserMessage userMessage = messageCreationService.createUserMessage(chatMessageContext); diff --git a/src/main/java/com/devoxx/genie/service/SettingsStateService.java b/src/main/java/com/devoxx/genie/service/SettingsStateService.java index 7653c8a3..3295595a 100644 --- a/src/main/java/com/devoxx/genie/service/SettingsStateService.java +++ b/src/main/java/com/devoxx/genie/service/SettingsStateService.java @@ -49,6 +49,7 @@ public static SettingsStateService getInstance() { private String tavilySearchKey = ""; // Prompt fields + private String systemPrompt = SYSTEM_PROMPT; private String testPrompt = TEST_PROMPT; private String reviewPrompt = REVIEW_PROMPT; private String explainPrompt = EXPLAIN_PROMPT; diff --git a/src/main/java/com/devoxx/genie/ui/DevoxxGenieSettingsManager.java b/src/main/java/com/devoxx/genie/ui/DevoxxGenieSettingsManager.java index d66998b4..b05e0c00 100644 --- a/src/main/java/com/devoxx/genie/ui/DevoxxGenieSettingsManager.java +++ b/src/main/java/com/devoxx/genie/ui/DevoxxGenieSettingsManager.java @@ -64,6 +64,7 @@ public class DevoxxGenieSettingsManager implements Configurable { private JCheckBox astReferenceFieldCheckBox; private JCheckBox astReferenceClassesCheckBox; + private JTextArea systemPromptField; private JTextArea testPromptField; private JTextArea explainPromptField; private JTextArea reviewPromptField; @@ -147,8 +148,9 @@ public JComponent createComponent() { googleCSIKeyField.setEnabled(!selected); }); - setTitle("Predefined Command Prompts", settingsPanel, gbc); + setTitle("The Prompts", settingsPanel, gbc); + systemPromptField = addTextAreaWithLabel(settingsPanel, gbc, "System prompt :", settings.getSystemPrompt()); testPromptField = addTextAreaWithLabel(settingsPanel, gbc, "Test prompt :", settings.getTestPrompt()); explainPromptField = addTextAreaWithLabel(settingsPanel, gbc, "Explain prompt :", settings.getExplainPrompt()); reviewPromptField = addTextAreaWithLabel(settingsPanel, gbc, "Review prompt :", settings.getReviewPrompt()); @@ -217,7 +219,7 @@ private void setTitle(String title, String value) { panel.add(new JLabel(label), gbc); gbc.gridx++; - JTextArea textArea = new JTextArea(value, 3, 80); + JTextArea textArea = new JTextArea(value, 3, 40); panel.add(textArea, gbc); resetGbc(gbc); return textArea; @@ -391,10 +393,10 @@ public boolean isModified() { isModified |= isFieldModified(retryField, settings.getMaxRetries()); isModified |= isFieldModified(chatMemorySizeField, settings.getChatMemorySize()); + isModified |= !StringUtil.equals(systemPromptField.getText(), settings.getSystemPrompt()); isModified |= !StringUtil.equals(testPromptField.getText(), settings.getTestPrompt()); isModified |= !StringUtil.equals(explainPromptField.getText(), settings.getExplainPrompt()); isModified |= !StringUtil.equals(reviewPromptField.getText(), settings.getReviewPrompt()); - isModified |= !StringUtil.equals(customPromptField.getText(), settings.getCustomPrompt()); isModified |= isFieldModified(openAiKeyField, settings.getOpenAIKey()); @@ -455,6 +457,7 @@ public void apply() { updateSettingIfModified(retryField, settings.getMaxRetries(), value -> settings.setMaxRetries(safeCastToInteger(value))); updateSettingIfModified(maxOutputTokensField, settings.getMaxOutputTokens(), settings::setMaxOutputTokens); + updateTextAreaIfModified(systemPromptField, settings.getSystemPrompt(), settings::setSystemPrompt); updateTextAreaIfModified(testPromptField, settings.getTestPrompt(), settings::setTestPrompt); updateTextAreaIfModified(explainPromptField, settings.getExplainPrompt(), settings::setExplainPrompt); updateTextAreaIfModified(reviewPromptField, settings.getReviewPrompt(), settings::setReviewPrompt);