Skip to content

Commit

Permalink
Merge pull request #391 from samkerr4coding/feat/issue-196
Browse files Browse the repository at this point in the history
Feat/issue 196
  • Loading branch information
stephanj authored Dec 16, 2024
2 parents 6ed3c0b + 8419aa7 commit c403375
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 40 deletions.
10 changes: 3 additions & 7 deletions src/main/java/com/devoxx/genie/model/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ private Constant() {
public static final String SYSTEM_PROMPT = """
You are a software developer IDEA plugin with expert knowledge in any programming language.
The Devoxx Genie plugin supports the following commands:
/test: write unit tests on selected code
/explain: explain the selected code
/review: review selected code
/help: show commands
The Devoxx Genie is open source and available at https://github.com/devoxx/DevoxxGenieIDEAPlugin.
You can follow us on Bluesky @ https://bsky.app/profile/devoxxgenie.bsky.social.
Do not include any more info which might be incorrect, like discord, documentation or other websites.
Expand All @@ -27,13 +21,15 @@ private Constant() {
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.";
public static final String TDG_PROMPT = "You are a professional Java developer. Give me a SINGLE FILE COMPLETE java implementation that will pass this test. Do not respond with a test. Give me only complete code and no snippets. Include imports and use the right package.";
public static final String FIND_PROMPT = "Perform semantic search on the project files using RAG and show matching files.";
public static final String FIND_PROMPT = "Perform semantic search on the project files using RAG and show matching files. (NOTE: The /find command requires RAG to be enabled in settings)";
public static final String HELP_PROMPT = "Display help and available commands for the Genie Devoxx Plugin";

public static final String TEST_COMMAND = "test";
public static final String FIND_COMMAND = "find";
public static final String REVIEW_COMMAND = "review";
public static final String EXPLAIN_COMMAND = "explain";
public static final String TDG_COMMAND = "tdg";
public static final String HELP_COMMAND = "help";

// The Local LLM Model URLs, these can be overridden in the settings page
public static final String OLLAMA_MODEL_URL = "http://localhost:11434/";
Expand Down
35 changes: 23 additions & 12 deletions src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;

import static com.devoxx.genie.model.Constant.FIND_COMMAND;
import static com.devoxx.genie.model.Constant.HELP_COMMAND;

public class ChatPromptExecutor {

Expand Down Expand Up @@ -183,10 +185,25 @@ public void stopPromptExecution(Project project) {
private Optional<String> getCommandFromPrompt(@NotNull ChatMessageContext chatMessageContext,
PromptOutputPanel promptOutputPanel) {
String prompt = chatMessageContext.getUserPrompt().trim();
if (prompt.startsWith("/")) {
DevoxxGenieSettingsService settings = DevoxxGenieStateService.getInstance();
DevoxxGenieSettingsService settings = DevoxxGenieStateService.getInstance();
List<CustomPrompt> customPrompts = settings.getCustomPrompts();

Optional<CustomPrompt> matchingPrompt = customPrompts.stream()
.filter(customPrompt ->
prompt.equalsIgnoreCase("/" + customPrompt.getName())
)
.findFirst();

// if OK
if (matchingPrompt.isPresent()) {
// Check if the prompt is "/help" --> we display the help
if (matchingPrompt.get().getName().equalsIgnoreCase(HELP_COMMAND)) {
promptOutputPanel.showHelpText();
return Optional.empty(); // Return empty since we handled the help case
}

if (prompt.toLowerCase().startsWith("/" + FIND_COMMAND + " ")) {
// Check for the /find command
if (matchingPrompt.get().getName().equalsIgnoreCase(FIND_COMMAND)) {
if (Boolean.FALSE.equals(DevoxxGenieStateService.getInstance().getRagEnabled())) {
NotificationUtil.sendNotification(chatMessageContext.getProject(),
"The /find command requires RAG to be enabled in settings");
Expand All @@ -196,15 +213,9 @@ private Optional<String> getCommandFromPrompt(@NotNull ChatMessageContext chatMe
return Optional.of(prompt.substring(6).trim());
}

// Check for custom prompts
for (CustomPrompt customPrompt : settings.getCustomPrompts()) {
if (prompt.equalsIgnoreCase("/" + customPrompt.getName())) {
chatMessageContext.setCommandName(customPrompt.getName());
return Optional.of(customPrompt.getPrompt());
}
}
promptOutputPanel.showHelpText();
return Optional.empty();
// Set the command name and return the prompt
chatMessageContext.setCommandName(matchingPrompt.get().getName());
return Optional.of(matchingPrompt.get().getPrompt());
}
return Optional.of(prompt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.util.ArrayList;
import java.util.List;

import static com.devoxx.genie.model.Constant.*;

public class CommandAutoCompleteTextField extends JBTextArea implements CustomPromptChangeListener {

private static final Logger LOG = Logger.getInstance(CommandAutoCompleteTextField.class);
Expand All @@ -46,11 +48,11 @@ public CommandAutoCompleteTextField(Project project) {

private void initializeCommands() {
commands.clear();
commands.add("/test");
commands.add("/explain");
commands.add("/review");
commands.add("/tdg");
commands.add("/help");
commands.add("/" + TEST_COMMAND);
commands.add("/" + EXPLAIN_COMMAND);
commands.add("/" + REVIEW_COMMAND);
commands.add("/" + TDG_COMMAND);
commands.add("/" + HELP_COMMAND);

DevoxxGenieSettingsService stateService = DevoxxGenieStateService.getInstance();
for (CustomPrompt customPrompt : stateService.getCustomPrompts()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ public static DevoxxGenieStateService getInstance() {

private List<CustomPrompt> customPrompts = new ArrayList<>();

private final List<CustomPrompt> defaultPrompts = Arrays.asList(
new CustomPrompt(TEST_COMMAND, TEST_PROMPT),
new CustomPrompt(EXPLAIN_COMMAND, EXPLAIN_PROMPT),
new CustomPrompt(REVIEW_COMMAND, REVIEW_PROMPT),
new CustomPrompt(TDG_COMMAND, TDG_PROMPT),
new CustomPrompt(FIND_COMMAND, FIND_PROMPT),
new CustomPrompt(HELP_COMMAND, HELP_PROMPT)
);

private List<LanguageModel> languageModels = new ArrayList<>();

private Boolean showExecutionTime = true;
Expand Down Expand Up @@ -160,16 +169,13 @@ public static DevoxxGenieStateService getInstance() {
private List<Runnable> loadListeners = new ArrayList<>();

public DevoxxGenieStateService() {
initializeDefaultPrompts();
initializeUserPrompt();
}

private void initializeDefaultPrompts() {
if (customPrompts.isEmpty()) {
customPrompts.add(new CustomPrompt(TEST_COMMAND, TEST_PROMPT));
customPrompts.add(new CustomPrompt(EXPLAIN_COMMAND, EXPLAIN_PROMPT));
customPrompts.add(new CustomPrompt(REVIEW_COMMAND, REVIEW_PROMPT));
customPrompts.add(new CustomPrompt(FIND_COMMAND, FIND_PROMPT));
customPrompts.add(new CustomPrompt(TDG_COMMAND, TDG_PROMPT));
private void initializeUserPrompt() {
//If User prompt happens to be empty then we load the default list
if (customPrompts == null || customPrompts.isEmpty()) {
customPrompts = new ArrayList<>(defaultPrompts);
}
}

Expand All @@ -182,7 +188,7 @@ public DevoxxGenieStateService getState() {
public void loadState(@NotNull DevoxxGenieStateService state) {
XmlSerializerUtil.copyBean(state, this);
initializeDefaultCostsIfEmpty();
initializeDefaultPrompts();
initializeUserPrompt();

// Notify all listeners that the state has been loaded
for (Runnable listener : loadListeners) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class PromptSettingsComponent extends AbstractSettingsComponent {
private static final int NAME_COLUMN = 0;
private static final int PROMPT_COLUMN = 1;


private final DevoxxGenieStateService settings;
@Getter
private final JTextArea systemPromptField = new JTextArea(stateService.getSystemPrompt());
@Getter
Expand All @@ -48,7 +50,7 @@ public boolean isCellEditable(int row, int column) {
public PromptSettingsComponent(Project project) {
this.project = project;

DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance();
settings = DevoxxGenieStateService.getInstance();

setupCustomPromptsTable();
setCustomPrompts(settings.getCustomPrompts());
Expand Down Expand Up @@ -88,6 +90,10 @@ public JPanel createPanel() {
removeCustomPromptBtn.addActionListener(e -> removeCustomPrompt());
buttonPanel.add(removeCustomPromptBtn);

JButton restoreDefaultCustomPromptBtn = new JButton("Restore Default Prompt");
restoreDefaultCustomPromptBtn.addActionListener(e -> restoreDefaultPrompts());
buttonPanel.add(restoreDefaultCustomPromptBtn);

gbc.gridy++;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
Expand Down Expand Up @@ -158,6 +164,10 @@ private void removeCustomPrompt() {
}
}

private void restoreDefaultPrompts() {
setCustomPrompts(settings.getDefaultPrompts());
}

public List<CustomPrompt> getCustomPrompts() {
int NAME_COLUMN = 0;
List<CustomPrompt> prompts = new ArrayList<>();
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/com/devoxx/genie/ui/util/HelpUtil.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.devoxx.genie.ui.util;

import com.devoxx.genie.ui.settings.DevoxxGenieStateService;
import com.intellij.ui.scale.JBUIScale;
import org.jetbrains.annotations.NotNull;

import java.util.stream.Collectors;

public class HelpUtil {
Expand All @@ -11,11 +11,44 @@ private HelpUtil() {
}

public static @NotNull String getHelpMessage() {
return "<html><body style='width: 300px; font-family: Arial, sans-serif; font-size: 12px;'>" +
"<h3>Available commands:</h3>" +
"<ul>" +
getCustomPromptCommands() +
"</ul></body></html>";
float scaleFactor = JBUIScale.scale(1f);
return """
<html>
<head>
<style type="text/css">
body {
font-family: 'Source Code Pro', monospace;
zoom: %s;
}
h2 {
margin-bottom: 5px;
}
p {
margin: 0;
}
ul {
margin-bottom: 5px;
}
li {
margin-bottom: 5px;
}
</style>
</head>
<body>
<h3>Available commands:</h3>
<ul>
%s
</ul>
<h3>
The Devoxx Genie is open source and available at https://github.com/devoxx/DevoxxGenieIDEAPlugin.
You can follow us on Bluesky @ https://bsky.app/profile/devoxxgenie.bsky.social.
Do not include any more info which might be incorrect, like discord, documentation or other websites.
</h3>
</body>
</html>
""".formatted(scaleFactor == 1.0f ? "normal" : scaleFactor * 100 + "%",
getCustomPromptCommands()
);
}

public static @NotNull String getCustomPromptCommands() {
Expand Down

0 comments on commit c403375

Please sign in to comment.