From 8c8c207e665a8f620c0c8eaafc92588391a1b41b Mon Sep 17 00:00:00 2001 From: Stephan Janssen Date: Mon, 3 Jun 2024 18:13:54 +0200 Subject: [PATCH] Feat #93: Use FormBuilder for Settings pages --- .../genie/chatmodel/ChatModelProvider.java | 16 ++--- .../genie/chatmodel/LLMProviderConstant.java | 16 ++--- .../anthropic/AnthropicChatModelFactory.java | 4 +- .../deepinfra/DeepInfraChatModelFactory.java | 4 +- .../gemini/GeminiChatModelFactory.java | 4 +- .../gpt4all/GPT4AllChatModelFactory.java | 6 +- .../chatmodel/groq/GroqChatModelFactory.java | 4 +- .../chatmodel/jan/JanChatModelFactory.java | 6 +- .../lmstudio/LMStudioChatModelFactory.java | 6 +- .../mistral/MistralChatModelFactory.java | 4 +- .../ollama/OllamaChatModelFactory.java | 6 +- .../openai/OpenAIChatModelFactory.java | 4 +- .../genie/service/ChatMemoryService.java | 4 +- .../genie/service/ChatPromptExecutor.java | 15 +++-- .../com/devoxx/genie/service/JanService.java | 4 +- .../genie/service/MessageCreationService.java | 5 +- .../devoxx/genie/service/OllamaService.java | 4 +- .../genie/service/PSIAnalyzerService.java | 8 +-- .../genie/service/PromptExecutionService.java | 4 +- .../genie/service/WebSearchService.java | 12 ++-- .../ui/DevoxxGenieToolWindowContent.java | 10 +-- .../genie/ui/panel/ActionButtonsPanel.java | 21 +++---- .../genie/ui/panel/PromptOutputPanel.java | 4 +- ...vice.java => DevoxxGenieStateService.java} | 34 +++++++++-- .../genie/ui/settings/SettingsComponent.java | 16 +++++ .../ui/settings/llm/LLMSettingsComponent.java | 50 ++++++++------- .../settings/llm/LLMSettingsConfigurable.java | 51 ++++++++++++---- .../llmconfig/LLMConfigSettingsComponent.java | 39 ++++++------ .../LLMConfigSettingsConfigurable.java | 61 ++++++++++--------- .../llmconfig/LLMConfigStateService.java | 56 ----------------- .../prompt/PromptSettingsComponent.java | 33 ++++++---- .../prompt/PromptSettingsConfigurable.java | 26 ++++---- .../prompt/PromptSettingsStateService.java | 44 ------------- 33 files changed, 287 insertions(+), 294 deletions(-) rename src/main/java/com/devoxx/genie/ui/settings/{llm/LLMStateService.java => DevoxxGenieStateService.java} (55%) create mode 100644 src/main/java/com/devoxx/genie/ui/settings/SettingsComponent.java delete mode 100644 src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigStateService.java delete mode 100644 src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsStateService.java diff --git a/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java b/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java index a89532de..6bbc4801 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java +++ b/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java @@ -13,7 +13,7 @@ import com.devoxx.genie.model.Constant; import com.devoxx.genie.model.enumarations.ModelProvider; import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.ui.settings.llmconfig.LLMConfigStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import lombok.Setter; @@ -83,13 +83,13 @@ public StreamingChatLanguageModel getStreamingChatLanguageModel(@NotNull ChatMes */ public @NotNull ChatModel initChatModel(@NotNull ChatMessageContext chatMessageContext) { ChatModel chatModel = new ChatModel(); - LLMConfigStateService settingsState = LLMConfigStateService.getInstance(); - setMaxOutputTokens(settingsState, chatModel); + DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); + setMaxOutputTokens(stateService, chatModel); - chatModel.setTemperature(settingsState.getTemperature()); - chatModel.setMaxRetries(settingsState.getMaxRetries()); - chatModel.setTopP(settingsState.getTopP()); - chatModel.setTimeout(settingsState.getTimeout()); + chatModel.setTemperature(stateService.getTemperature()); + chatModel.setMaxRetries(stateService.getMaxRetries()); + chatModel.setTopP(stateService.getTopP()); + chatModel.setTimeout(stateService.getTimeout()); chatModel.setModelName(chatMessageContext.getModelName()); return chatModel; } @@ -101,7 +101,7 @@ public StreamingChatLanguageModel getStreamingChatLanguageModel(@NotNull ChatMes * @param settingsState the settings state * @param chatModel the chat model */ - private static void setMaxOutputTokens(@NotNull LLMConfigStateService settingsState, ChatModel chatModel) { + private static void setMaxOutputTokens(@NotNull DevoxxGenieStateService settingsState, ChatModel chatModel) { Integer maxOutputTokens = settingsState.getMaxOutputTokens(); if (maxOutputTokens == null) { chatModel.setMaxTokens(Constant.MAX_OUTPUT_TOKENS); diff --git a/src/main/java/com/devoxx/genie/chatmodel/LLMProviderConstant.java b/src/main/java/com/devoxx/genie/chatmodel/LLMProviderConstant.java index b7ed61bf..4d0bd262 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/LLMProviderConstant.java +++ b/src/main/java/com/devoxx/genie/chatmodel/LLMProviderConstant.java @@ -1,6 +1,6 @@ package com.devoxx.genie.chatmodel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -32,14 +32,14 @@ private LLMProviderConstant() { }; public static @NotNull List getLLMProviders() { - LLMStateService settingState = LLMStateService.getInstance(); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); Map> providerKeyMap = new HashMap<>(); - providerKeyMap.put(OpenAI.getName(), settingState::getOpenAIKey); - providerKeyMap.put(Anthropic.getName(), settingState::getAnthropicKey); - providerKeyMap.put(Mistral.getName(), settingState::getMistralKey); - providerKeyMap.put(Groq.getName(), settingState::getGroqKey); - providerKeyMap.put(DeepInfra.getName(), settingState::getDeepInfraKey); - providerKeyMap.put(Gemini.getName(), settingState::getGeminiKey); + providerKeyMap.put(OpenAI.getName(), settings::getOpenAIKey); + providerKeyMap.put(Anthropic.getName(), settings::getAnthropicKey); + providerKeyMap.put(Mistral.getName(), settings::getMistralKey); + providerKeyMap.put(Groq.getName(), settings::getGroqKey); + providerKeyMap.put(DeepInfra.getName(), settings::getDeepInfraKey); + providerKeyMap.put(Gemini.getName(), settings::getGeminiKey); // Filter out cloud LLM providers that do not have a key var providers = Stream.of(llmProvidersWithKey) diff --git a/src/main/java/com/devoxx/genie/chatmodel/anthropic/AnthropicChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/anthropic/AnthropicChatModelFactory.java index badc1184..1007bf52 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/anthropic/AnthropicChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/anthropic/AnthropicChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.anthropic.AnthropicChatModel; import dev.langchain4j.model.anthropic.AnthropicStreamingChatModel; import dev.langchain4j.model.chat.ChatLanguageModel; @@ -40,7 +40,7 @@ public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel ch @Override public String getApiKey() { - return LLMStateService.getInstance().getAnthropicKey().trim(); + return DevoxxGenieStateService.getInstance().getAnthropicKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/chatmodel/deepinfra/DeepInfraChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/deepinfra/DeepInfraChatModelFactory.java index dc7b7e36..346e1efc 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/deepinfra/DeepInfraChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/deepinfra/DeepInfraChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; @@ -42,7 +42,7 @@ public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel ch @Override public String getApiKey() { - return LLMStateService.getInstance().getDeepInfraKey().trim(); + return DevoxxGenieStateService.getInstance().getDeepInfraKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/chatmodel/gemini/GeminiChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/gemini/GeminiChatModelFactory.java index c543bb86..2e594ed9 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/gemini/GeminiChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/gemini/GeminiChatModelFactory.java @@ -3,7 +3,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; import com.devoxx.genie.model.gemini.GeminiChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import org.jetbrains.annotations.NotNull; @@ -26,7 +26,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { @Override public String getApiKey() { - return LLMStateService.getInstance().getGeminiKey().trim(); + return DevoxxGenieStateService.getInstance().getGeminiKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/chatmodel/gpt4all/GPT4AllChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/gpt4all/GPT4AllChatModelFactory.java index d5dcaead..d5a5f276 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/gpt4all/GPT4AllChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/gpt4all/GPT4AllChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.localai.LocalAiChatModel; @@ -16,7 +16,7 @@ public class GPT4AllChatModelFactory implements ChatModelFactory { @Override public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { return LocalAiChatModel.builder() - .baseUrl(LLMStateService.getInstance().getGpt4allModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getGpt4allModelUrl()) .modelName("test-model") .maxRetries(chatModel.getMaxRetries()) .maxTokens(chatModel.getMaxTokens()) @@ -28,7 +28,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel chatModel) { return LocalAiStreamingChatModel.builder() - .baseUrl(LLMStateService.getInstance().getGpt4allModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getGpt4allModelUrl()) .modelName("test-model") .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) diff --git a/src/main/java/com/devoxx/genie/chatmodel/groq/GroqChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/groq/GroqChatModelFactory.java index 71c82401..0e996dfd 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/groq/GroqChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/groq/GroqChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import org.jetbrains.annotations.NotNull; @@ -40,7 +40,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { @Override public String getApiKey() { - return LLMStateService.getInstance().getGroqKey().trim(); + return DevoxxGenieStateService.getInstance().getGroqKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/chatmodel/jan/JanChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/jan/JanChatModelFactory.java index 4bccc65e..63b886e3 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/jan/JanChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/jan/JanChatModelFactory.java @@ -4,7 +4,7 @@ import com.devoxx.genie.model.ChatModel; import com.devoxx.genie.model.jan.Data; import com.devoxx.genie.service.JanService; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.project.ProjectManager; import dev.langchain4j.model.chat.ChatLanguageModel; @@ -27,7 +27,7 @@ public class JanChatModelFactory implements ChatModelFactory { @Override public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { return LocalAiChatModel.builder() - .baseUrl(LLMStateService.getInstance().getJanModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getJanModelUrl()) .modelName(chatModel.getModelName()) .maxRetries(chatModel.getMaxRetries()) .temperature(chatModel.getTemperature()) @@ -41,7 +41,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { @Override public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel chatModel) { return LocalAiStreamingChatModel.builder() - .baseUrl(LLMStateService.getInstance().getJanModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getJanModelUrl()) .modelName(chatModel.getModelName()) .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) diff --git a/src/main/java/com/devoxx/genie/chatmodel/lmstudio/LMStudioChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/lmstudio/LMStudioChatModelFactory.java index 0dfce58e..87cbcede 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/lmstudio/LMStudioChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/lmstudio/LMStudioChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.localai.LocalAiChatModel; @@ -16,7 +16,7 @@ public class LMStudioChatModelFactory implements ChatModelFactory { @Override public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { return LocalAiChatModel.builder() - .baseUrl(LLMStateService.getInstance().getLmstudioModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getLmstudioModelUrl()) .modelName("LMStudio") .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) @@ -29,7 +29,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { @Override public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel chatModel) { return LocalAiStreamingChatModel.builder() - .baseUrl(LLMStateService.getInstance().getLmstudioModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getLmstudioModelUrl()) .modelName("LMStudio") .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) diff --git a/src/main/java/com/devoxx/genie/chatmodel/mistral/MistralChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/mistral/MistralChatModelFactory.java index db423f9b..c811e6d2 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/mistral/MistralChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/mistral/MistralChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.mistralai.MistralAiChatModel; @@ -42,7 +42,7 @@ public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel ch @Override public String getApiKey() { - return LLMStateService.getInstance().getMistralKey().trim(); + return DevoxxGenieStateService.getInstance().getMistralKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/chatmodel/ollama/OllamaChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/ollama/OllamaChatModelFactory.java index e0c9b0d4..363def9c 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/ollama/OllamaChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/ollama/OllamaChatModelFactory.java @@ -4,7 +4,7 @@ import com.devoxx.genie.model.ChatModel; import com.devoxx.genie.model.ollama.OllamaModelEntryDTO; import com.devoxx.genie.service.OllamaService; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.project.ProjectManager; import dev.langchain4j.model.chat.ChatLanguageModel; @@ -23,7 +23,7 @@ public class OllamaChatModelFactory implements ChatModelFactory { @Override public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { return OllamaChatModel.builder() - .baseUrl(LLMStateService.getInstance().getOllamaModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getOllamaModelUrl()) .modelName(chatModel.getModelName()) .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) @@ -35,7 +35,7 @@ public ChatLanguageModel createChatModel(@NotNull ChatModel chatModel) { @Override public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel chatModel) { return OllamaStreamingChatModel.builder() - .baseUrl(LLMStateService.getInstance().getOllamaModelUrl()) + .baseUrl(DevoxxGenieStateService.getInstance().getOllamaModelUrl()) .modelName(chatModel.getModelName()) .temperature(chatModel.getTemperature()) .topP(chatModel.getTopP()) diff --git a/src/main/java/com/devoxx/genie/chatmodel/openai/OpenAIChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/openai/OpenAIChatModelFactory.java index c48a596e..fbe3536d 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/openai/OpenAIChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/openai/OpenAIChatModelFactory.java @@ -2,7 +2,7 @@ import com.devoxx.genie.chatmodel.ChatModelFactory; import com.devoxx.genie.model.ChatModel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.chat.StreamingChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; @@ -41,7 +41,7 @@ public StreamingChatLanguageModel createStreamingChatModel(@NotNull ChatModel ch @Override public String getApiKey() { - return LLMStateService.getInstance().getOpenAIKey().trim(); + return DevoxxGenieStateService.getInstance().getOpenAIKey().trim(); } @Override diff --git a/src/main/java/com/devoxx/genie/service/ChatMemoryService.java b/src/main/java/com/devoxx/genie/service/ChatMemoryService.java index aad708bc..1a1658ff 100644 --- a/src/main/java/com/devoxx/genie/service/ChatMemoryService.java +++ b/src/main/java/com/devoxx/genie/service/ChatMemoryService.java @@ -1,7 +1,7 @@ package com.devoxx.genie.service; import com.devoxx.genie.ui.listener.ChatMemorySizeListener; -import com.devoxx.genie.ui.settings.llmconfig.LLMConfigStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.topic.AppTopics; import com.intellij.openapi.application.ApplicationManager; import dev.langchain4j.data.message.ChatMessage; @@ -22,7 +22,7 @@ public class ChatMemoryService implements ChatMemorySizeListener { * @link PostStartupActivity */ public void init() { - createChatMemory(LLMConfigStateService.getInstance().getChatMemorySize()); + createChatMemory(DevoxxGenieStateService.getInstance().getChatMemorySize()); createChangeListener(); } diff --git a/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java b/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java index 0601f848..02327452 100644 --- a/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java +++ b/src/main/java/com/devoxx/genie/service/ChatPromptExecutor.java @@ -2,8 +2,7 @@ import com.devoxx.genie.model.request.ChatMessageContext; import com.devoxx.genie.ui.panel.PromptOutputPanel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; -import com.devoxx.genie.ui.settings.prompt.PromptSettingsStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; @@ -39,7 +38,7 @@ public void run(@NotNull ProgressIndicator progressIndicator) { if (chatMessageContext.getContext() != null && chatMessageContext.getContext().toLowerCase().contains("search")) { webSearchPrompt(chatMessageContext, promptOutputPanel, enableButtons); } else { - if (LLMStateService.getInstance().getStreamMode()) { + if (DevoxxGenieStateService.getInstance().getStreamMode()) { setupStreaming(chatMessageContext, promptOutputPanel, enableButtons); } else { runPrompt(chatMessageContext, promptOutputPanel, enableButtons); @@ -99,7 +98,7 @@ private void setupStreaming(@NotNull ChatMessageContext chatMessageContext, MessageCreationService messageCreationService = MessageCreationService.getInstance(); if (chatMemoryService.isEmpty()) { - chatMemoryService.add(new SystemMessage(PromptSettingsStateService.getInstance().getSystemPrompt())); + chatMemoryService.add(new SystemMessage(DevoxxGenieStateService.getInstance().getSystemPrompt())); } UserMessage userMessage = messageCreationService.createUserMessage(chatMessageContext); @@ -124,13 +123,13 @@ private Optional getCommandFromPrompt(@NotNull String prompt, if (prompt.startsWith("/")) { if (prompt.equalsIgnoreCase("/test")) { - prompt = PromptSettingsStateService.getInstance().getTestPrompt(); + prompt = DevoxxGenieStateService.getInstance().getTestPrompt(); } else if (prompt.equalsIgnoreCase("/review")) { - prompt = PromptSettingsStateService.getInstance().getReviewPrompt(); + prompt = DevoxxGenieStateService.getInstance().getReviewPrompt(); } else if (prompt.equalsIgnoreCase("/explain")) { - prompt = PromptSettingsStateService.getInstance().getExplainPrompt(); + prompt = DevoxxGenieStateService.getInstance().getExplainPrompt(); } else if (prompt.equalsIgnoreCase("/custom")) { - prompt = PromptSettingsStateService.getInstance().getCustomPrompt(); + prompt = DevoxxGenieStateService.getInstance().getCustomPrompt(); } else { promptOutputPanel.showHelpText(); return Optional.empty(); diff --git a/src/main/java/com/devoxx/genie/service/JanService.java b/src/main/java/com/devoxx/genie/service/JanService.java index f432a3dc..87971b15 100644 --- a/src/main/java/com/devoxx/genie/service/JanService.java +++ b/src/main/java/com/devoxx/genie/service/JanService.java @@ -2,7 +2,7 @@ import com.devoxx.genie.model.jan.Data; import com.devoxx.genie.model.jan.ResponseDTO; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.google.gson.Gson; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -21,7 +21,7 @@ public JanService(OkHttpClient client) { } public List getModels() throws IOException { - String baseUrl = ensureEndsWithSlash(LLMStateService.getInstance().getJanModelUrl()); + String baseUrl = ensureEndsWithSlash(DevoxxGenieStateService.getInstance().getJanModelUrl()); Request request = new Request.Builder() .url(baseUrl + "models") diff --git a/src/main/java/com/devoxx/genie/service/MessageCreationService.java b/src/main/java/com/devoxx/genie/service/MessageCreationService.java index c273fcbf..33f7c1ed 100644 --- a/src/main/java/com/devoxx/genie/service/MessageCreationService.java +++ b/src/main/java/com/devoxx/genie/service/MessageCreationService.java @@ -1,8 +1,7 @@ package com.devoxx.genie.service; import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.ui.settings.llm.LLMStateService; -import com.devoxx.genie.ui.settings.llmconfig.LLMConfigStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; @@ -101,7 +100,7 @@ public static MessageCreationService getInstance() { appendIfNotEmpty(sb, chatMessageContext.getEditorInfo().getSelectedText()); - if (LLMConfigStateService.getInstance().getAstMode()) { + if (DevoxxGenieStateService.getInstance().getAstMode()) { addASTContext(chatMessageContext, sb); } diff --git a/src/main/java/com/devoxx/genie/service/OllamaService.java b/src/main/java/com/devoxx/genie/service/OllamaService.java index 4db4ec1e..5b751951 100644 --- a/src/main/java/com/devoxx/genie/service/OllamaService.java +++ b/src/main/java/com/devoxx/genie/service/OllamaService.java @@ -2,7 +2,7 @@ import com.devoxx.genie.model.ollama.OllamaModelDTO; import com.devoxx.genie.model.ollama.OllamaModelEntryDTO; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.google.gson.Gson; import com.intellij.openapi.application.ApplicationManager; import okhttp3.OkHttpClient; @@ -29,7 +29,7 @@ public static OllamaService getInstance() { * @throws IOException if there is an error */ public OllamaModelEntryDTO[] getModels() throws IOException { - String baseUrl = ensureEndsWithSlash(LLMStateService.getInstance().getOllamaModelUrl()); + String baseUrl = ensureEndsWithSlash(DevoxxGenieStateService.getInstance().getOllamaModelUrl()); Request request = new Request.Builder() .url(baseUrl + "api/tags") diff --git a/src/main/java/com/devoxx/genie/service/PSIAnalyzerService.java b/src/main/java/com/devoxx/genie/service/PSIAnalyzerService.java index 3800f8de..3b016da2 100644 --- a/src/main/java/com/devoxx/genie/service/PSIAnalyzerService.java +++ b/src/main/java/com/devoxx/genie/service/PSIAnalyzerService.java @@ -1,6 +1,6 @@ package com.devoxx.genie.service; -import com.devoxx.genie.ui.settings.llmconfig.LLMConfigStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -36,13 +36,13 @@ public Optional> analyze(Project project, VirtualFile file) { } for (PsiClass psiClass : runReadAction(javaFile::getClasses)) { - if (LLMConfigStateService.getInstance().getAstParentClass()) { + if (DevoxxGenieStateService.getInstance().getAstParentClass()) { extractBaseClass(psiClass, relatedClasses); } - if (LLMConfigStateService.getInstance().getAstClassReference()) { + if (DevoxxGenieStateService.getInstance().getAstClassReference()) { extractReferenceClasses(psiClass, relatedClasses); } - if (LLMConfigStateService.getInstance().getAstFieldReference()) { + if (DevoxxGenieStateService.getInstance().getAstFieldReference()) { PsiField[] fields = runReadAction(psiClass::getFields); extractPSIFields(fields, relatedClasses); } diff --git a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java index 37011263..db7b2e83 100644 --- a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java +++ b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java @@ -2,7 +2,7 @@ import com.devoxx.genie.model.Constant; import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.ui.settings.prompt.PromptSettingsStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import dev.langchain4j.data.message.AiMessage; @@ -52,7 +52,7 @@ static PromptExecutionService getInstance() { if (ChatMemoryService.getInstance().isEmpty()) { ChatMemoryService.getInstance().add( - new SystemMessage(PromptSettingsStateService.getInstance().getSystemPrompt() + Constant.MARKDOWN) + new SystemMessage(DevoxxGenieStateService.getInstance().getSystemPrompt() + Constant.MARKDOWN) ); } diff --git a/src/main/java/com/devoxx/genie/service/WebSearchService.java b/src/main/java/com/devoxx/genie/service/WebSearchService.java index dce3cb9a..6d4524a9 100644 --- a/src/main/java/com/devoxx/genie/service/WebSearchService.java +++ b/src/main/java/com/devoxx/genie/service/WebSearchService.java @@ -2,7 +2,7 @@ import com.devoxx.genie.model.request.ChatMessageContext; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.application.ApplicationManager; import dev.langchain4j.data.message.AiMessage; import dev.langchain4j.rag.content.retriever.ContentRetriever; @@ -71,15 +71,15 @@ interface SearchWebsite { */ private static Optional getWebSearchEngine(@NotNull ChatMessageContext chatMessageContext) { if (chatMessageContext.getContext().equals(TAVILY_SEARCH_ACTION) && - LLMStateService.getInstance().getTavilySearchKey() != null) { + DevoxxGenieStateService.getInstance().getTavilySearchKey() != null) { return Optional.of(TavilyWebSearchEngine.builder() - .apiKey(LLMStateService.getInstance().getTavilySearchKey()) + .apiKey(DevoxxGenieStateService.getInstance().getTavilySearchKey()) .build()); - } else if (LLMStateService.getInstance().getGoogleSearchKey() != null && + } else if (DevoxxGenieStateService.getInstance().getGoogleSearchKey() != null && chatMessageContext.getContext().equals(GOOGLE_SEARCH_ACTION)) { return Optional.of(GoogleCustomWebSearchEngine.builder() - .apiKey(LLMStateService.getInstance().getGoogleSearchKey()) - .csi(LLMStateService.getInstance().getGoogleCSIKey()) + .apiKey(DevoxxGenieStateService.getInstance().getGoogleSearchKey()) + .csi(DevoxxGenieStateService.getInstance().getGoogleCSIKey()) .build()); } else { return Optional.empty(); diff --git a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java index 1facbb73..0edae69a 100644 --- a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java +++ b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java @@ -12,7 +12,7 @@ import com.devoxx.genie.ui.panel.ConversationPanel; import com.devoxx.genie.ui.panel.PromptContextFileListPanel; import com.devoxx.genie.ui.panel.PromptOutputPanel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.ui.Splitter; @@ -71,7 +71,7 @@ public DevoxxGenieToolWindowContent(@NotNull ToolWindow toolWindow) { * Set the last selected LLM provider or show default. */ private void setLastSelectedProvider() { - String lastSelectedProvider = LLMStateService.getInstance().getLastSelectedProvider(); + String lastSelectedProvider = DevoxxGenieStateService.getInstance().getLastSelectedProvider(); if (lastSelectedProvider != null && !lastSelectedProvider.isEmpty()) { llmProvidersComboBox.setSelectedItem(lastSelectedProvider); updateModelNamesComboBox(ModelProvider.valueOf(lastSelectedProvider)); @@ -229,7 +229,7 @@ private void processModelNameSelection(@NotNull ActionEvent e) { JComboBox comboBox = (JComboBox) e.getSource(); String selectedModel = (String) comboBox.getSelectedItem(); if (selectedModel != null) { - LLMStateService.getInstance().setLastSelectedModel(selectedModel); + DevoxxGenieStateService.getInstance().setLastSelectedModel(selectedModel); } } } @@ -246,7 +246,7 @@ private void handleModelProviderSelectionChange(@NotNull ActionEvent e) { String selectedLLMProvider = (String) comboBox.getSelectedItem(); if (selectedLLMProvider == null) return; - LLMStateService.getInstance().setLastSelectedProvider(selectedLLMProvider); + DevoxxGenieStateService.getInstance().setLastSelectedProvider(selectedLLMProvider); ModelProvider provider = ModelProvider.fromString(selectedLLMProvider); updateModelNamesComboBox(provider); @@ -269,7 +269,7 @@ private void updateModelNamesComboBox(ModelProvider provider) { .getFactoryByProvider(provider) .ifPresentOrElse(this::populateModelNames, this::hideModelNameComboBox); - String lastSelectedModel = LLMStateService.getInstance().getLastSelectedModel(); + String lastSelectedModel = DevoxxGenieStateService.getInstance().getLastSelectedModel(); if (lastSelectedModel != null) { modelNameComboBox.setSelectedItem(lastSelectedModel); } diff --git a/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java b/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java index c85fc556..9b869425 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/ActionButtonsPanel.java @@ -12,8 +12,7 @@ import com.devoxx.genie.ui.component.ContextPopupMenu; import com.devoxx.genie.ui.component.JHoverButton; import com.devoxx.genie.ui.component.PromptInputArea; -import com.devoxx.genie.ui.settings.llm.LLMStateService; -import com.devoxx.genie.ui.settings.llmconfig.LLMConfigStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.EditorUtil; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.openapi.editor.Editor; @@ -170,7 +169,7 @@ public void enableButtons() { */ private void disableSubmitBtn() { invokeLater(() -> { - if (LLMStateService.getInstance().getStreamMode()) { + if (DevoxxGenieStateService.getInstance().getStreamMode()) { submitBtn.setEnabled(false); } submitBtn.setIcon(StopIcon); @@ -225,7 +224,7 @@ private boolean isWebSearchTriggeredAndConfigured(@NotNull ActionEvent actionEve chatMessageContext.setLlmProvider((String) llmProvidersComboBox.getSelectedItem()); chatMessageContext.setModelName((String) modelNameComboBox.getSelectedItem()); - if (LLMStateService.getInstance().getStreamMode() && actionEvent.getActionCommand().equals(Constant.SUBMIT_ACTION)) { + if (DevoxxGenieStateService.getInstance().getStreamMode() && actionEvent.getActionCommand().equals(Constant.SUBMIT_ACTION)) { chatMessageContext.setStreamingChatLanguageModel(chatModelProvider.getStreamingChatLanguageModel(chatMessageContext)); } else { chatMessageContext.setChatLanguageModel(chatModelProvider.getChatLanguageModel(chatMessageContext)); @@ -282,7 +281,7 @@ private void addSelectedCodeSnippet(String userPrompt, * @param chatMessageContext the chat message context */ private void setChatTimeout(ChatMessageContext chatMessageContext) { - Integer timeout = LLMConfigStateService.getInstance().getTimeout(); + Integer timeout = DevoxxGenieStateService.getInstance().getTimeout(); if (timeout == 0) { chatMessageContext.setTimeout(60); } else { @@ -295,8 +294,8 @@ private void setChatTimeout(ChatMessageContext chatMessageContext) { * @return true if web search is enabled */ private boolean isWebSearchEnabled() { - return !LLMStateService.getInstance().getTavilySearchKey().isEmpty() || - !LLMStateService.getInstance().getGoogleSearchKey().isEmpty(); + return !DevoxxGenieStateService.getInstance().getTavilySearchKey().isEmpty() || + !DevoxxGenieStateService.getInstance().getGoogleSearchKey().isEmpty(); } /** @@ -328,13 +327,13 @@ private void disableButtons() { * Set the search buttons visibility based on settings. */ public void configureSearchButtonsVisibility() { - if (LLMStateService.getInstance().getHideSearchButtonsFlag()) { + if (DevoxxGenieStateService.getInstance().getHideSearchButtonsFlag()) { tavilySearchBtn.setVisible(false); googleSearchBtn.setVisible(false); } else { - tavilySearchBtn.setVisible(!LLMStateService.getInstance().getTavilySearchKey().isEmpty()); - googleSearchBtn.setVisible(!LLMStateService.getInstance().getGoogleSearchKey().isEmpty() && - !LLMStateService.getInstance().getGoogleCSIKey().isEmpty()); + tavilySearchBtn.setVisible(!DevoxxGenieStateService.getInstance().getTavilySearchKey().isEmpty()); + googleSearchBtn.setVisible(!DevoxxGenieStateService.getInstance().getGoogleSearchKey().isEmpty() && + !DevoxxGenieStateService.getInstance().getGoogleCSIKey().isEmpty()); } } } diff --git a/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java b/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java index d4300eca..c8c3a847 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java @@ -2,7 +2,7 @@ import com.devoxx.genie.model.request.ChatMessageContext; import com.devoxx.genie.ui.component.ExpandablePanel; -import com.devoxx.genie.ui.settings.llm.LLMStateService; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.devoxx.genie.ui.util.HelpUtil; import com.intellij.ui.components.JBPanel; import com.intellij.ui.components.JBScrollPane; @@ -88,7 +88,7 @@ public void addUserPrompt(ChatMessageContext chatMessageContext) { UserPromptPanel userPromptPanel = new UserPromptPanel(container, chatMessageContext); - if (!LLMStateService.getInstance().getStreamMode()) { + if (!DevoxxGenieStateService.getInstance().getStreamMode()) { waitingPanel.showMsg(); userPromptPanel.add(waitingPanel, BorderLayout.SOUTH); } diff --git a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMStateService.java b/src/main/java/com/devoxx/genie/ui/settings/DevoxxGenieStateService.java similarity index 55% rename from src/main/java/com/devoxx/genie/ui/settings/llm/LLMStateService.java rename to src/main/java/com/devoxx/genie/ui/settings/DevoxxGenieStateService.java index 4f24d6d4..8cf2a41e 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMStateService.java +++ b/src/main/java/com/devoxx/genie/ui/settings/DevoxxGenieStateService.java @@ -1,4 +1,4 @@ -package com.devoxx.genie.ui.settings.llm; +package com.devoxx.genie.ui.settings; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PersistentStateComponent; @@ -19,10 +19,10 @@ name = "com.devoxx.genie.ui.SettingsState", storages = @Storage("DevoxxGenieSettingsPlugin.xml") ) -public final class LLMStateService implements PersistentStateComponent { +public final class DevoxxGenieStateService implements PersistentStateComponent { - public static LLMStateService getInstance() { - return ApplicationManager.getApplication().getService(LLMStateService.class); + public static DevoxxGenieStateService getInstance() { + return ApplicationManager.getApplication().getService(DevoxxGenieStateService.class); } // Local LLM URL fields @@ -45,19 +45,41 @@ public static LLMStateService getInstance() { private String googleCSIKey = ""; private String tavilySearchKey = ""; + // Last selected LLM provider and model name private String lastSelectedProvider = ""; private String lastSelectedModel = ""; // Enable stream mode private Boolean streamMode = STREAM_MODE; + // LLM settings + private Double temperature = TEMPERATURE; + private Double topP = TOP_P; + + private Integer timeout = TIMEOUT; + private Integer maxRetries = MAX_RETRIES; + private Integer chatMemorySize = MAX_MEMORY; + private Integer maxOutputTokens = MAX_OUTPUT_TOKENS; + + // Enable AST mode + private Boolean astMode = AST_MODE; + private Boolean astParentClass = AST_PARENT_CLASS; + private Boolean astClassReference = AST_CLASS_REFERENCE; + private Boolean astFieldReference = AST_FIELD_REFERENCE; + + private String systemPrompt = SYSTEM_PROMPT; + private String testPrompt = TEST_PROMPT; + private String reviewPrompt = REVIEW_PROMPT; + private String explainPrompt = EXPLAIN_PROMPT; + private String customPrompt = CUSTOM_PROMPT; + @Override - public LLMStateService getState() { + public DevoxxGenieStateService getState() { return this; } @Override - public void loadState(@NotNull LLMStateService state) { + public void loadState(@NotNull DevoxxGenieStateService state) { XmlSerializerUtil.copyBean(state, this); } } diff --git a/src/main/java/com/devoxx/genie/ui/settings/SettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/SettingsComponent.java new file mode 100644 index 00000000..1218ec1f --- /dev/null +++ b/src/main/java/com/devoxx/genie/ui/settings/SettingsComponent.java @@ -0,0 +1,16 @@ +package com.devoxx.genie.ui.settings; + +import javax.swing.*; + +public interface SettingsComponent { + + /** + * Create the settings panel + */ + JPanel createSettingsPanel(); + + /** + * Adds listeners to the settings panel components + */ + void addListeners(); +} diff --git a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java index a986b40b..ef81cfdb 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsComponent.java @@ -1,5 +1,7 @@ package com.devoxx.genie.ui.settings.llm; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; +import com.devoxx.genie.ui.settings.SettingsComponent; import com.devoxx.genie.ui.util.NotificationUtil; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.project.Project; @@ -13,49 +15,51 @@ import java.awt.*; import java.awt.event.ItemEvent; -public class LLMSettingsComponent { +public class LLMSettingsComponent implements SettingsComponent { - public LLMStateService llmStateService = LLMStateService.getInstance(); + private final DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); public static final String LINK_EMOJI = "\uD83D\uDD17"; public static final String PASSWORD_EMOJI = "\uD83D\uDD11"; @Getter - private final JTextField ollamaModelUrlField = new JTextField(llmStateService.getOllamaModelUrl()); + private final JTextField ollamaModelUrlField = new JTextField(stateService.getOllamaModelUrl()); @Getter - private final JTextField lmStudioModelUrlField = new JTextField(llmStateService.getLmstudioModelUrl()); + private final JTextField lmStudioModelUrlField = new JTextField(stateService.getLmstudioModelUrl()); @Getter - private final JTextField gpt4AllModelUrlField = new JTextField(llmStateService.getGpt4allModelUrl()); + private final JTextField gpt4AllModelUrlField = new JTextField(stateService.getGpt4allModelUrl()); @Getter - private final JTextField janModelUrlField = new JTextField(llmStateService.getJanModelUrl()); + private final JTextField janModelUrlField = new JTextField(stateService.getJanModelUrl()); @Getter - private final JPasswordField openAIKeyField = new JPasswordField(llmStateService.getOpenAIKey()); + private final JPasswordField openAIKeyField = new JPasswordField(stateService.getOpenAIKey()); @Getter - private final JPasswordField mistralApiKeyField = new JPasswordField(llmStateService.getMistralKey()); + private final JPasswordField mistralApiKeyField = new JPasswordField(stateService.getMistralKey()); @Getter - private final JPasswordField anthropicApiKeyField = new JPasswordField(llmStateService.getAnthropicKey()); + private final JPasswordField anthropicApiKeyField = new JPasswordField(stateService.getAnthropicKey()); @Getter - private final JPasswordField groqApiKeyField = new JPasswordField(llmStateService.getGroqKey()); + private final JPasswordField groqApiKeyField = new JPasswordField(stateService.getGroqKey()); @Getter - private final JPasswordField deepInfraApiKeyField = new JPasswordField(llmStateService.getDeepInfraKey()); + private final JPasswordField deepInfraApiKeyField = new JPasswordField(stateService.getDeepInfraKey()); @Getter - private final JPasswordField geminiApiKeyField = new JPasswordField(llmStateService.getGeminiKey()); + private final JPasswordField geminiApiKeyField = new JPasswordField(stateService.getGeminiKey()); @Getter - private final JCheckBox hideSearchButtonsField = new JCheckBox("", llmStateService.getHideSearchButtonsFlag()); + private final JCheckBox hideSearchButtonsField = new JCheckBox("", stateService.getHideSearchButtonsFlag()); @Getter - private final JPasswordField tavilySearchApiKeyField = new JPasswordField(llmStateService.getTavilySearchKey()); + private final JPasswordField tavilySearchApiKeyField = new JPasswordField(stateService.getTavilySearchKey()); @Getter - private final JPasswordField googleSearchApiKeyField = new JPasswordField(llmStateService.getGoogleSearchKey()); + private final JPasswordField googleSearchApiKeyField = new JPasswordField(stateService.getGoogleSearchKey()); @Getter - private final JPasswordField googleCSIApiKeyField = new JPasswordField(llmStateService.getGoogleCSIKey()); + private final JPasswordField googleCSIApiKeyField = new JPasswordField(stateService.getGoogleCSIKey()); @Getter - private final JCheckBox streamModeCheckBox = new JCheckBox("", llmStateService.getStreamMode()); - - @Getter - private final JPanel panel; + private final JCheckBox streamModeCheckBox = new JCheckBox("", stateService.getStreamMode()); public LLMSettingsComponent() { - panel = FormBuilder.createFormBuilder() + addListeners(); + } + + @Override + public JPanel createSettingsPanel() { + return FormBuilder.createFormBuilder() .addComponent(new JXTitledSeparator("Local Large Language Response")) .addVerticalGap(5) .addComponent(new JLabel("Enable Stream Mode (Beta)")) @@ -98,7 +102,10 @@ public LLMSettingsComponent() { .addComponent(new JLabel("Hide Search Providers")) .addComponent(hideSearchButtonsField) .getPanel(); + } + @Override + public void addListeners() { hideSearchButtonsField.addItemListener(e -> { boolean selected = e.getStateChange() == ItemEvent.SELECTED; tavilySearchApiKeyField.setEnabled(!selected); @@ -142,5 +149,4 @@ public LLMSettingsComponent() { jPanel.add(btnApiKey, BorderLayout.EAST); return jPanel; } - } diff --git a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsConfigurable.java b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsConfigurable.java index 5efd80dd..02002a38 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsConfigurable.java +++ b/src/main/java/com/devoxx/genie/ui/settings/llm/LLMSettingsConfigurable.java @@ -1,6 +1,10 @@ package com.devoxx.genie.ui.settings.llm; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; +import com.devoxx.genie.ui.topic.AppTopics; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.Configurable; +import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; @@ -10,7 +14,11 @@ public class LLMSettingsConfigurable implements Configurable { - private final LLMSettingsComponent llmSettingsComponent = new LLMSettingsComponent(); + private final LLMSettingsComponent llmSettingsComponent; + + public LLMSettingsConfigurable() { + llmSettingsComponent = new LLMSettingsComponent(); + } /** * Get the display name @@ -29,7 +37,7 @@ public String getDisplayName() { @Nullable @Override public JComponent createComponent() { - return llmSettingsComponent.getPanel(); + return llmSettingsComponent.createSettingsPanel(); } /** @@ -38,14 +46,11 @@ public JComponent createComponent() { */ @Override public boolean isModified() { - LLMStateService settings = LLMStateService.getInstance(); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); boolean isModified = false; - isModified |= isFieldModified(llmSettingsComponent.getOllamaModelUrlField(), settings.getOllamaModelUrl()); - isModified |= isFieldModified(llmSettingsComponent.getLmStudioModelUrlField(), settings.getLmstudioModelUrl()); - isModified |= isFieldModified(llmSettingsComponent.getGpt4AllModelUrlField(), settings.getGpt4allModelUrl()); - isModified |= isFieldModified(llmSettingsComponent.getJanModelUrlField(), settings.getJanModelUrl()); + isModified |= !settings.getStreamMode().equals(llmSettingsComponent.getStreamModeCheckBox().isSelected()); isModified |= isFieldModified(llmSettingsComponent.getOpenAIKeyField(), settings.getOpenAIKey()); isModified |= isFieldModified(llmSettingsComponent.getMistralApiKeyField(), settings.getMistralKey()); @@ -54,21 +59,39 @@ public boolean isModified() { isModified |= isFieldModified(llmSettingsComponent.getDeepInfraApiKeyField(), settings.getDeepInfraKey()); isModified |= isFieldModified(llmSettingsComponent.getGeminiApiKeyField(), settings.getGeminiKey()); - isModified |= !settings.getStreamMode().equals(llmSettingsComponent.getStreamModeCheckBox().isSelected()); + isModified |= isFieldModified(llmSettingsComponent.getOllamaModelUrlField(), settings.getOllamaModelUrl()); + isModified |= isFieldModified(llmSettingsComponent.getLmStudioModelUrlField(), settings.getLmstudioModelUrl()); + isModified |= isFieldModified(llmSettingsComponent.getGpt4AllModelUrlField(), settings.getGpt4allModelUrl()); + isModified |= isFieldModified(llmSettingsComponent.getJanModelUrlField(), settings.getJanModelUrl()); isModified |= !settings.getHideSearchButtonsFlag().equals(llmSettingsComponent.getHideSearchButtonsField().isSelected()); + llmSettingsComponent.getHideSearchButtonsField().addItemListener(event -> { + String text = llmSettingsComponent.getHideSearchButtonsField().getText(); + settings.setHideSearchButtonsFlag(text.equals("true")); + }); + isModified |= isFieldModified(llmSettingsComponent.getTavilySearchApiKeyField(), settings.getTavilySearchKey()); isModified |= isFieldModified(llmSettingsComponent.getGoogleSearchApiKeyField(), settings.getGoogleSearchKey()); isModified |= isFieldModified(llmSettingsComponent.getGoogleCSIApiKeyField(), settings.getGoogleCSIKey()); + return isModified; } + private void notifySettingsChanged() { + MessageBus messageBus = ApplicationManager.getApplication().getMessageBus(); + messageBus.syncPublisher(AppTopics.SETTINGS_CHANGED_TOPIC).settingsChanged(); + } + /** * Apply the changes to the settings */ @Override public void apply() { - LLMStateService settings = LLMStateService.getInstance(); + boolean isModified = isModified(); + + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); + + settings.setStreamMode(llmSettingsComponent.getStreamModeCheckBox().isSelected()); settings.setOllamaModelUrl(llmSettingsComponent.getOllamaModelUrlField().getText()); settings.setLmstudioModelUrl(llmSettingsComponent.getLmStudioModelUrlField().getText()); @@ -86,6 +109,11 @@ public void apply() { settings.setTavilySearchKey(new String(llmSettingsComponent.getTavilySearchApiKeyField().getPassword())); settings.setGoogleSearchKey(new String(llmSettingsComponent.getGoogleSearchApiKeyField().getPassword())); settings.setGoogleCSIKey(new String(llmSettingsComponent.getGoogleCSIApiKeyField().getPassword())); + + // Only notify the listener if an API key has changed, so we can refresh the LLM providers list in the UI + if (isModified) { + notifySettingsChanged(); + } } /** @@ -93,7 +121,9 @@ public void apply() { */ @Override public void reset() { - LLMStateService settings = LLMStateService.getInstance(); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); + + llmSettingsComponent.getStreamModeCheckBox().setSelected(settings.getStreamMode()); llmSettingsComponent.getOllamaModelUrlField().setText(settings.getOllamaModelUrl()); llmSettingsComponent.getLmStudioModelUrlField().setText(settings.getLmstudioModelUrl()); @@ -111,6 +141,5 @@ public void reset() { llmSettingsComponent.getTavilySearchApiKeyField().setText(settings.getTavilySearchKey()); llmSettingsComponent.getGoogleSearchApiKeyField().setText(settings.getGoogleSearchKey()); llmSettingsComponent.getGoogleCSIApiKeyField().setText(settings.getGoogleCSIKey()); - } } diff --git a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsComponent.java index dbac993b..4327452b 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsComponent.java @@ -1,5 +1,7 @@ package com.devoxx.genie.ui.settings.llmconfig; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; +import com.devoxx.genie.ui.settings.SettingsComponent; import com.intellij.ide.ui.UINumericRange; import com.intellij.ui.JBIntSpinner; import com.intellij.util.ui.FormBuilder; @@ -9,38 +11,38 @@ import javax.swing.*; import java.awt.event.ItemEvent; -public class LLMConfigSettingsComponent { +public class LLMConfigSettingsComponent implements SettingsComponent { - public LLMConfigStateService llmConfigStateService = LLMConfigStateService.getInstance(); + private final DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); @Getter - private final JPanel panel; - - @Getter - private final JBIntSpinner chatMemorySizeField = new JBIntSpinner(new UINumericRange(llmConfigStateService.getChatMemorySize(), 1, 100)); + private final JBIntSpinner chatMemorySizeField = new JBIntSpinner(new UINumericRange(stateService.getChatMemorySize(), 1, 100)); @Getter - private final JSpinner temperatureField = new JSpinner(new SpinnerNumberModel(llmConfigStateService.getTemperature().doubleValue(), 0.0d, 1.0d, 0.1d)); + private final JSpinner temperatureField = new JSpinner(new SpinnerNumberModel(stateService.getTemperature().doubleValue(), 0.0d, 1.0d, 0.1d)); @Getter - private final JSpinner topPField = new JSpinner(new SpinnerNumberModel(llmConfigStateService.getTopP().doubleValue(), 0.0d, 1.0d, 0.1d)); + private final JSpinner topPField = new JSpinner(new SpinnerNumberModel(stateService.getTopP().doubleValue(), 0.0d, 1.0d, 0.1d)); @Getter - private final JBIntSpinner maxOutputTokensField = new JBIntSpinner(new UINumericRange(llmConfigStateService.getMaxOutputTokens(), 1, 1_000_000)); + private final JBIntSpinner maxOutputTokensField = new JBIntSpinner(new UINumericRange(stateService.getMaxOutputTokens(), 1, 1_000_000)); @Getter - private final JBIntSpinner timeoutField = new JBIntSpinner(new UINumericRange(llmConfigStateService.getTimeout(), 1, 60)); + private final JBIntSpinner timeoutField = new JBIntSpinner(new UINumericRange(stateService.getTimeout(), 1, 60)); @Getter - private final JBIntSpinner retryField = new JBIntSpinner(new UINumericRange(llmConfigStateService.getMaxRetries(), 1, 5)); + private final JBIntSpinner retryField = new JBIntSpinner(new UINumericRange(stateService.getMaxRetries(), 1, 5)); @Getter - private final JCheckBox astMode = new JCheckBox("", llmConfigStateService.getAstMode()); + private final JCheckBox astMode = new JCheckBox("", stateService.getAstMode()); @Getter - private final JCheckBox astParentClassCheckBox = new JCheckBox("", llmConfigStateService.getAstParentClass()); + private final JCheckBox astParentClassCheckBox = new JCheckBox("", stateService.getAstParentClass()); @Getter - private final JCheckBox astReferenceClassesCheckBox = new JCheckBox("", llmConfigStateService.getAstClassReference()); + private final JCheckBox astReferenceClassesCheckBox = new JCheckBox("", stateService.getAstClassReference()); @Getter - private final JCheckBox astReferenceFieldCheckBox = new JCheckBox("", llmConfigStateService.getAstFieldReference()); - + private final JCheckBox astReferenceFieldCheckBox = new JCheckBox("", stateService.getAstFieldReference()); public LLMConfigSettingsComponent() { + addListeners(); + } - panel = FormBuilder.createFormBuilder() + @Override + public JPanel createSettingsPanel() { + return FormBuilder.createFormBuilder() .addComponent(new JXTitledSeparator("Local Large Language Models")) .addVerticalGap(5) .addComponent(new JLabel("Chat Memory Size")) @@ -77,7 +79,10 @@ public LLMConfigSettingsComponent() { .addComponent(new JLabel("Include Field References")) .addComponent(astReferenceFieldCheckBox) .getPanel(); + } + @Override + public void addListeners() { astMode.addItemListener(e -> { boolean selected = e.getStateChange() == ItemEvent.SELECTED; astParentClassCheckBox.setEnabled(selected); diff --git a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsConfigurable.java b/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsConfigurable.java index 3b4b64f6..43903100 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsConfigurable.java +++ b/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigSettingsConfigurable.java @@ -1,5 +1,6 @@ package com.devoxx.genie.ui.settings.llmconfig; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.options.Configurable; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; @@ -8,7 +9,11 @@ public class LLMConfigSettingsConfigurable implements Configurable { - private final LLMConfigSettingsComponent llmConfigSettingsComponent = new LLMConfigSettingsComponent(); + private final LLMConfigSettingsComponent llmConfigSettingsComponent; + + public LLMConfigSettingsConfigurable() { + llmConfigSettingsComponent = new LLMConfigSettingsComponent(); + } /** * Get the display name @@ -27,7 +32,7 @@ public String getDisplayName() { @Nullable @Override public JComponent createComponent() { - return llmConfigSettingsComponent.getPanel(); + return llmConfigSettingsComponent.createSettingsPanel(); } /** @@ -36,21 +41,21 @@ public JComponent createComponent() { */ @Override public boolean isModified() { - LLMConfigStateService settingsState = LLMConfigStateService.getInstance(); + DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); boolean isModified = false; - isModified |= ((Double)llmConfigSettingsComponent.getTemperatureField().getValue()) != settingsState.getTemperature(); - isModified |= ((Double)llmConfigSettingsComponent.getTopPField().getValue()) != settingsState.getTopP(); - isModified |= llmConfigSettingsComponent.getMaxOutputTokensField().getNumber() != settingsState.getMaxOutputTokens(); - isModified |= llmConfigSettingsComponent.getChatMemorySizeField().getNumber() != settingsState.getChatMemorySize(); - isModified |= llmConfigSettingsComponent.getTimeoutField().getNumber() != settingsState.getTimeout(); - isModified |= llmConfigSettingsComponent.getRetryField().getNumber() != settingsState.getMaxRetries(); - - isModified |= !settingsState.getAstMode().equals(llmConfigSettingsComponent.getAstMode().isSelected()); - isModified |= !settingsState.getAstParentClass().equals(llmConfigSettingsComponent.getAstParentClassCheckBox().isSelected()); - isModified |= !settingsState.getAstClassReference().equals(llmConfigSettingsComponent.getAstReferenceClassesCheckBox().isSelected()); - isModified |= !settingsState.getAstFieldReference().equals(llmConfigSettingsComponent.getAstReferenceFieldCheckBox().isSelected()); + isModified |= llmConfigSettingsComponent.getTemperatureField().getValue() != stateService.getTemperature(); + isModified |= llmConfigSettingsComponent.getTopPField().getValue() != stateService.getTopP(); + isModified |= llmConfigSettingsComponent.getMaxOutputTokensField().getNumber() != stateService.getMaxOutputTokens(); + isModified |= llmConfigSettingsComponent.getChatMemorySizeField().getNumber() != stateService.getChatMemorySize(); + isModified |= llmConfigSettingsComponent.getTimeoutField().getNumber() != stateService.getTimeout(); + isModified |= llmConfigSettingsComponent.getRetryField().getNumber() != stateService.getMaxRetries(); + + isModified |= !stateService.getAstMode().equals(llmConfigSettingsComponent.getAstMode().isSelected()); + isModified |= !stateService.getAstParentClass().equals(llmConfigSettingsComponent.getAstParentClassCheckBox().isSelected()); + isModified |= !stateService.getAstClassReference().equals(llmConfigSettingsComponent.getAstReferenceClassesCheckBox().isSelected()); + isModified |= !stateService.getAstFieldReference().equals(llmConfigSettingsComponent.getAstReferenceFieldCheckBox().isSelected()); return isModified; } /** @@ -58,15 +63,15 @@ public boolean isModified() { */ @Override public void apply() { - LLMConfigStateService settingsState = LLMConfigStateService.getInstance(); + DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); - settingsState.setTemperature(((Double)llmConfigSettingsComponent.getTemperatureField().getValue())); - settingsState.setTopP(((Double)llmConfigSettingsComponent.getTopPField().getValue())); + stateService.setTemperature(((Double)llmConfigSettingsComponent.getTemperatureField().getValue())); + stateService.setTopP(((Double)llmConfigSettingsComponent.getTopPField().getValue())); - settingsState.setChatMemorySize(llmConfigSettingsComponent.getChatMemorySizeField().getNumber()); - settingsState.setMaxOutputTokens(llmConfigSettingsComponent.getMaxOutputTokensField().getNumber()); - settingsState.setTimeout(llmConfigSettingsComponent.getTimeoutField().getNumber()); - settingsState.setMaxRetries(llmConfigSettingsComponent.getRetryField().getNumber()); + stateService.setChatMemorySize(llmConfigSettingsComponent.getChatMemorySizeField().getNumber()); + stateService.setMaxOutputTokens(llmConfigSettingsComponent.getMaxOutputTokensField().getNumber()); + stateService.setTimeout(llmConfigSettingsComponent.getTimeoutField().getNumber()); + stateService.setMaxRetries(llmConfigSettingsComponent.getRetryField().getNumber()); } /** @@ -74,14 +79,14 @@ public void apply() { */ @Override public void reset() { - LLMConfigStateService settingsState = LLMConfigStateService.getInstance(); + DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); - llmConfigSettingsComponent.getTemperatureField().setValue(settingsState.getTemperature()); - llmConfigSettingsComponent.getTopPField().setValue(settingsState.getTopP()); + llmConfigSettingsComponent.getTemperatureField().setValue(stateService.getTemperature()); + llmConfigSettingsComponent.getTopPField().setValue(stateService.getTopP()); - llmConfigSettingsComponent.getMaxOutputTokensField().setNumber(settingsState.getMaxOutputTokens()); - llmConfigSettingsComponent.getChatMemorySizeField().setNumber(settingsState.getChatMemorySize()); - llmConfigSettingsComponent.getTimeoutField().setNumber(settingsState.getTimeout()); - llmConfigSettingsComponent.getRetryField().setNumber(settingsState.getMaxRetries()); + llmConfigSettingsComponent.getMaxOutputTokensField().setNumber(stateService.getMaxOutputTokens()); + llmConfigSettingsComponent.getChatMemorySizeField().setNumber(stateService.getChatMemorySize()); + llmConfigSettingsComponent.getTimeoutField().setNumber(stateService.getTimeout()); + llmConfigSettingsComponent.getRetryField().setNumber(stateService.getMaxRetries()); } } diff --git a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigStateService.java b/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigStateService.java deleted file mode 100644 index 5f77adb9..00000000 --- a/src/main/java/com/devoxx/genie/ui/settings/llmconfig/LLMConfigStateService.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.devoxx.genie.ui.settings.llmconfig; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.Service; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import lombok.Getter; -import lombok.Setter; -import org.jetbrains.annotations.NotNull; - -import static com.devoxx.genie.model.Constant.*; - -@Getter -@Setter -@Service -@State( - name = "com.devoxx.genie.ui.LLMConfigState", - storages = @Storage("DevoxxGenieLLMConfigPlugin.xml") -) -public final class LLMConfigStateService implements PersistentStateComponent { - - public static LLMConfigStateService getInstance() { - return ApplicationManager.getApplication().getService(LLMConfigStateService.class); - } - - // LLM settings - private Double temperature = TEMPERATURE; - private Double topP = TOP_P; - - private Integer timeout = TIMEOUT; - private Integer maxRetries = MAX_RETRIES; - private Integer chatMemorySize = MAX_MEMORY; - private Integer maxOutputTokens = MAX_OUTPUT_TOKENS; - - // Last selected LLM provider and model name - private String lastSelectedProvider; - private String lastSelectedModel; - - // Enable AST mode - private Boolean astMode = AST_MODE; - private Boolean astParentClass = AST_PARENT_CLASS; - private Boolean astClassReference = AST_CLASS_REFERENCE; - private Boolean astFieldReference = AST_FIELD_REFERENCE; - - @Override - public LLMConfigStateService getState() { - return this; - } - - @Override - public void loadState(@NotNull LLMConfigStateService state) { - XmlSerializerUtil.copyBean(state, this); - } -} diff --git a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsComponent.java index 844edb8f..09bfcf0a 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsComponent.java @@ -1,31 +1,35 @@ package com.devoxx.genie.ui.settings.prompt; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; +import com.devoxx.genie.ui.settings.SettingsComponent; import com.intellij.util.ui.FormBuilder; import lombok.Getter; import org.jdesktop.swingx.JXTitledSeparator; import com.intellij.ui.components.JBLabel; import javax.swing.*; -public class PromptSettingsComponent { +public class PromptSettingsComponent implements SettingsComponent { - public PromptSettingsStateService promptSettingsStateService = PromptSettingsStateService.getInstance(); + private final DevoxxGenieStateService stateService = DevoxxGenieStateService.getInstance(); @Getter - private final JTextArea systemPromptField = new JTextArea(promptSettingsStateService.getSystemPrompt()); + private final JTextArea systemPromptField = new JTextArea(stateService.getSystemPrompt()); @Getter - private final JTextArea testPromptField = new JTextArea(promptSettingsStateService.getTestPrompt()); + private final JTextArea testPromptField = new JTextArea(stateService.getTestPrompt()); @Getter - private final JTextArea explainPromptField = new JTextArea(promptSettingsStateService.getExplainPrompt()); + private final JTextArea explainPromptField = new JTextArea(stateService.getExplainPrompt()); @Getter - private final JTextArea reviewPromptField = new JTextArea(promptSettingsStateService.getReviewPrompt()); + private final JTextArea reviewPromptField = new JTextArea(stateService.getReviewPrompt()); @Getter - private final JTextArea customPromptField = new JTextArea(promptSettingsStateService.getCustomPrompt()); - - @Getter - private final JPanel panel; + private final JTextArea customPromptField = new JTextArea(stateService.getCustomPrompt()); public PromptSettingsComponent() { - panel = FormBuilder.createFormBuilder() + addListeners(); + } + + @Override + public JPanel createSettingsPanel() { + return FormBuilder.createFormBuilder() .addComponent(new JXTitledSeparator("Prompts")) .addVerticalGap(5) .addLabeledComponentFillVertically( @@ -37,7 +41,7 @@ public PromptSettingsComponent() { testPromptField, 10, true - ) + ) .addLabeledComponent( new JBLabel("Explain Prompt"), explainPromptField, @@ -58,4 +62,9 @@ public PromptSettingsComponent() { ) .getPanel(); } + + @Override + public void addListeners() { + + } } diff --git a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsConfigurable.java b/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsConfigurable.java index a815e314..90b4cd6c 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsConfigurable.java +++ b/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsConfigurable.java @@ -1,5 +1,6 @@ package com.devoxx.genie.ui.settings.prompt; +import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nls; @@ -11,7 +12,11 @@ public class PromptSettingsConfigurable implements Configurable { - private final PromptSettingsComponent promptSettingsComponent = new PromptSettingsComponent(); + private final PromptSettingsComponent promptSettingsComponent; + + public PromptSettingsConfigurable() { + promptSettingsComponent = new PromptSettingsComponent(); + } /** * Get the display name @@ -30,7 +35,7 @@ public String getDisplayName() { @Nullable @Override public JComponent createComponent() { - return promptSettingsComponent.getPanel(); + return promptSettingsComponent.createSettingsPanel(); } /** @@ -39,7 +44,7 @@ public JComponent createComponent() { */ @Override public boolean isModified() { - PromptSettingsStateService settings = PromptSettingsStateService.getInstance(); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); boolean isModified = false; @@ -57,7 +62,7 @@ public boolean isModified() { */ @Override public void apply() { - PromptSettingsStateService settings = PromptSettingsStateService.getInstance(); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); updateTextAreaIfModified(promptSettingsComponent.getSystemPromptField(), settings.getSystemPrompt(), settings::setSystemPrompt); updateTextAreaIfModified(promptSettingsComponent.getTestPromptField(), settings.getTestPrompt(), settings::setTestPrompt); updateTextAreaIfModified(promptSettingsComponent.getExplainPromptField(), settings.getExplainPrompt(), settings::setExplainPrompt); @@ -70,15 +75,14 @@ public void apply() { */ @Override public void reset() { - PromptSettingsStateService settingsState = PromptSettingsStateService.getInstance(); - promptSettingsComponent.getSystemPromptField().setText(settingsState.getSystemPrompt()); - promptSettingsComponent.getTestPromptField().setText(settingsState.getTestPrompt()); - promptSettingsComponent.getExplainPromptField().setText(settingsState.getExplainPrompt()); - promptSettingsComponent.getReviewPromptField().setText(settingsState.getReviewPrompt()); - promptSettingsComponent.getCustomPromptField().setText(settingsState.getCustomPrompt()); + DevoxxGenieStateService settings = DevoxxGenieStateService.getInstance(); + promptSettingsComponent.getSystemPromptField().setText(settings.getSystemPrompt()); + promptSettingsComponent.getTestPromptField().setText(settings.getTestPrompt()); + promptSettingsComponent.getExplainPromptField().setText(settings.getExplainPrompt()); + promptSettingsComponent.getReviewPromptField().setText(settings.getReviewPrompt()); + promptSettingsComponent.getCustomPromptField().setText(settings.getCustomPrompt()); } - /** * Update the text area if the value has changed * @param textArea the text area diff --git a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsStateService.java b/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsStateService.java deleted file mode 100644 index f10f2c45..00000000 --- a/src/main/java/com/devoxx/genie/ui/settings/prompt/PromptSettingsStateService.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.devoxx.genie.ui.settings.prompt; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.Service; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import lombok.Getter; -import lombok.Setter; -import org.jetbrains.annotations.NotNull; - -import static com.devoxx.genie.model.Constant.*; - -@Getter -@Setter -@Service -@State( - name = "com.devoxx.genie.ui.PromptSettingsState", - storages = @Storage("DevoxxGeniePromptSettingsPlugin.xml") -) -public final class PromptSettingsStateService implements PersistentStateComponent { - - // Prompt fields - private String systemPrompt = SYSTEM_PROMPT; - private String testPrompt = TEST_PROMPT; - private String reviewPrompt = REVIEW_PROMPT; - private String explainPrompt = EXPLAIN_PROMPT; - private String customPrompt = CUSTOM_PROMPT; - - public static PromptSettingsStateService getInstance() { - return ApplicationManager.getApplication().getService(PromptSettingsStateService.class); - } - - @Override - public PromptSettingsStateService getState() { - return this; - } - - @Override - public void loadState(@NotNull PromptSettingsStateService state) { - XmlSerializerUtil.copyBean(state, this); - } -}