From 331e41fa725da1205de08c3a28970b9258393059 Mon Sep 17 00:00:00 2001 From: Carl-Robert Linnupuu Date: Mon, 21 Jul 2025 16:34:57 +0100 Subject: [PATCH] feat: add kimi k2 model --- .../java/ee/carlrobert/codegpt/Icons.java | 1 + .../codegpt/settings/models/ModelIcons.kt | 1 + .../codegpt/settings/models/ModelRegistry.kt | 30 +++++++------- .../service/codegpt/CodeGPTAvailableModels.kt | 39 +------------------ src/main/resources/icons/moonshot.svg | 7 ++++ src/main/resources/icons/moonshot_dark.svg | 7 ++++ .../settings/models/ModelRegistryTest.kt | 4 +- .../models/ModelSelectionServiceTest.kt | 2 +- 8 files changed, 33 insertions(+), 58 deletions(-) create mode 100644 src/main/resources/icons/moonshot.svg create mode 100644 src/main/resources/icons/moonshot_dark.svg diff --git a/src/main/java/ee/carlrobert/codegpt/Icons.java b/src/main/java/ee/carlrobert/codegpt/Icons.java index 4bdafab9..6f501587 100644 --- a/src/main/java/ee/carlrobert/codegpt/Icons.java +++ b/src/main/java/ee/carlrobert/codegpt/Icons.java @@ -24,6 +24,7 @@ public final class Icons { public static final Icon MCP = IconLoader.getIcon("/icons/mcp.svg", Icons.class); public static final Icon Meta = IconLoader.getIcon("/icons/meta.svg", Icons.class); public static final Icon Mistral = IconLoader.getIcon("/icons/mistral.svg", Icons.class); + public static final Icon Moonshot = IconLoader.getIcon("/icons/moonshot.svg", Icons.class); public static final Icon Send = IconLoader.getIcon("/icons/send.svg", Icons.class); public static final Icon Sparkle = IconLoader.getIcon("/icons/sparkle.svg", Icons.class); public static final Icon Ollama = IconLoader.getIcon("/icons/ollama.svg", Icons.class); diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelIcons.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelIcons.kt index e889dc64..433ed3e2 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelIcons.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelIcons.kt @@ -18,6 +18,7 @@ object ModelIcons { ModelRegistry.CLAUDE_4_SONNET_THINKING, ModelRegistry.CLAUDE_4_SONNET -> Icons.Anthropic ModelRegistry.GEMINI_PRO_2_5, ModelRegistry.GEMINI_FLASH_2_5 -> Icons.Google ModelRegistry.DEEPSEEK_R1, ModelRegistry.DEEPSEEK_V3 -> Icons.DeepSeek + ModelRegistry.KIMI_K2 -> Icons.Moonshot "qwen-2.5-32b-chat", ModelRegistry.QWEN_2_5_32B_CODE -> Icons.Qwen "llama-3.1-405b" -> Icons.Meta else -> Icons.DefaultSmall diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistry.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistry.kt index 69b3ab0e..50fb3489 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistry.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistry.kt @@ -135,23 +135,11 @@ class ModelRegistry { FeatureType.NEXT_EDIT to ModelSelection(ServiceType.PROXYAI, ZETA, "Zeta") ), PricingPlan.FREE to mapOf( - FeatureType.CHAT to ModelSelection(ServiceType.PROXYAI, DEEPSEEK_V3, "DeepSeek V3"), - FeatureType.AUTO_APPLY to ModelSelection( - ServiceType.PROXYAI, - DEEPSEEK_V3, - "DeepSeek V3" - ), - FeatureType.COMMIT_MESSAGE to ModelSelection( - ServiceType.PROXYAI, - DEEPSEEK_V3, - "DeepSeek V3" - ), - FeatureType.EDIT_CODE to ModelSelection( - ServiceType.PROXYAI, - DEEPSEEK_V3, - "DeepSeek V3" - ), - FeatureType.LOOKUP to ModelSelection(ServiceType.PROXYAI, DEEPSEEK_V3, "DeepSeek V3"), + FeatureType.CHAT to ModelSelection(ServiceType.PROXYAI, KIMI_K2, "Kimi K2"), + FeatureType.AUTO_APPLY to ModelSelection(ServiceType.PROXYAI, KIMI_K2, "Kimi K2"), + FeatureType.COMMIT_MESSAGE to ModelSelection(ServiceType.PROXYAI, KIMI_K2, "Kimi K2"), + FeatureType.EDIT_CODE to ModelSelection(ServiceType.PROXYAI, KIMI_K2, "Kimi K2"), + FeatureType.LOOKUP to ModelSelection(ServiceType.PROXYAI, KIMI_K2, "Kimi K2"), FeatureType.CODE_COMPLETION to ModelSelection( ServiceType.PROXYAI, QWEN_2_5_32B_CODE, @@ -368,6 +356,13 @@ class ModelRegistry { "DeepSeek V3", Icons.DeepSeek, PricingPlan.FREE + ), + ModelSelection( + ServiceType.PROXYAI, + KIMI_K2, + "Kimi K2", + Icons.Moonshot, + PricingPlan.FREE ) ) } @@ -544,6 +539,7 @@ class ModelRegistry { const val DEEPSEEK_V3 = "deepseek-v3" const val QWEN_2_5_32B_CODE = "qwen-2.5-32b-code" const val ZETA = "zeta" + const val KIMI_K2 = "kimi-k2-instruct" // OpenAI Models const val GPT_3_5_TURBO_INSTRUCT = "gpt-3.5-turbo-instruct" diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt index c48bc7b4..7922a067 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTAvailableModels.kt @@ -7,46 +7,8 @@ import javax.swing.Icon object CodeGPTAvailableModels { - val DEFAULT_CHAT_MODEL = CodeGPTModel("Gemini 2.5 Flash", "gemini-flash-2.5", Icons.Google, ANONYMOUS) val DEFAULT_CODE_MODEL = CodeGPTModel("Qwen 2.5 Coder", "qwen-2.5-32b-code", Icons.Qwen, ANONYMOUS) - @JvmStatic - fun getToolWindowModels(pricingPlan: PricingPlan?): List { - return when (pricingPlan) { - null, ANONYMOUS -> listOf( - CodeGPTModel("o4-mini", "o4-mini", Icons.OpenAI, INDIVIDUAL), - CodeGPTModel("Gemini 2.5 Pro", "gemini-pro-2.5", Icons.Google, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4 (thinking)", "claude-4-sonnet-thinking", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4", "claude-4-sonnet", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL), - CodeGPTModel("Gemini 2.5 Flash", "gemini-flash-2.5", Icons.Google, ANONYMOUS), - CodeGPTModel("GPT-4.1 Mini", "gpt-4.1-mini", Icons.OpenAI, ANONYMOUS), - ) - - FREE -> listOf( - CodeGPTModel("o4-mini", "o4-mini", Icons.OpenAI, INDIVIDUAL), - CodeGPTModel("Gemini 2.5 Pro", "gemini-pro-2.5", Icons.Google, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4 (thinking)", "claude-4-sonnet-thinking", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4", "claude-4-sonnet", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL), - CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE), - CodeGPTModel("Gemini 2.5 Flash", "gemini-flash-2.5", Icons.Google, ANONYMOUS), - CodeGPTModel("GPT-4.1 Mini", "gpt-4.1-mini", Icons.OpenAI, ANONYMOUS), - ) - - INDIVIDUAL -> listOf( - CodeGPTModel("o4-mini", "o4-mini", Icons.OpenAI, INDIVIDUAL), - CodeGPTModel("GPT-4.1", "gpt-4.1", Icons.OpenAI, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4 (thinking)", "claude-4-sonnet-thinking", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("Claude Sonnet 4", "claude-4-sonnet", Icons.Anthropic, INDIVIDUAL), - CodeGPTModel("Gemini 2.5 Pro", "gemini-pro-2.5", Icons.Google, INDIVIDUAL), - CodeGPTModel("Gemini 2.5 Flash", "gemini-flash-2.5", Icons.Google, ANONYMOUS), - CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL), - CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE), - ) - } - } - @JvmStatic val ALL_CHAT_MODELS: List = listOf( CodeGPTModel("o4-mini", "o4-mini", Icons.OpenAI, INDIVIDUAL), @@ -58,6 +20,7 @@ object CodeGPTAvailableModels { CodeGPTModel("Gemini 2.5 Flash", "gemini-flash-2.5", Icons.Google, ANONYMOUS), CodeGPTModel("DeepSeek R1", "deepseek-r1", Icons.DeepSeek, INDIVIDUAL), CodeGPTModel("DeepSeek V3", "deepseek-v3", Icons.DeepSeek, FREE), + CodeGPTModel("Kimi K2", "kimi-k2", Icons.Moonshot, FREE), ) @JvmStatic diff --git a/src/main/resources/icons/moonshot.svg b/src/main/resources/icons/moonshot.svg new file mode 100644 index 00000000..9b19b01f --- /dev/null +++ b/src/main/resources/icons/moonshot.svg @@ -0,0 +1,7 @@ + + + MoonshotAI + + \ No newline at end of file diff --git a/src/main/resources/icons/moonshot_dark.svg b/src/main/resources/icons/moonshot_dark.svg new file mode 100644 index 00000000..cd55988c --- /dev/null +++ b/src/main/resources/icons/moonshot_dark.svg @@ -0,0 +1,7 @@ + + + MoonshotAI + + \ No newline at end of file diff --git a/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistryTest.kt b/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistryTest.kt index 758c7dbb..de1130cb 100644 --- a/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistryTest.kt +++ b/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelRegistryTest.kt @@ -27,8 +27,8 @@ class ModelRegistryTest : IntegrationTest() { val result = modelRegistry.getDefaultModelForFeature(FeatureType.CHAT, PricingPlan.FREE) assertThat(result.provider).isEqualTo(ServiceType.PROXYAI) - assertThat(result.model).isEqualTo("deepseek-v3") - assertThat(result.displayName).isEqualTo("DeepSeek V3") + assertThat(result.model).isEqualTo("kimi-k2-instruct") + assertThat(result.displayName).isEqualTo("Kimi K2") } fun `test getDefaultModelForFeature with anonymous plan returns basic model`() { diff --git a/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelSelectionServiceTest.kt b/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelSelectionServiceTest.kt index 4672c9f1..1b6604bc 100644 --- a/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelSelectionServiceTest.kt +++ b/src/test/kotlin/ee/carlrobert/codegpt/settings/models/ModelSelectionServiceTest.kt @@ -41,7 +41,7 @@ class ModelSelectionServiceTest : IntegrationTest() { modelSelectionService.getModelSelectionForFeature(FeatureType.CHAT, PricingPlan.FREE) assertThat(individualResult.model).isEqualTo("claude-4-sonnet-thinking") - assertThat(freeResult.model).isEqualTo("deepseek-v3") + assertThat(freeResult.model).isEqualTo("kimi-k2-instruct") } fun `test getModelSelectionForFeature with code completion returns code model`() {