-
Notifications
You must be signed in to change notification settings - Fork 0
Mirror: fix: Improve Kimi model search and add fallback models (#5704) #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| "webview-ui": patch | ||
| --- | ||
|
|
||
| Fix case-insensitive model search in ModelPicker | ||
|
|
||
| Users can now search for models regardless of casing. For example, searching for "kimi k2.5" will find models like "Kimi-K2.5-Instruct". This fixes model discovery issues when using Azure Cognitive Services or other OpenAI-compatible providers that return models with different casing. | ||
|
|
||
| Before: Search was case-sensitive, making it hard to find models | ||
| After: Search is case-insensitive for better discoverability |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "kilo-code": patch | ||
| --- | ||
|
|
||
| Fix Kimi model search and add Kimi models as fallback for OpenAI Compatible provider |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,21 @@ export const ModelPicker = ({ | |
|
|
||
| const [searchValue, setSearchValue] = useState("") | ||
|
|
||
| // kilocode_change: Case-insensitive search with dash/space normalization | ||
| const normalizeForSearch = (str: string) => str.toLowerCase().replace(/[-_\s]/g, "") | ||
|
|
||
| const filteredPreferredIds = useMemo(() => { | ||
| if (!searchValue.trim()) return preferredModelIds | ||
| const searchNormalized = normalizeForSearch(searchValue) | ||
| return preferredModelIds.filter((id) => normalizeForSearch(id).includes(searchNormalized)) | ||
| }, [preferredModelIds, searchValue]) | ||
|
|
||
| const filteredRestIds = useMemo(() => { | ||
| if (!searchValue.trim()) return restModelIds | ||
| const searchNormalized = normalizeForSearch(searchValue) | ||
| return restModelIds.filter((id) => normalizeForSearch(id).includes(searchNormalized)) | ||
| }, [restModelIds, searchValue]) | ||
|
Comment on lines
+101
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. modelpicker search untested The PR changes ModelPicker search behavior to be case-insensitive and normalize dashes/spaces, but there are no updated/additional tests asserting the new matching behavior. This risks regressions where searches may not return expected models across different casing/formatting. Agent Prompt
|
||
|
|
||
| const onSelect = useCallback( | ||
| (modelId: string) => { | ||
| if (!modelId) { | ||
|
|
@@ -179,7 +194,7 @@ export const ModelPicker = ({ | |
| </Button> | ||
| </PopoverTrigger> | ||
| <PopoverContent className="p-0 w-[var(--radix-popover-trigger-width)]"> | ||
| <Command> | ||
| <Command shouldFilter={false}> | ||
| <div className="relative"> | ||
| <CommandInput | ||
| ref={searchInputRef} | ||
|
|
@@ -206,10 +221,15 @@ export const ModelPicker = ({ | |
| </div> | ||
| )} | ||
| </CommandEmpty> | ||
| {/* kilocode_change start: Section headers for recommended and all models */} | ||
| {preferredModelIds.length > 0 && ( | ||
| <CommandGroup heading={t("settings:modelPicker.recommendedModels")}> | ||
| {preferredModelIds.map((model) => ( | ||
| {/* kilocode_change start: Section headers for recommended and all models with case-insensitive search */} | ||
| {filteredPreferredIds.length > 0 && ( | ||
| <CommandGroup | ||
| heading={ | ||
| searchValue.trim() | ||
| ? t("settings:modelPicker.matchingModels") | ||
| : t("settings:modelPicker.recommendedModels") | ||
| }> | ||
|
Comment on lines
+225
to
+231
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3. Missing i18n key ModelPicker now references the translation key settings:modelPicker.matchingModels, but it is not defined in locale files (at least en), so the UI will likely show the raw key string when searching. Agent Prompt
|
||
| {filteredPreferredIds.map((model) => ( | ||
| <CommandItem | ||
| key={model} | ||
| value={model} | ||
|
|
@@ -229,9 +249,9 @@ export const ModelPicker = ({ | |
| ))} | ||
| </CommandGroup> | ||
| )} | ||
| {restModelIds.length > 0 && ( | ||
| {filteredRestIds.length > 0 && ( | ||
| <CommandGroup heading={t("settings:modelPicker.allModels")}> | ||
| {restModelIds.map((model) => ( | ||
| {filteredRestIds.map((model) => ( | ||
| <CommandItem | ||
| key={model} | ||
| value={model} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { useState, useCallback, useEffect } from "react" | ||
| import { useState, useCallback, useEffect, useMemo } from "react" | ||
| import { useEvent } from "react-use" | ||
| import { Checkbox } from "vscrui" | ||
| import { VSCodeButton, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" | ||
|
|
@@ -11,6 +11,8 @@ import { | |
| type ExtensionMessage, | ||
| azureOpenAiDefaultApiVersion, | ||
| openAiModelInfoSaneDefaults, | ||
| moonshotModels, | ||
| moonshotDefaultModelId, | ||
| } from "@roo-code/types" | ||
|
|
||
| import { useAppTranslation } from "@src/i18n/TranslationContext" | ||
|
|
@@ -48,6 +50,22 @@ export const OpenAICompatible = ({ | |
| return Object.entries(headers) | ||
| }) | ||
|
|
||
| const isKimiEndpoint = | ||
| apiConfiguration.openAiBaseUrl?.toLowerCase().includes("kimi") || | ||
| apiConfiguration.openAiBaseUrl?.toLowerCase().includes("moonshot") || | ||
| apiConfiguration.openAiBaseUrl?.toLowerCase().includes("api.moonshot.ai") || | ||
| apiConfiguration.openAiBaseUrl?.toLowerCase().includes("api.moonshot.cn") | ||
|
Comment on lines
+56
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| const modelsToUse = useMemo(() => { | ||
| const fetchedModels = openAiModels ?? {} | ||
| if (isKimiEndpoint) { | ||
| return { ...moonshotModels, ...fetchedModels } | ||
| } | ||
| return fetchedModels | ||
| }, [isKimiEndpoint, openAiModels]) | ||
|
|
||
| const defaultModelId = isKimiEndpoint ? moonshotDefaultModelId : "gpt-4o" | ||
|
|
||
|
Comment on lines
+53
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Kimi fallback untested The PR adds Kimi endpoint detection and fallback model/default model selection for OpenAICompatible, but existing tests do not validate the new defaultModelId/models behavior passed to ModelPicker. This can break provider configuration silently if endpoint detection or merging logic changes. Agent Prompt
|
||
| const handleAddCustomHeader = useCallback(() => { | ||
| // Only update the local state to show the new row in the UI. | ||
| setCustomHeaders((prev) => [...prev, ["", ""]]) | ||
|
|
@@ -138,10 +156,11 @@ export const OpenAICompatible = ({ | |
| <label className="block font-medium mb-1">{t("settings:providers.apiKey")}</label> | ||
| </VSCodeTextField> | ||
| <ModelPicker | ||
| key={`${apiConfiguration.openAiBaseUrl}-${isKimiEndpoint}`} | ||
| apiConfiguration={apiConfiguration} | ||
| setApiConfigurationField={setApiConfigurationField} | ||
| defaultModelId="gpt-4o" | ||
| models={openAiModels} | ||
| defaultModelId={defaultModelId} | ||
| models={modelsToUse} | ||
| modelIdKey="openAiModelId" | ||
| serviceName="OpenAI" | ||
| serviceUrl="https://platform.openai.com" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
normalizeForSearchfunction is redefined on every render, which causes theuseMemohooks to re-evaluate unnecessarily. This negates the performance benefits of memoization. Additionally, the filtering logic forpreferredModelIdsandrestModelIdsis duplicated.To improve performance and maintainability, you should:
normalizeForSearchinuseCallbackto ensure it's stable across renders.useMemohooks into a single one to avoid code duplication.