Giter Site home page Giter Site logo

devoxx / devoxxgenieideaplugin Goto Github PK

View Code? Open in Web Editor NEW
96.0 5.0 17.0 7.84 MB

DevoxxGenie is a plugin for IntelliJ IDEA that uses local LLM's (Ollama, LMStudio, GPT4All and Jan) and Cloud based LLMs to help review, test, explain your project code.

Home Page: https://devoxx.com

License: MIT License

Java 100.00%
anthropic assistant copilot gemini genai gpt4all groq intellij-plugin java llm

devoxxgenieideaplugin's Introduction

Devoxx Genie

X

Devoxx Genie is a fully Java-based LLM Code Assistant plugin for IntelliJ IDEA, designed to integrate with local LLM providers such as Ollama, LMStudio, GPT4All and Exo but also cloud based LLM's such as OpenAI, Anthropic, Mistral, Groq, Gemini and DeepInfra.

We now also support LLM-driven web search with Google and Tavily.

With Claude 3.5 Sonnet, DevoxxGenie isn't just another developer tool... it's a glimpse into the future of software engineering. As we eagerly await Claude 3.5 Opus, one thing is clear: we're witnessing a paradigm shift in Ai Augmented Programming (AAP) ๐Ÿ’

Marketplace

DevoxxGeniev0.1-p1-720p.mp4

Key Features:

  • ๐Ÿง  Project Scanner: Add source code (full project or by package) to prompt context when using Anthropic, OpenAI or Gemini.
  • ๐Ÿ’ฐ Token Cost Calculator: Calculate the cost when using Cloud LLM providers.
  • ๐Ÿ” Web Search : Search the web for a given query using Google or Tavily.
  • ๐ŸŽ๏ธ Streaming responses: See each token as it's received from the LLM in real-time.
  • ๐Ÿง Abstract Syntax Tree (AST) context: Automatically include parent class and class/field references in the prompt for better code analysis.
  • ๐Ÿ’ฌ Chat Memory Size: Set the size of your chat memory, by default its set to a total of 10 messages (system + user & AI msgs).
  • โ˜•๏ธ 100% Java: An IDEA plugin using local and cloud based LLM models. Fully developed in Java using Langchain4J
  • ๐Ÿ‘€ Code Highlighting: Supports highlighting of code blocks.
  • ๐Ÿ’ฌ Chat conversations: Supports chat conversations with configurable memory size.
  • ๐Ÿ“ Add files & code snippets to context: You can add open files to the chat window context for producing better answers or code snippets if you want to have a super focused window

See new features in action @ https://www.youtube.com/watch?v=7IJrKIS1eN8

GenieExample

We now support also streaming responses which you can enable in the Settings page ๐Ÿคฉ ๐Ÿš€

StreamingResponse.mp4

LLM Settings

In the IDEA settings you can modify the REST endpoints and the LLM parameters. Make sure to press enter and apply to save your changes.

We now also support Cloud based LLMs, you can paste the API keys on the Settings page.

DevoxxGenieSettings

Smart Model Selection and Cost Estimation

The language model dropdown is not just a list anymore, it's your compass for smart model selection.

Models

See available context window sizes for each cloud model View associated costs upfront Make data-driven decisions on which model to use for your project

Add Project to prompt & clipboard

You can now add the full project to your prompt IF your selected cloud LLM has a big enough window context.

AddFull

Calc Cost

Leverage the prompt cost calculator for precise budget management. Get real-time updates on how much of the context window you're using.

AddCalcProject

See the input/output costs and window context per Cloud LLM. Eventually we'll also allow you to edit these values.

Cost

Handling Massive Projects?

"But wait," you might say, "my project is HUGE!" ๐Ÿ˜…

Fear not! We've got options:

  1. Leverage Gemini's Massive Context:

Gemini's colossal 1 million token window isn't just big, it's massive. We're talking about the capacity to digest approximately 30,000 lines of code in a single go. That's enough to digest most codebases whole, from the tiniest scripts to some decent projects.

But if that's not enough you have more options...

  1. Smart Filtering:

The new "Copy Project" panel lets you:

Exclude specific directories Filter by file extensions Remove JavaDocs to slim down your context

Filter

  1. Selective Inclusion

Right-click to add only the most relevant parts of your project to the context.

RightClick

The Power of Full Context: A Real-World Example

The DevoxxGenie project itself, at about 70K tokens, fits comfortably within most high-end LLM context windows. This allows for incredibly nuanced interactions โ€“ we're talking advanced queries and feature requests that leave tools like GitHub Copilot scratching their virtual heads!

Local LLM Cluster with Exo

V0.2.7 also supports Exo, a local LLM cluster for Apple Silicon which allows you to run Llama 3.1 8b, 70b and 405b on your own Apple computers ๐Ÿคฉ

image

Installation:

  • From IntelliJ IDEA: Go to Settings -> Plugins -> Marketplace -> Enter 'Devoxx' to find plugin OR Install plugin from Disk
  • From Source Code: Clone the repository, build the plugin using ./gradlew buildPlugin, and install the plugin from the build/distributions directory and select file 'DevoxxGenie-X.Y.Z.zip'

Requirements:

  • IntelliJ minimum version is 2023.3.4
  • Java minimum version is JDK 17

Build

Gradle IntelliJ Plugin prepares a ZIP archive when running the buildPlugin task.
You'll find it in the build/distributions/ directory

./gradlew buildPlugin 

Publish plugin

It is recommended to use the publishPlugin task for releasing the plugin

./gradlew publishPlugin

Usage:

  1. Select an LLM provider from the DevoxxGenie panel (right corner)
  2. Select some code
  3. Enter shortcode command review, explain, generate unit tests of the selected code or enter a custom prompt.

Enjoy!

devoxxgenieideaplugin's People

Contributors

eltociear avatar stephanj avatar sunix avatar trautmannp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

devoxxgenieideaplugin's Issues

Introduce a "custom" command

Allow the developer to define a "/custom" command for which the prompt can be defined by developer

/custom "Custom prompt here"

Of course this should also be defined on the Settings page.

image

Support Web Search Queries

Now that Tavily and Google Search is available in Langchain4J, we can add Web Search in the plugin.
Let's start simple and allow a user prompt to trigger a web search when the related API keys are present.

Settings Changes don't get applied and persisted

Foremost: Great Plugin, and thanks for developing it!

Issue:
Changes inside the DevoxxGenie Settings Modal don't get applied and persisted

Reproduction:

  1. Open Settings โ†’ Devoxx Genie Settings
  2. Change Ollama URL to something else.
  3. Click โ€œOKโ€.

Description:
I'm using a self-hosted Ollama Instance on my Interference Server. When I tried to change the Ollama Base URL, I noticed that changes don't get applied. After restarting IDEA, I also noticed that changes don't get persisted.

I checked the source code and noticed that there is no usage of IDEA's State Services. I'm by far no experienced IntelliJ Plugin Developer, but I addressed the problem by following the IDEA suggestions. Furthermore, I will create a Pull Request in a few minutes for a review and further tests.

Feature: Support Tab auto completion

An experimental AcceptAutocompleteAction (pressing tab key) is available and can be activated be enabling the plugin config file

<actions> 
    <action id="com.devoxx.genie.action.AcceptAutocompleteAction"
            class="com.devoxx.genie.actions.AcceptAutocompleteAction"
            text="Accept Autocomplete Suggestion"
            description="Accept autocomplete suggestion">
        <keyboard-shortcut keymap="$default" first-keystroke="TAB"/>
        <keyboard-shortcut keymap="Mac OS X" first-keystroke="TAB"/>
        </action>
</actions>

However the related prompt does not really return useable auto complete code ๐Ÿ˜‚

/**
     * EXPERIMENTAL : Execute continue prompt
     * @param selectedText the selected text
     * @return the prompt
     */
    public String executeGenieContinuePrompt(String selectedText) {
        ChatLanguageModel chatLanguageModel = getChatLanguageModel();
        List<ChatMessage> messages = new ArrayList<>();
        messages.add(new dev.langchain4j.data.message.SystemMessage(
            YOU_ARE_A_SOFTWARE_DEVELOPER_WITH_EXPERT_KNOWLEDGE_IN + "JAVA" + PROGRAMMING_LANGUAGE +
                "\n\nSelected code: " + selectedText));
        messages.add(new UserMessage("Only return the code which finalises the code block."));
        Response<AiMessage> generate = chatLanguageModel.generate(messages);
        return generate.content().text();
    }

Suggestions welcome how we can accomplish this.

9 Compatibility problems

image

Package 'android.net' is not found

Package 'android.net' is not found (1 problem)
Package 'android.net' is not found along with its 2 classes.
Probably the package 'android.net' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'android.net' are not resolved:
Class X509TrustManagerExtensions is referenced in
AndroidCertificateChainCleaner.(...)
AndroidCertificateChainCleaner.clean(List, String)
AndroidCertificateChainCleaner.Companion.buildIfSupported(...)
AndroidCertificateChainCleaner.x509TrustManagerExtensions
Class SSLSockets is referenced in
Android10SocketAdapter.configureTlsExtensions(...)
Android10SocketAdapter.matchesSocket(SSLSocket)

Package 'android.os' is not found along with its 3 classes.

Probably the package 'android.os' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'android.os' are not resolved:
Class Build.VERSION is referenced in
Android10Platform.()
AndroidPlatform.()
AndroidPlatform.connectSocket(...)
AndroidPlatform.isCleartextTrafficPermitted(...)
Android10SocketAdapter.Companion.isSupported()
Platform.Android.()
Platform.Android.invokeDefaultMethod(...)
Class Handler is referenced in
Platform.Android.MainThreadExecutor.()
Platform.Android.MainThreadExecutor.execute(...)
Platform.Android.MainThreadExecutor.handler
Class Looper is referenced in
Platform.Android.MainThreadExecutor.()

Package 'android.security' is not found

Package 'android.security' is not found along with its class NetworkSecurityPolicy.
Probably the package 'android.security' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'android.security' are not resolved:
Class NetworkSecurityPolicy is referenced in
Android10Platform.isCleartextTrafficPermitted(...)
AndroidPlatform.isCleartextTrafficPermitted(...)

Package 'android.util' is not found

Package 'android.util' is not found along with its class Log.
Probably the package 'android.util' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'android.util' are not resolved:
Class Log is referenced in
AndroidLog.androidLog$okhttp(...)
AndroidLog.enableLogging(String, String)

Package 'org.bouncycastle.jsse' is not found

Package 'org.bouncycastle.jsse' is not found along with its 3 classes.
Probably the package 'org.bouncycastle.jsse' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'org.bouncycastle.jsse' are not resolved:
Class BCSSLSocket is referenced in
BouncyCastlePlatform.configureTlsExtensions(...)
BouncyCastlePlatform.getSelectedProtocol(...)
BouncyCastleSocketAdapter.configureTlsExtensions(...)
BouncyCastleSocketAdapter.getSelectedProtocol(...)
BouncyCastleSocketAdapter.matchesSocket(SSLSocket)
BouncyCastleSocketAdapter.Companion.factory$1.matchesSocket(...)
Class BCSSLParameters is referenced in
BouncyCastlePlatform.configureTlsExtensions(...)
BouncyCastleSocketAdapter.configureTlsExtensions(...)
Class BouncyCastleJsseProvider is referenced in
BouncyCastlePlatform.()

Package 'org.conscrypt' is not found

Package 'org.conscrypt' is not found along with its 3 classes.
Probably the package 'org.conscrypt' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'org.conscrypt' are not resolved:
Class Conscrypt is referenced in
ConscryptPlatform.()
ConscryptPlatform.()
ConscryptPlatform.Companion.atLeastVersion(...)
ConscryptSocketAdapter.configureTlsExtensions(...)
ConscryptSocketAdapter.Companion.factory$1.matchesSocket(...)
...and 5 other places...
Class ConscryptHostnameVerifier is referenced in
ConscryptPlatform.DisabledHostnameVerifier
ConscryptPlatform.platformTrustManager()
Class Conscrypt.Version is referenced in
ConscryptPlatform.Companion.atLeastVersion(...)

Package 'org.openjsse' is not found

Package 'org.openjsse' is not found along with its 3 classes.
Probably the package 'org.openjsse' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'org.openjsse' are not resolved:
Class SSLSocket is referenced in
OpenJSSEPlatform.configureTlsExtensions(...)
OpenJSSEPlatform.getSelectedProtocol(SSLSocket)
Class SSLParameters is referenced in
OpenJSSEPlatform.configureTlsExtensions(...)
Class OpenJSSE is referenced in
OpenJSSEPlatform.()

Package 'org.osgi' is not found

Package 'org.osgi' is not found along with its 6 classes.
Probably the package 'org.osgi' belongs to a library or dependency that is not resolved by the checker.
It is also possible, however, that this package was actually removed from a dependency causing the detected problems. Access to unresolved classes at runtime may lead to NoSuchClassError.
The following classes of 'org.osgi' are not resolved:
Class BundleContext is referenced in
OSGiExtensionLoader.context
OSGiExtensionLoader.start(BundleContext)
OSGiExtensionLoader.stop(BundleContext)
Class BundleActivator is referenced in
OSGiExtensionLoader
Class Filter is referenced in
OSGiExtensionLoader.getExtension(Class, String)
Class FrameworkUtil is referenced in
OSGiExtensionLoader.getExtension(Class, String)
Class InvalidSyntaxException is referenced in
OSGiExtensionLoader.getExtension(Class, String)
Class ServiceTracker is referenced in
OSGiExtensionLoader.getExtension(Class, String)

Abstract method TypeVariable.getAnnotatedBounds() is not implemented (1 problem)

Concrete class TypeVariableImpl inherits from TypeVariable but doesn't implement the abstract method getAnnotatedBounds(). This can lead to AbstractMethodError exception at runtime.

Externalise the fixed command prompts to Settings page

The fixed commands : explain, test and review uses currently hard coded prompts.
These must be moved to the Settings page so users can also customise these!

private void initializeCommands() {
        commandMap.put(COMMAND_HELP, listener::showHelp);

        commandMap.put(COMMAND_TEST,
            () -> listener.executePrompt("Write a unit test for this code using JUnit."));

        commandMap.put(COMMAND_REVIEW,
            () -> listener.executePrompt("Review the selected code, can it be improved or are there bugs?"));

        commandMap.put(COMMAND_EXPLAIN,
            () -> listener.executePrompt("Explain the code so a junior developer can understand it."));
    }

Should be

private void initializeCommands() {
        SettingsState settings = SettingsState.getInstance();

        commandMap.put(COMMAND_HELP, listener::showHelp);

        commandMap.put(COMMAND_TEST,
            () -> listener.executePrompt(settings.getCommandPrompt()));

        commandMap.put(COMMAND_REVIEW,
            () -> listener.executePrompt(settings.getReviewPrompt()));

        commandMap.put(COMMAND_EXPLAIN,
            () -> listener.executePrompt(settings.getExplainPrompt()));
    }

Set chat memory size in settings page

The ChatMemory is now set by default to 10 messages. However depending on which LLM you're using (looking at you Gemini) you might want to increase this.

Introduce chat memory

Depending on which LLM provider you use (size of window context), we can enable/disable chat memory.

automatic command completion

I hope to add the input box automatic command completion and carriage return confirmation function, so that the efficiency and experience will be good.

Introduce "Copy code" to clipboard

Currently when you copy & paste the output code there are no line breaks.
So having a "Copy to clipboard" icon above code would be a great feature.

Reduce complexity of DevoxxGenieToolWindowContent

Asked GPT-4o how to reduce the complexity of DevoxxGenieToolWindowContent because it obviously needs some extra refactoring love.

To reduce the complexity of the `DevoxxGenieToolWindowContent` class, we can break it down into smaller, more manageable components. This approach follows the single responsibility principle, where each class or method has one responsibility. Here's a refactored version of the class, split into multiple classes:

1. **UI Setup**: Create a separate class to handle the UI setup.
2. **Event Handlers**: Create separate classes or methods to handle events.
3. **Prompt Execution**: Create a class to handle prompt execution.

### Refactored Code

#### DevoxxGenieToolWindowContent.java

```java
package com.devoxx.genie.ui;

import com.devoxx.genie.service.PromptExecutionService;
import com.devoxx.genie.ui.listener.SettingsChangeListener;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.wm.ToolWindow;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.ResourceBundle;

public class DevoxxGenieToolWindowContent implements SettingsChangeListener {

    public static final String WORKING_MESSAGE = "working.message";

    private final Project project;
    private final ResourceBundle resourceBundle = ResourceBundle.getBundle("messages");
    private final FileEditorManager fileEditorManager;

    @Getter
    private final JPanel contentPanel = new JPanel();
    private final ComboBox<String> llmProvidersComboBox = new ComboBox<>();
    private final ComboBox<String> modelNameComboBox = new ComboBox<>();

    private final JButton configBtn = new JHoverButton(CogIcon, true);
    private final JButton submitBtn = new JHoverButton(SubmitIcon, true);
    private final JButton addFileBtn = new JHoverButton(AddFileIcon, true);
    private final JButton historyBtn = new JHoverButton(ClockIcon, true);
    private final JButton newConversationBtn = new JHoverButton(PlusIcon, true);

    private final PromptExecutionService promptExecutionService;
    private final SettingsState settingsState;

    private final UISetup uiSetup;
    private final EventHandlers eventHandlers;

    public DevoxxGenieToolWindowContent(@NotNull ToolWindow toolWindow) {
        project = toolWindow.getProject();
        fileEditorManager = FileEditorManager.getInstance(project);
        promptExecutionService = PromptExecutionService.getInstance();
        settingsState = SettingsState.getInstance();

        uiSetup = new UISetup(this, resourceBundle, llmProvidersComboBox, modelNameComboBox, configBtn, submitBtn, addFileBtn, newConversationBtn);
        eventHandlers = new EventHandlers(this, promptExecutionService, llmProvidersComboBox, modelNameComboBox, submitBtn);

        uiSetup.setupUI(contentPanel);
        eventHandlers.addEventListeners();

        setLastSelectedProvider();
    }

    private void setLastSelectedProvider() {
        String lastSelectedProvider = SettingsState.getInstance().getLastSelectedProvider();
        if (lastSelectedProvider != null) {
            llmProvidersComboBox.setSelectedItem(lastSelectedProvider);
        }
    }

    @Override
    public void settingsChanged() {
        llmProvidersComboBox.removeAllItems();
        uiSetup.addLLMProvidersToComboBox();
    }
}

UISetup.java

package com.devoxx.genie.ui;

import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.Splitter;

import javax.swing.*;
import java.awt.*;
import java.util.ResourceBundle;

public class UISetup {

    private final DevoxxGenieToolWindowContent parent;
    private final ResourceBundle resourceBundle;
    private final ComboBox<String> llmProvidersComboBox;
    private final ComboBox<String> modelNameComboBox;
    private final JButton configBtn;
    private final JButton submitBtn;
    private final JButton addFileBtn;
    private final JButton newConversationBtn;

    public UISetup(DevoxxGenieToolWindowContent parent, ResourceBundle resourceBundle, ComboBox<String> llmProvidersComboBox, ComboBox<String> modelNameComboBox, JButton configBtn, JButton submitBtn, JButton addFileBtn, JButton newConversationBtn) {
        this.parent = parent;
        this.resourceBundle = resourceBundle;
        this.llmProvidersComboBox = llmProvidersComboBox;
        this.modelNameComboBox = modelNameComboBox;
        this.configBtn = configBtn;
        this.submitBtn = submitBtn;
        this.addFileBtn = addFileBtn;
        this.newConversationBtn = newConversationBtn;
    }

    public void setupUI(JPanel contentPanel) {
        PromptInputArea promptInputComponent = new PromptInputArea(resourceBundle);
        PromptOutputPanel promptOutputPanel = new PromptOutputPanel(resourceBundle);
        PromptContextFileListPanel promptContextFileListPanel = new PromptContextFileListPanel(parent.getProject());

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BorderLayout());
        topPanel.add(createSelectionPanel(), BorderLayout.NORTH);
        topPanel.add(createConversationPanel(promptOutputPanel, promptInputComponent), BorderLayout.CENTER);

        contentPanel.setLayout(new BorderLayout());
        contentPanel.add(topPanel, BorderLayout.NORTH);

        Splitter splitter = new Splitter(true, 0.8f);
        splitter.setFirstComponent(promptOutputPanel);
        splitter.setSecondComponent(createInputPanel(promptContextFileListPanel, promptInputComponent));
        splitter.setHonorComponentsMinimumSize(true);

        contentPanel.add(splitter, BorderLayout.CENTER);
    }

    private JPanel createConversationPanel(PromptOutputPanel promptOutputPanel, PromptInputArea promptInputComponent) {
        JPanel conversationPanel = new JPanel(new BorderLayout());
        conversationPanel.setPreferredSize(new Dimension(0, 30));
        conversationPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));

        JLabel newConversationLabel = new JLabel("New conversation " + getCurrentTimestamp());
        newConversationLabel.setForeground(JBColor.GRAY);
        newConversationLabel.setPreferredSize(new Dimension(0, 30));

        newConversationBtn.setPreferredSize(new Dimension(25, 30));
        configBtn.setPreferredSize(new Dimension(25, 30));

        JPanel conversationButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        conversationButtonPanel.add(newConversationBtn);
        conversationButtonPanel.add(configBtn);
        conversationButtonPanel.setPreferredSize(new Dimension(60, 30));
        conversationButtonPanel.setMinimumSize(new Dimension(60, 30));

        configBtn.addActionListener(e -> parent.showSettingsDialog());
        newConversationBtn.addActionListener(e -> {
            newConversationLabel.setText("New conversation " + getCurrentTimestamp());
            promptOutputPanel.clear();
            parent.getPromptExecutionService().clearChatMessages();
            promptInputComponent.clear();
            FileListManager.getInstance().clear();
            parent.enableButtons();
        });

        conversationPanel.add(newConversationLabel, BorderLayout.CENTER);
        conversationPanel.add(conversationButtonPanel, BorderLayout.EAST);

        return conversationPanel;
    }

    private JPanel createSelectionPanel() {
        JPanel toolPanel = new JPanel();
        toolPanel.setLayout(new BoxLayout(toolPanel, BoxLayout.Y_AXIS));

        JPanel providerPanel = new JPanel(new BorderLayout(), true);
        providerPanel.add(llmProvidersComboBox, BorderLayout.CENTER);
        llmProvidersComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, llmProvidersComboBox.getPreferredSize().height));

        toolPanel.add(providerPanel);
        toolPanel.add(Box.createVerticalStrut(5));
        toolPanel.add(modelNameComboBox);
        modelNameComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, modelNameComboBox.getPreferredSize().height));

        return toolPanel;
    }

    private JPanel createInputPanel(PromptContextFileListPanel promptContextFileListPanel, PromptInputArea promptInputComponent) {
        addFileBtn.setToolTipText("Add file(s) to prompt context");
        submitBtn.setToolTipText("Submit the prompt");

        JPanel buttonPanel = new JPanel(new BorderLayout());
        buttonPanel.add(submitBtn, BorderLayout.WEST);
        buttonPanel.add(addFileBtn, BorderLayout.EAST);

        JPanel submitPanel = new JPanel(new BorderLayout());
        submitPanel.setMinimumSize(new Dimension(Integer.MAX_VALUE, 100));
        submitPanel.add(promptContextFileListPanel, BorderLayout.NORTH);
        submitPanel.add(new JBScrollPane(promptInputComponent), BorderLayout.CENTER);
        submitPanel.add(new JBScrollPane(buttonPanel), BorderLayout.SOUTH);

        return submitPanel;
    }

    private String getCurrentTimestamp() {
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM ''yy HH:mm");
        return dateTime.format(formatter);
    }

    public void addLLMProvidersToComboBox() {
        getLLMProviders().stream()
            .sorted()
            .forEach(llmProvidersComboBox::addItem);
    }
}

EventHandlers.java

package com.devoxx.genie.ui;

import com.devoxx.genie.service.PromptExecutionService;
import com.intellij.openapi.ui.ComboBox;

import javax.swing.*;
import java.awt.event.ActionEvent;

public class EventHandlers {

    private final DevoxxGenieToolWindowContent parent;
    private final PromptExecutionService promptExecutionService;
    private final ComboBox<String> llmProvidersComboBox;
    private final ComboBox<String> modelNameComboBox;
    private final JButton submitBtn;

    public EventHandlers(DevoxxGenieToolWindowContent parent, PromptExecutionService promptExecutionService, ComboBox<String> llmProviders

ChatGPT using GPT-4o :

https://chat.openai.com/share/09e00c0d-b9eb-4ba2-ba52-bca3b1b21188

Introduce also non-local LLM's

We can also add non local LLM like : OpenAI, Anthropic (Claude), Mistral, Fireworks, Gemini, Groq, Cohere and DeepInfra.
This would make the DevoxxGenie pluing a one stop tool for all available LLM's ๐Ÿฅณ

The related API Keys would need to be stored securely via the Settings page.

The following Langchain4J Gradle dependencies would need to be added:

Anthropic (Claude) :

dev.langchain4j:langchain4j-anthropic

OpenAi (also used by Fireworks and DeepInfra)

dev.langchain4j:langchain4j-open-ai

Gemini:

dev.langchain4j:langchain4j-vertex-ai-gemini

Mistral:

dev.langchain4j:langchain4j-mistral-ai

Introduce smart prompt context

Populate the prompt context based on open tabs and/or select code and add to prompt using right-click.
This should be an option that the developer can enable/disable based on selected LLM and available window context!

The SystemMessage gets removed when the max chat memory have been reached

The CircularQueue will override the SystemMessage when the max chat memory has been reached.

public String executeGeniePrompt(String userPrompt,
                                     LanguageTextPair languageAndSelectedText) {
        ChatLanguageModel chatLanguageModel = getChatLanguageModel();
=>        if (chatMessages.isEmpty()) {
            chatMessages.add(new SystemMessage(
                YOU_ARE_A_SOFTWARE_DEVELOPER_WITH_EXPERT_KNOWLEDGE_IN + languageAndSelectedText.getLanguage() + PROGRAMMING_LANGUAGE +
                    "Always return the response in Markdown."));
        }

        userPrompt = userPrompt + "\n\nSelected code: " + languageAndSelectedText.getText();
        chatMessages.add(new UserMessage(userPrompt));

        try {
            Response<AiMessage> generate = chatLanguageModel.generate(chatMessages.asList());
            String response = generate.content().text();
            chatMessages.add(new AiMessage(response));
            return response;
        } catch (Exception e) {
            return "Failed to execute Genie prompt!\n" + e.getMessage();
        }
    }

Introduce previous / next chat responses

It would be nice to have the possibility to see the previous chat response, so introducing a prev/next button in the chat box would be a nice way to scroll through the chat messages

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.