diff --git a/build.gradle.kts b/build.gradle.kts index 94378ddd..2d452db2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "com.devoxx.genie" -version = "0.4.6" +version = "0.4.7" repositories { mavenCentral() diff --git a/core/src/main/java/com/devoxx/genie/model/LanguageModel.java b/core/src/main/java/com/devoxx/genie/model/LanguageModel.java index 75125c6f..0036f4c2 100644 --- a/core/src/main/java/com/devoxx/genie/model/LanguageModel.java +++ b/core/src/main/java/com/devoxx/genie/model/LanguageModel.java @@ -17,10 +17,19 @@ public class LanguageModel implements Comparable { private boolean apiKeyUsed; private double inputCost; private double outputCost; - private int contextWindow; + private int inputMaxTokens; + private int outputMaxTokens; public LanguageModel() { - this(ModelProvider.OpenAI, "", "", false, 0.0, 0.0, 0); + + this(ModelProvider.OpenAI, + "", + "", + false, + 0.0, + 0.0, + 0, + 0); } public LanguageModel(ModelProvider provider, @@ -29,14 +38,16 @@ public LanguageModel(ModelProvider provider, boolean apiKeyUsed, double inputCost, double outputCost, - int contextWindow) { + int inputMaxTokens, + int outputMaxTokens) { this.provider = provider; this.modelName = modelName; this.displayName = displayName; this.apiKeyUsed = apiKeyUsed; this.inputCost = inputCost; this.outputCost = outputCost; - this.contextWindow = contextWindow; + this.inputMaxTokens = inputMaxTokens; + this.outputMaxTokens = outputMaxTokens; } @Override diff --git a/src/main/java/com/devoxx/genie/action/AddDirectoryAction.java b/src/main/java/com/devoxx/genie/action/AddDirectoryAction.java index d38f2f09..ea938fb3 100644 --- a/src/main/java/com/devoxx/genie/action/AddDirectoryAction.java +++ b/src/main/java/com/devoxx/genie/action/AddDirectoryAction.java @@ -68,7 +68,7 @@ private void addDirectoryToContext(Project project, @NotNull VirtualFile directo .filter(model -> model.getProvider().getName().equals(selectedProvider.getName()) && model.getModelName().equals(selectedModel)) .findFirst() - .map(LanguageModel::getContextWindow); + .map(LanguageModel::getInputMaxTokens); ProjectContentService.getInstance() .getDirectoryContent(project, directory, contextWindow.orElse(settings.getDefaultWindowContext()), false) diff --git a/src/main/java/com/devoxx/genie/chatmodel/ChatModelFactoryProvider.java b/src/main/java/com/devoxx/genie/chatmodel/ChatModelFactoryProvider.java index b9c07eb2..61576494 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/ChatModelFactoryProvider.java +++ b/src/main/java/com/devoxx/genie/chatmodel/ChatModelFactoryProvider.java @@ -2,19 +2,19 @@ import com.devoxx.genie.chatmodel.cloud.anthropic.AnthropicChatModelFactory; import com.devoxx.genie.chatmodel.cloud.azureopenai.AzureOpenAIChatModelFactory; -import com.devoxx.genie.chatmodel.local.customopenai.CustomOpenAIChatModelFactory; import com.devoxx.genie.chatmodel.cloud.deepinfra.DeepInfraChatModelFactory; import com.devoxx.genie.chatmodel.cloud.deepseek.DeepSeekChatModelFactory; import com.devoxx.genie.chatmodel.cloud.google.GoogleChatModelFactory; -import com.devoxx.genie.chatmodel.local.gpt4all.GPT4AllChatModelFactory; import com.devoxx.genie.chatmodel.cloud.groq.GroqChatModelFactory; +import com.devoxx.genie.chatmodel.cloud.mistral.MistralChatModelFactory; +import com.devoxx.genie.chatmodel.cloud.openai.OpenAIChatModelFactory; +import com.devoxx.genie.chatmodel.cloud.openrouter.OpenRouterChatModelFactory; +import com.devoxx.genie.chatmodel.local.customopenai.CustomOpenAIChatModelFactory; +import com.devoxx.genie.chatmodel.local.gpt4all.GPT4AllChatModelFactory; import com.devoxx.genie.chatmodel.local.jan.JanChatModelFactory; import com.devoxx.genie.chatmodel.local.llamaCPP.LlamaChatModelFactory; import com.devoxx.genie.chatmodel.local.lmstudio.LMStudioChatModelFactory; -import com.devoxx.genie.chatmodel.cloud.mistral.MistralChatModelFactory; import com.devoxx.genie.chatmodel.local.ollama.OllamaChatModelFactory; -import com.devoxx.genie.chatmodel.cloud.openai.OpenAIChatModelFactory; -import com.devoxx.genie.chatmodel.cloud.openrouter.OpenRouterChatModelFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java b/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java index 08f455e3..e07be25c 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java +++ b/src/main/java/com/devoxx/genie/chatmodel/ChatModelProvider.java @@ -1,9 +1,5 @@ package com.devoxx.genie.chatmodel; -import com.devoxx.genie.chatmodel.local.gpt4all.GPT4AllChatModelFactory; -import com.devoxx.genie.chatmodel.local.jan.JanChatModelFactory; -import com.devoxx.genie.chatmodel.local.lmstudio.LMStudioChatModelFactory; -import com.devoxx.genie.chatmodel.local.ollama.OllamaChatModelFactory; import com.devoxx.genie.model.ChatModel; import com.devoxx.genie.model.Constant; import com.devoxx.genie.model.LanguageModel; diff --git a/src/main/java/com/devoxx/genie/chatmodel/cloud/azureopenai/AzureOpenAIChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/cloud/azureopenai/AzureOpenAIChatModelFactory.java index 09843225..4a9a5496 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/cloud/azureopenai/AzureOpenAIChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/cloud/azureopenai/AzureOpenAIChatModelFactory.java @@ -61,7 +61,7 @@ public List getModels() { .displayName(DevoxxGenieStateService.getInstance().getAzureOpenAIDeployment()) .inputCost(0.0) .outputCost(0.0) - .contextWindow(0) + .inputMaxTokens(0) .apiKeyUsed(true) .build()); } diff --git a/src/main/java/com/devoxx/genie/chatmodel/cloud/google/GoogleChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/cloud/google/GoogleChatModelFactory.java index 7abfb095..9126a891 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/cloud/google/GoogleChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/cloud/google/GoogleChatModelFactory.java @@ -10,7 +10,6 @@ import dev.langchain4j.model.googleai.GoogleAiGeminiStreamingChatModel; import org.jetbrains.annotations.NotNull; -import java.time.Duration; import java.util.List; public class GoogleChatModelFactory implements ChatModelFactory { diff --git a/src/main/java/com/devoxx/genie/chatmodel/cloud/openrouter/OpenRouterChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/cloud/openrouter/OpenRouterChatModelFactory.java index 9e7b7262..8dd63990 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/cloud/openrouter/OpenRouterChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/cloud/openrouter/OpenRouterChatModelFactory.java @@ -87,7 +87,7 @@ public List getModels() { .displayName(model.getName()) .inputCost(inputCost) .outputCost(outputCost) - .contextWindow(model.getContextLength() == null ? model.getTopProvider().getContextLength() : model.getContextLength()) + .inputMaxTokens(model.getContextLength() == null ? model.getTopProvider().getContextLength() : model.getContextLength()) .apiKeyUsed(true) .build(); synchronized (modelNames) { diff --git a/src/main/java/com/devoxx/genie/chatmodel/local/jan/JanChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/local/jan/JanChatModelFactory.java index ac44fa14..ed55af9e 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/local/jan/JanChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/local/jan/JanChatModelFactory.java @@ -47,7 +47,7 @@ protected LanguageModel buildLanguageModel(Object model) { .displayName(janModel.getName()) .inputCost(0) .outputCost(0) - .contextWindow(janModel.getCtxLen() == null ? 8_000 : janModel.getSettings().getCtxLen()) + .inputMaxTokens(janModel.getCtxLen() == null ? 8_000 : janModel.getSettings().getCtxLen()) .apiKeyUsed(false) .build(); } diff --git a/src/main/java/com/devoxx/genie/chatmodel/local/llamaCPP/LlamaChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/local/llamaCPP/LlamaChatModelFactory.java index b7dba021..885bde8e 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/local/llamaCPP/LlamaChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/local/llamaCPP/LlamaChatModelFactory.java @@ -35,7 +35,7 @@ public List getModels() { .displayName(TEST_MODEL) .inputCost(0) .outputCost(0) - .contextWindow(8000) + .inputMaxTokens(8000) .apiKeyUsed(false) .build(); diff --git a/src/main/java/com/devoxx/genie/chatmodel/local/lmstudio/LMStudioChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/local/lmstudio/LMStudioChatModelFactory.java index 93db5fa9..473351e9 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/local/lmstudio/LMStudioChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/local/lmstudio/LMStudioChatModelFactory.java @@ -58,7 +58,7 @@ protected LanguageModel buildLanguageModel(Object model) { .displayName(lmStudioModel.getId()) .inputCost(0) .outputCost(0) - .contextWindow(DEFAULT_CONTEXT_LENGTH) + .inputMaxTokens(DEFAULT_CONTEXT_LENGTH) .apiKeyUsed(false) .build(); } diff --git a/src/main/java/com/devoxx/genie/chatmodel/local/ollama/OllamaChatModelFactory.java b/src/main/java/com/devoxx/genie/chatmodel/local/ollama/OllamaChatModelFactory.java index 41f2400b..21898d10 100644 --- a/src/main/java/com/devoxx/genie/chatmodel/local/ollama/OllamaChatModelFactory.java +++ b/src/main/java/com/devoxx/genie/chatmodel/local/ollama/OllamaChatModelFactory.java @@ -64,7 +64,7 @@ protected LanguageModel buildLanguageModel(Object model) throws IOException { .displayName(ollamaModel.getName()) .inputCost(0) .outputCost(0) - .contextWindow(contextWindow) + .inputMaxTokens(contextWindow) .apiKeyUsed(false) .build(); } diff --git a/src/main/java/com/devoxx/genie/controller/ActionButtonsPanelController.java b/src/main/java/com/devoxx/genie/controller/ActionButtonsPanelController.java index e49c2587..a83ab5d5 100644 --- a/src/main/java/com/devoxx/genie/controller/ActionButtonsPanelController.java +++ b/src/main/java/com/devoxx/genie/controller/ActionButtonsPanelController.java @@ -136,7 +136,7 @@ private LanguageModel createDefaultLanguageModel(@NotNull DevoxxGenieSettingsSer .apiKeyUsed(false) .inputCost(0) .outputCost(0) - .contextWindow(4096) + .inputMaxTokens(4096) .build(); } else { String modelName = stateService.getSelectedLanguageModel(project.getLocationHash()); @@ -146,7 +146,7 @@ private LanguageModel createDefaultLanguageModel(@NotNull DevoxxGenieSettingsSer .apiKeyUsed(false) .inputCost(0) .outputCost(0) - .contextWindow(128_000) + .inputMaxTokens(128_000) .build(); } } diff --git a/src/main/java/com/devoxx/genie/controller/ProjectContextController.java b/src/main/java/com/devoxx/genie/controller/ProjectContextController.java index 5d167308..bdf08ca7 100644 --- a/src/main/java/com/devoxx/genie/controller/ProjectContextController.java +++ b/src/main/java/com/devoxx/genie/controller/ProjectContextController.java @@ -114,7 +114,7 @@ private int getWindowContext() { LanguageModel languageModel = (LanguageModel) modelNameComboBox.getSelectedItem(); int tokenLimit = 4096; if (languageModel != null) { - tokenLimit = languageModel.getContextWindow(); + tokenLimit = languageModel.getInputMaxTokens(); } return tokenLimit; } diff --git a/src/main/java/com/devoxx/genie/controller/TokenCalculationController.java b/src/main/java/com/devoxx/genie/controller/TokenCalculationController.java index 4b8b7394..ae064c0f 100644 --- a/src/main/java/com/devoxx/genie/controller/TokenCalculationController.java +++ b/src/main/java/com/devoxx/genie/controller/TokenCalculationController.java @@ -41,7 +41,7 @@ public void calculateTokensAndCost() { return; } - int maxTokens = selectedModel.getContextWindow(); + int maxTokens = selectedModel.getInputMaxTokens(); boolean isApiKeyBased = DefaultLLMSettingsUtil.isApiKeyBasedProvider(selectedProvider); // Perform the token and cost calculation diff --git a/src/main/java/com/devoxx/genie/service/ChatMemoryService.java b/src/main/java/com/devoxx/genie/service/ChatMemoryService.java index 1b86fb36..6490cea3 100644 --- a/src/main/java/com/devoxx/genie/service/ChatMemoryService.java +++ b/src/main/java/com/devoxx/genie/service/ChatMemoryService.java @@ -9,7 +9,10 @@ import com.devoxx.genie.util.ChatMessageContextUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import dev.langchain4j.data.message.*; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.data.message.SystemMessage; +import dev.langchain4j.data.message.UserMessage; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/devoxx/genie/service/LLMModelRegistryService.java b/src/main/java/com/devoxx/genie/service/LLMModelRegistryService.java index efba2894..8a97b1fe 100644 --- a/src/main/java/com/devoxx/genie/service/LLMModelRegistryService.java +++ b/src/main/java/com/devoxx/genie/service/LLMModelRegistryService.java @@ -46,7 +46,7 @@ private void addAnthropicModels() { .displayName("Claude 2.0") .inputCost(8) .outputCost(24) - .contextWindow(100_000) + .inputMaxTokens(100_000) .apiKeyUsed(true) .build()); @@ -58,7 +58,7 @@ private void addAnthropicModels() { .displayName("Claude 2.1") .inputCost(8) .outputCost(24) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); @@ -70,7 +70,7 @@ private void addAnthropicModels() { .displayName("Claude 3 Haiku") .inputCost(0.25) .outputCost(1.25) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); @@ -82,7 +82,7 @@ private void addAnthropicModels() { .displayName("Claude 3 Sonnet") .inputCost(3) .outputCost(15) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); @@ -94,7 +94,7 @@ private void addAnthropicModels() { .displayName("Claude 3 Opus") .inputCost(15) .outputCost(75) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); @@ -106,7 +106,7 @@ private void addAnthropicModels() { .displayName("Claude 3.5 Sonnet") .inputCost(3) .outputCost(15) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); @@ -118,13 +118,28 @@ private void addAnthropicModels() { .displayName("Claude 3.5 Haiku") .inputCost(1) .outputCost(5) - .contextWindow(200_000) + .inputMaxTokens(200_000) .apiKeyUsed(true) .build()); } private void addOpenAiModels() { + // TODO Add o3 and o3-mini when available in Feb 2025 + + String o1Model = "o1"; + models.put(ModelProvider.OpenAI.getName() + ":" + o1Model, + LanguageModel.builder() + .provider(ModelProvider.OpenAI) + .modelName(o1Model) + .displayName("o1") + .inputCost(5) + .outputCost(15) + .inputMaxTokens(200_000) + .outputMaxTokens(100_000) + .apiKeyUsed(true) + .build()); + String o1Mini = "o1-mini"; models.put(ModelProvider.OpenAI.getName() + ":" + o1Mini, LanguageModel.builder() @@ -133,7 +148,8 @@ private void addOpenAiModels() { .displayName("o1 mini") .inputCost(5) .outputCost(15) - .contextWindow(128_000) + .inputMaxTokens(128_000) + .outputMaxTokens(65_536) .apiKeyUsed(true) .build()); @@ -145,19 +161,8 @@ private void addOpenAiModels() { .displayName("o1 preview") .inputCost(10) .outputCost(30) - .contextWindow(128_000) - .apiKeyUsed(true) - .build()); - - String gpt35Turbo = GPT_3_5_TURBO.toString(); - models.put(ModelProvider.OpenAI.getName() + ":" + gpt35Turbo, - LanguageModel.builder() - .provider(ModelProvider.OpenAI) - .modelName(gpt35Turbo) - .displayName("GPT 3.5 Turbo") - .inputCost(0.5) - .outputCost(1.5) - .contextWindow(16_000) + .inputMaxTokens(128_000) + .outputMaxTokens(32_768) .apiKeyUsed(true) .build()); @@ -169,19 +174,8 @@ private void addOpenAiModels() { .displayName("GPT 4") .inputCost(30) .outputCost(60) - .contextWindow(8_000) - .apiKeyUsed(true) - .build()); - - String gpt4TurboPreview = GPT_4_TURBO_PREVIEW.toString(); - models.put(ModelProvider.OpenAI.getName() + ":" + gpt4TurboPreview, - LanguageModel.builder() - .provider(ModelProvider.OpenAI) - .modelName(gpt4TurboPreview) - .displayName("GPT 4 Turbo") - .inputCost(10) - .outputCost(30) - .contextWindow(128_000) + .inputMaxTokens(8_192) + .outputMaxTokens(8_192) .apiKeyUsed(true) .build()); @@ -193,7 +187,7 @@ private void addOpenAiModels() { .displayName("GPT 4o") .inputCost(5) .outputCost(15) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); @@ -205,7 +199,34 @@ private void addOpenAiModels() { .displayName("GPT 4o mini") .inputCost(0.15) .outputCost(0.6) - .contextWindow(128_000) + .inputMaxTokens(128_000) + .outputMaxTokens(16_384) + .apiKeyUsed(true) + .build()); + + String gpt4TurboPreview = GPT_4_TURBO_PREVIEW.toString(); + models.put(ModelProvider.OpenAI.getName() + ":" + gpt4TurboPreview, + LanguageModel.builder() + .provider(ModelProvider.OpenAI) + .modelName(gpt4TurboPreview) + .displayName("GPT 4 Turbo") + .inputCost(10) + .outputCost(30) + .inputMaxTokens(128_000) + .outputMaxTokens(4_096) + .apiKeyUsed(true) + .build()); + + String gpt35Turbo = GPT_3_5_TURBO.toString(); + models.put(ModelProvider.OpenAI.getName() + ":" + gpt35Turbo, + LanguageModel.builder() + .provider(ModelProvider.OpenAI) + .modelName(gpt35Turbo) + .displayName("GPT 3.5 Turbo") + .inputCost(0.5) + .outputCost(1.5) + .inputMaxTokens(16_385) + .outputMaxTokens(4_096) .apiKeyUsed(true) .build()); @@ -217,7 +238,7 @@ private void addOpenAiModels() { .displayName("Custom Model") .inputCost(0.15) .outputCost(0.6) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); } @@ -231,7 +252,7 @@ private void addDeepInfraModels() { .displayName("Meta Llama 3.1 405B") .inputCost(2.7) .outputCost(2.7) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -243,7 +264,7 @@ private void addDeepInfraModels() { .displayName("Meta Llama 3.1 70B") .inputCost(0.35) .outputCost(0.4) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); @@ -255,7 +276,7 @@ private void addDeepInfraModels() { .displayName("Meta Llama 3.1 8B") .inputCost(0.055) .outputCost(0.055) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); @@ -267,7 +288,7 @@ private void addDeepInfraModels() { .displayName("Mistral Nemo 12B") .inputCost(0.13) .outputCost(0.13) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); @@ -279,7 +300,7 @@ private void addDeepInfraModels() { .displayName("Mixtral 8x7B Instruct v0.1") .inputCost(0.24) .outputCost(0.24) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -291,7 +312,7 @@ private void addDeepInfraModels() { .displayName("Mixtral 8x22B Instruct v0.1") .inputCost(0.65) .outputCost(0.65) - .contextWindow(64_000) + .inputMaxTokens(64_000) .apiKeyUsed(true) .build()); @@ -303,7 +324,7 @@ private void addDeepInfraModels() { .displayName("Mistral 7B Instruct v0.3") .inputCost(0.07) .outputCost(0.07) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -315,7 +336,7 @@ private void addDeepInfraModels() { .displayName("Wizard LM 2 8x22B") .inputCost(0.5) .outputCost(0.5) - .contextWindow(64_000) + .inputMaxTokens(64_000) .apiKeyUsed(true) .build()); @@ -327,7 +348,7 @@ private void addDeepInfraModels() { .displayName("Wizard LM 2 7B") .inputCost(0.055) .outputCost(0.055) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -339,7 +360,7 @@ private void addDeepInfraModels() { .displayName("OpenChat 3.5") .inputCost(0.055) .outputCost(0.055) - .contextWindow(8_000) + .inputMaxTokens(8_000) .apiKeyUsed(true) .build()); @@ -351,7 +372,7 @@ private void addDeepInfraModels() { .displayName("Gemma 2 9B it") .inputCost(0.06) .outputCost(0.06) - .contextWindow(4_000) + .inputMaxTokens(4_000) .apiKeyUsed(true) .build()); } @@ -362,7 +383,6 @@ private void addDeepInfraModels() { * @see V1 Gemini models */ private void addGeminiModels() { - String gemini15Flash = "gemini-1.5-flash"; models.put(ModelProvider.Google.getName() + ":" + gemini15Flash, LanguageModel.builder() @@ -371,7 +391,21 @@ private void addGeminiModels() { .displayName("Gemini 1.5 Flash") .inputCost(0.0375) .outputCost(0.6) - .contextWindow(1_000_000) + .inputMaxTokens(1_048_576) + .outputMaxTokens(8_192) + .apiKeyUsed(true) + .build()); + + String gemini15Flash8B = "gemini-1.5-flash-8b"; + models.put(ModelProvider.Google.getName() + ":" + gemini15Flash8B, + LanguageModel.builder() + .provider(ModelProvider.Google) + .modelName(gemini15Flash8B) + .displayName("Gemini 1.5 Flash 8B") + .inputCost(0.0375) + .outputCost(0.6) + .inputMaxTokens(1_048_576) + .outputMaxTokens(8_192) .apiKeyUsed(true) .build()); @@ -383,7 +417,8 @@ private void addGeminiModels() { .displayName("Gemini 1.5 Pro") .inputCost(7) .outputCost(21) - .contextWindow(2_000_000) + .inputMaxTokens(2_097_152) + .outputMaxTokens(8_192) .apiKeyUsed(true) .build()); @@ -392,10 +427,22 @@ private void addGeminiModels() { LanguageModel.builder() .provider(ModelProvider.Google) .modelName(gemini15ProExp0801) - .displayName("Gemini 1.5 Pro 0801") + .displayName("Gemini 1.5 Pro Exp. 0801") .inputCost(7) .outputCost(21) - .contextWindow(2_000_000) + .inputMaxTokens(2_000_000) + .apiKeyUsed(true) + .build()); + + String geminiLearnLM = "learnlm-1.5-pro-experimental"; + models.put(ModelProvider.Google.getName() + ":" + geminiLearnLM, + LanguageModel.builder() + .provider(ModelProvider.Google) + .modelName(geminiLearnLM) + .displayName("Learn LM 1.5 Pro Exp.") + .inputCost(0) + .outputCost(0) + .inputMaxTokens(2_000_000) .apiKeyUsed(true) .build()); @@ -404,10 +451,10 @@ private void addGeminiModels() { LanguageModel.builder() .provider(ModelProvider.Google) .modelName(geminiExp1206) - .displayName("Gemini Exp 1206") + .displayName("Gemini Exp. 1206") .inputCost(0) .outputCost(0) - .contextWindow(2_000_000) + .inputMaxTokens(2_000_000) .apiKeyUsed(true) .build()); @@ -416,13 +463,26 @@ private void addGeminiModels() { LanguageModel.builder() .provider(ModelProvider.Google) .modelName(gemini2FlashExp) - .displayName("Gemini 2.0 Flash Exp") + .displayName("Gemini 2.0 Flash Exp.") .inputCost(0) .outputCost(0) - .contextWindow(1_000_000) + .inputMaxTokens(1_048_576) + .outputMaxTokens(8_192) .apiKeyUsed(true) .build()); + String geminiFlashThinking = "gemini-2.0-flash-thinking-exp-1219"; + models.put(ModelProvider.Google.getName() + ":" + geminiFlashThinking, + LanguageModel.builder() + .provider(ModelProvider.Google) + .modelName(geminiFlashThinking) + .displayName("Gemini 2.0 Flash Thinking Exp.") + .inputCost(0) + .outputCost(0) + .inputMaxTokens(32_000) + .outputMaxTokens(8_000) + .apiKeyUsed(true) + .build()); } private void addGroqModels() { @@ -435,7 +495,7 @@ private void addGroqModels() { .displayName("Gemma 7B it") .inputCost(0.07) .outputCost(0.07) - .contextWindow(8_192) + .inputMaxTokens(8_192) .apiKeyUsed(true) .build()); @@ -447,7 +507,7 @@ private void addGroqModels() { .displayName("Gemma 2 9B it") .inputCost(0.2) .outputCost(0.2) - .contextWindow(8_192) + .inputMaxTokens(8_192) .apiKeyUsed(true) .build()); @@ -459,7 +519,7 @@ private void addGroqModels() { .displayName("Llama 3 8B") .inputCost(0.05) .outputCost(0.05) - .contextWindow(8_000) + .inputMaxTokens(8_000) .apiKeyUsed(true) .build()); @@ -471,7 +531,7 @@ private void addGroqModels() { .displayName("Llama 3.1 70B") .inputCost(0.59) .outputCost(0.79) - .contextWindow(131_072) + .inputMaxTokens(131_072) .apiKeyUsed(true) .build()); @@ -483,7 +543,7 @@ private void addGroqModels() { .displayName("Llama 3.1 8B") .inputCost(0.05) .outputCost(0.08) - .contextWindow(131_072) + .inputMaxTokens(131_072) .apiKeyUsed(true) .build()); @@ -495,7 +555,7 @@ private void addGroqModels() { .displayName("Mixtral 8x7B") .inputCost(0.24) .outputCost(0.24) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -507,7 +567,7 @@ private void addGroqModels() { .displayName("Llama 3 70B") .inputCost(0.59) .outputCost(0.79) - .contextWindow(8192) + .inputMaxTokens(8192) .apiKeyUsed(true) .build()); } @@ -521,7 +581,7 @@ private void addMistralModels() { .displayName("Mistral 7B") .inputCost(0.25) .outputCost(0.25) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -533,7 +593,7 @@ private void addMistralModels() { .displayName("Mistral 8x7B") .inputCost(0.7) .outputCost(0.7) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -545,7 +605,7 @@ private void addMistralModels() { .displayName("Mistral 8x22b") .inputCost(2) .outputCost(6) - .contextWindow(64_000) + .inputMaxTokens(64_000) .apiKeyUsed(true) .build()); @@ -557,7 +617,7 @@ private void addMistralModels() { .displayName("Mistral Small") .inputCost(1) .outputCost(3) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -569,7 +629,7 @@ private void addMistralModels() { .displayName("Mistral Medium") .inputCost(2.7) .outputCost(0.1) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -581,7 +641,7 @@ private void addMistralModels() { .displayName("Mistral Large") .inputCost(4) .outputCost(12) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); @@ -593,7 +653,7 @@ private void addMistralModels() { .displayName("Codestral") .inputCost(1) .outputCost(3) - .contextWindow(32_000) + .inputMaxTokens(32_000) .apiKeyUsed(true) .build()); } @@ -607,7 +667,7 @@ private void addDeepSeekModels() { .displayName("DeepSeek Coder") .inputCost(0.14) .outputCost(0.28) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); @@ -619,7 +679,7 @@ private void addDeepSeekModels() { .displayName("DeepSeek Chat") .inputCost(0.14) .outputCost(0.28) - .contextWindow(128_000) + .inputMaxTokens(128_000) .apiKeyUsed(true) .build()); } diff --git a/src/main/java/com/devoxx/genie/service/MessageCreationService.java b/src/main/java/com/devoxx/genie/service/MessageCreationService.java index 1adbd45b..1b312d7c 100644 --- a/src/main/java/com/devoxx/genie/service/MessageCreationService.java +++ b/src/main/java/com/devoxx/genie/service/MessageCreationService.java @@ -14,7 +14,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import dev.langchain4j.data.message.TextContent; import dev.langchain4j.data.message.UserMessage; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java index 4a85ca17..95145da9 100644 --- a/src/main/java/com/devoxx/genie/service/PromptExecutionService.java +++ b/src/main/java/com/devoxx/genie/service/PromptExecutionService.java @@ -10,7 +10,9 @@ import com.devoxx.genie.util.ChatMessageContextUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import dev.langchain4j.data.message.*; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.data.message.SystemMessage; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.output.Response; import lombok.Getter; diff --git a/src/main/java/com/devoxx/genie/service/TokenCalculationService.java b/src/main/java/com/devoxx/genie/service/TokenCalculationService.java index ee68745b..036c23f9 100644 --- a/src/main/java/com/devoxx/genie/service/TokenCalculationService.java +++ b/src/main/java/com/devoxx/genie/service/TokenCalculationService.java @@ -99,9 +99,9 @@ private void showInfoForCloudProvider(@NotNull Project project, message = getTotalFilesAndEstimatedCostMessage(selectedProvider, languageModel, scanResult, estimatedInputCost); } - if (scanResult.getTokenCount() > languageModel.getContextWindow()) { + if (scanResult.getTokenCount() > languageModel.getInputMaxTokens()) { message += String.format(". Total project size exceeds model's max context of %s tokens.", - WindowContextFormatterUtil.format(languageModel.getContextWindow())); + WindowContextFormatterUtil.format(languageModel.getInputMaxTokens())); } listener.onTokenCalculationComplete(message); }), () -> { diff --git a/src/main/java/com/devoxx/genie/service/rag/validator/NomicEmbedTextValidator.java b/src/main/java/com/devoxx/genie/service/rag/validator/NomicEmbedTextValidator.java index 41608c67..15838960 100644 --- a/src/main/java/com/devoxx/genie/service/rag/validator/NomicEmbedTextValidator.java +++ b/src/main/java/com/devoxx/genie/service/rag/validator/NomicEmbedTextValidator.java @@ -1,7 +1,7 @@ package com.devoxx.genie.service.rag.validator; -import com.devoxx.genie.model.ollama.OllamaModelEntryDTO; import com.devoxx.genie.chatmodel.local.ollama.OllamaModelService; +import com.devoxx.genie.model.ollama.OllamaModelEntryDTO; import com.devoxx.genie.ui.settings.DevoxxGenieStateService; public class NomicEmbedTextValidator implements Validator { diff --git a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java index b85ea0e4..3d5cf4a8 100644 --- a/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java +++ b/src/main/java/com/devoxx/genie/ui/DevoxxGenieToolWindowContent.java @@ -193,7 +193,7 @@ private void processModelNameSelection(@NotNull ActionEvent e) { LanguageModel selectedModel = (LanguageModel) llmProviderPanel.getModelNameComboBox().getSelectedItem(); if (selectedModel != null) { DevoxxGenieStateService.getInstance().setSelectedLanguageModel(project.getLocationHash(), selectedModel.getModelName()); - submitPanel.getActionButtonsPanel().updateTokenUsage(selectedModel.getContextWindow()); + submitPanel.getActionButtonsPanel().updateTokenUsage(selectedModel.getInputMaxTokens()); } } } diff --git a/src/main/java/com/devoxx/genie/ui/panel/ChatResponsePanel.java b/src/main/java/com/devoxx/genie/ui/panel/ChatResponsePanel.java index 7a0a0774..ca510a29 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/ChatResponsePanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/ChatResponsePanel.java @@ -4,6 +4,7 @@ import com.devoxx.genie.ui.panel.chatresponse.*; import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import org.jetbrains.annotations.NotNull; + import javax.swing.*; public class ChatResponsePanel extends BackgroundPanel { 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 7c312d17..df598729 100644 --- a/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java +++ b/src/main/java/com/devoxx/genie/ui/panel/PromptOutputPanel.java @@ -248,7 +248,7 @@ private ChatMessageContext createChatMessageContext(@NotNull Conversation conver .apiKeyUsed(conversation.getApiKeyUsed()) .inputCost(conversation.getInputCost() == null ? 0 : conversation.getInputCost()) .outputCost(conversation.getOutputCost() == null ? 0 : conversation.getOutputCost()) - .contextWindow(conversation.getContextWindow() == null ? 0 : conversation.getContextWindow()) + .inputMaxTokens(conversation.getContextWindow() == null ? 0 : conversation.getContextWindow()) .build()) .cost(0).build(); } diff --git a/src/main/java/com/devoxx/genie/ui/renderer/ModelInfoRenderer.java b/src/main/java/com/devoxx/genie/ui/renderer/ModelInfoRenderer.java index 73f5eec0..253f43a3 100644 --- a/src/main/java/com/devoxx/genie/ui/renderer/ModelInfoRenderer.java +++ b/src/main/java/com/devoxx/genie/ui/renderer/ModelInfoRenderer.java @@ -36,13 +36,13 @@ public Component getListCellRendererComponent(JList lis infoLabel.setText(""); } else { nameLabel.setText(model.getDisplayName()); - String windowContext = WindowContextFormatterUtil.format(model.getContextWindow(), "tokens"); + String windowContext = WindowContextFormatterUtil.format(model.getInputMaxTokens(), "tokens"); if (model.getInputCost() > 0.0) { double cost; if (model.getProvider().getName().equalsIgnoreCase("openrouter")) { - cost = model.getInputCost() * model.getContextWindow(); + cost = model.getInputCost() * model.getInputMaxTokens(); } else { - cost = (model.getInputCost() / 1_000_000) * model.getContextWindow(); + cost = (model.getInputCost() / 1_000_000) * model.getInputMaxTokens(); } infoLabel.setText(String.format("%s @ %s USD", windowContext, decimalFormat.format(cost))); } else { diff --git a/src/main/java/com/devoxx/genie/ui/settings/costsettings/LanguageModelCostSettingsComponent.java b/src/main/java/com/devoxx/genie/ui/settings/costsettings/LanguageModelCostSettingsComponent.java index e70eda51..9be04451 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/costsettings/LanguageModelCostSettingsComponent.java +++ b/src/main/java/com/devoxx/genie/ui/settings/costsettings/LanguageModelCostSettingsComponent.java @@ -102,7 +102,7 @@ private void loadCurrentCosts() { model.getModelName(), model.getInputCost(), model.getOutputCost(), - NumberFormat.getInstance().format(model.getContextWindow()) + NumberFormat.getInstance().format(model.getInputMaxTokens()) })); } diff --git a/src/main/java/com/devoxx/genie/ui/settings/rag/RAGSettingsHandler.java b/src/main/java/com/devoxx/genie/ui/settings/rag/RAGSettingsHandler.java index 6c2c1193..2cb7c7b8 100644 --- a/src/main/java/com/devoxx/genie/ui/settings/rag/RAGSettingsHandler.java +++ b/src/main/java/com/devoxx/genie/ui/settings/rag/RAGSettingsHandler.java @@ -1,8 +1,8 @@ package com.devoxx.genie.ui.settings.rag; +import com.devoxx.genie.chatmodel.local.ollama.OllamaModelService; import com.devoxx.genie.service.chromadb.ChromaDBManager; import com.devoxx.genie.service.chromadb.ChromaDBStatusCallback; -import com.devoxx.genie.chatmodel.local.ollama.OllamaModelService; import com.devoxx.genie.service.rag.RagValidatorService; import com.devoxx.genie.service.rag.validator.ValidationActionType; import com.devoxx.genie.service.rag.validator.ValidationResult; diff --git a/src/main/java/com/devoxx/genie/ui/util/HelpUtil.java b/src/main/java/com/devoxx/genie/ui/util/HelpUtil.java index d64dd382..9f71beb7 100644 --- a/src/main/java/com/devoxx/genie/ui/util/HelpUtil.java +++ b/src/main/java/com/devoxx/genie/ui/util/HelpUtil.java @@ -3,6 +3,7 @@ import com.devoxx.genie.ui.settings.DevoxxGenieStateService; import com.intellij.ui.scale.JBUIScale; import org.jetbrains.annotations.NotNull; + import java.util.stream.Collectors; public class HelpUtil { diff --git a/src/main/java/com/devoxx/genie/util/ChatMessageContextUtil.java b/src/main/java/com/devoxx/genie/util/ChatMessageContextUtil.java index ed3f4e17..9fee2795 100644 --- a/src/main/java/com/devoxx/genie/util/ChatMessageContextUtil.java +++ b/src/main/java/com/devoxx/genie/util/ChatMessageContextUtil.java @@ -15,14 +15,10 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import dev.langchain4j.data.message.UserMessage; import org.jetbrains.annotations.NotNull; import java.util.List; -import static com.devoxx.genie.model.Constant.GOOGLE_SEARCH_ACTION; -import static com.devoxx.genie.model.Constant.TAVILY_SEARCH_ACTION; - public class ChatMessageContextUtil { public static final int ZERO_SECONDS = 0; diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index a7f20d81..84bc6204 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,10 @@ ]]> V0.4.7 +
    +
  • Feat #411: Add more preview (experimental) Gemini and Open AI models
  • +

V0.4.6

  • Fix #196 : Continue with prompt if '/' command is unknown
  • diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a23105ca..264ef405 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,2 @@ -#Thu Dec 19 10:30:01 CET 2024 +#Sat Dec 21 10:22:03 CET 2024 version=0.4.6 diff --git a/src/test/java/com/devoxx/genie/service/PromptExecutionServiceIT.java b/src/test/java/com/devoxx/genie/service/PromptExecutionServiceIT.java index 1fc0f7bf..e490aa79 100644 --- a/src/test/java/com/devoxx/genie/service/PromptExecutionServiceIT.java +++ b/src/test/java/com/devoxx/genie/service/PromptExecutionServiceIT.java @@ -62,7 +62,7 @@ public void testExecuteQueryOpenAI() { .apiKeyUsed(true) .inputCost(0.0) .outputCost(0.0) - .contextWindow(4096) + .inputMaxTokens(4096) .build(); verifyResponse(createChatModel(model), model); } @@ -76,7 +76,7 @@ public void testExecuteQueryAnthropic() { .apiKeyUsed(true) .inputCost(0.0) .outputCost(0.0) - .contextWindow(100000) + .inputMaxTokens(100000) .build(); verifyResponse(createChatModel(model), model); } @@ -90,7 +90,7 @@ public void testExecuteQueryGemini() { .apiKeyUsed(true) .inputCost(0.0) .outputCost(0.0) - .contextWindow(32768) + .inputMaxTokens(32768) .build(); verifyResponse(createChatModel(model), model); } @@ -104,7 +104,7 @@ public void testExecuteQueryMistral() { .apiKeyUsed(true) .inputCost(0.0) .outputCost(0.0) - .contextWindow(32768) + .inputMaxTokens(32768) .build(); verifyResponse(createChatModel(model), model); } @@ -118,7 +118,7 @@ public void testExecuteQueryDeepInfra() { .apiKeyUsed(true) .inputCost(0.0) .outputCost(0.0) - .contextWindow(32768) + .inputMaxTokens(32768) .build(); verifyResponse(createChatModel(model), model); }