From db718533c617716d4b8b91d1130034d340880592 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Tue, 15 Jul 2025 19:00:14 -0400 Subject: [PATCH 1/4] Move less commonly used provider settings into an advanced dropdown (#5762) --- .../src/components/settings/ApiOptions.tsx | 122 ++++++++++++++---- .../settings/__tests__/ApiOptions.spec.tsx | 14 ++ .../settings/__tests__/SettingsView.spec.tsx | 14 ++ .../settings/providers/OpenRouter.tsx | 50 ------- webview-ui/src/i18n/locales/ca/settings.json | 3 + webview-ui/src/i18n/locales/de/settings.json | 3 + webview-ui/src/i18n/locales/en/settings.json | 3 + webview-ui/src/i18n/locales/es/settings.json | 3 + webview-ui/src/i18n/locales/fr/settings.json | 3 + webview-ui/src/i18n/locales/hi/settings.json | 3 + webview-ui/src/i18n/locales/id/settings.json | 3 + webview-ui/src/i18n/locales/it/settings.json | 3 + webview-ui/src/i18n/locales/ja/settings.json | 3 + webview-ui/src/i18n/locales/ko/settings.json | 3 + webview-ui/src/i18n/locales/nl/settings.json | 3 + webview-ui/src/i18n/locales/pl/settings.json | 3 + .../src/i18n/locales/pt-BR/settings.json | 3 + webview-ui/src/i18n/locales/ru/settings.json | 3 + webview-ui/src/i18n/locales/tr/settings.json | 3 + webview-ui/src/i18n/locales/vi/settings.json | 3 + .../src/i18n/locales/zh-CN/settings.json | 3 + .../src/i18n/locales/zh-TW/settings.json | 3 + 22 files changed, 179 insertions(+), 75 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index e3f5ae7a0d..d0ec50abad 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -2,6 +2,7 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from "react" import { convertHeadersToObject } from "./utils/headers" import { useDebounce } from "react-use" import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" +import { ExternalLinkIcon } from "@radix-ui/react-icons" import { type ProviderName, @@ -31,8 +32,22 @@ import { useAppTranslation } from "@src/i18n/TranslationContext" import { useRouterModels } from "@src/components/ui/hooks/useRouterModels" import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel" import { useExtensionState } from "@src/context/ExtensionStateContext" +import { + useOpenRouterModelProviders, + OPENROUTER_DEFAULT_PROVIDER_NAME, +} from "@src/components/ui/hooks/useOpenRouterModelProviders" import { filterProviders, filterModels } from "./utils/organizationFilters" -import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SearchableSelect } from "@src/components/ui" +import { + Select, + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, + SearchableSelect, + Collapsible, + CollapsibleTrigger, + CollapsibleContent, +} from "@src/components/ui" import { Anthropic, @@ -121,6 +136,7 @@ const ApiOptions = ({ ) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) + const [isAdvancedSettingsOpen, setIsAdvancedSettingsOpen] = useState(false) const handleInputChange = useCallback( ( @@ -141,6 +157,14 @@ const ApiOptions = ({ const { data: routerModels, refetch: refetchRouterModels } = useRouterModels() + const { data: openRouterModelProviders } = useOpenRouterModelProviders(apiConfiguration?.openRouterModelId, { + enabled: + !!apiConfiguration?.openRouterModelId && + routerModels?.openrouter && + Object.keys(routerModels.openrouter).length > 1 && + apiConfiguration.openRouterModelId in routerModels.openrouter, + }) + // Update `apiModelId` whenever `selectedModelId` changes. useEffect(() => { if (selectedModelId) { @@ -534,30 +558,78 @@ const ApiOptions = ({ /> {!fromWelcomeView && ( - <> - setApiConfigurationField(field, value)} - /> - - setApiConfigurationField("rateLimitSeconds", value)} - /> - setApiConfigurationField("consecutiveMistakeLimit", value)} - /> - + + + + {t("settings:advancedSettings.title")} + + + setApiConfigurationField(field, value)} + /> + + setApiConfigurationField("rateLimitSeconds", value)} + /> + setApiConfigurationField("consecutiveMistakeLimit", value)} + /> + {selectedProvider === "openrouter" && + openRouterModelProviders && + Object.keys(openRouterModelProviders).length > 0 && ( +
+
+ + + + +
+ +
+ {t("settings:providers.openRouter.providerRouting.description")}{" "} + + {t("settings:providers.openRouter.providerRouting.learnMore")}. + +
+
+ )} +
+
)} ) diff --git a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx index 07331b8e42..bf02840429 100644 --- a/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/ApiOptions.spec.tsx @@ -100,6 +100,20 @@ vi.mock("@/components/ui", () => ({ ), + // Add Collapsible components + Collapsible: ({ children, open }: any) => ( +
+ {children} +
+ ), + CollapsibleTrigger: ({ children, className, onClick }: any) => ( +
+ {children} +
+ ), + CollapsibleContent: ({ children, className }: any) => ( +
{children}
+ ), })) vi.mock("../TemperatureControl", () => ({ diff --git a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx index 404b3a6883..72d4598ea6 100644 --- a/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx +++ b/webview-ui/src/components/settings/__tests__/SettingsView.spec.tsx @@ -179,6 +179,20 @@ vi.mock("@/components/ui", () => ({ {children} ), + // Add Collapsible components + Collapsible: ({ children, open }: any) => ( +
+ {children} +
+ ), + CollapsibleTrigger: ({ children, className, onClick }: any) => ( +
+ {children} +
+ ), + CollapsibleContent: ({ children, className }: any) => ( +
{children}
+ ), })) // Mock window.postMessage to trigger state hydration diff --git a/webview-ui/src/components/settings/providers/OpenRouter.tsx b/webview-ui/src/components/settings/providers/OpenRouter.tsx index 9ef73d8b24..f6cad36bf8 100644 --- a/webview-ui/src/components/settings/providers/OpenRouter.tsx +++ b/webview-ui/src/components/settings/providers/OpenRouter.tsx @@ -2,7 +2,6 @@ import { useCallback, useState } from "react" import { Trans } from "react-i18next" import { Checkbox } from "vscrui" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ExternalLinkIcon } from "@radix-ui/react-icons" import { type ProviderSettings, type OrganizationAllowList, openRouterDefaultModelId } from "@roo-code/types" @@ -10,12 +9,7 @@ import type { RouterModels } from "@roo/api" import { useAppTranslation } from "@src/i18n/TranslationContext" import { getOpenRouterAuthUrl } from "@src/oauth/urls" -import { - useOpenRouterModelProviders, - OPENROUTER_DEFAULT_PROVIDER_NAME, -} from "@src/components/ui/hooks/useOpenRouterModelProviders" import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" import { inputEventTransform, noTransform } from "../transforms" @@ -37,7 +31,6 @@ export const OpenRouter = ({ apiConfiguration, setApiConfigurationField, routerModels, - selectedModelId, uriScheme, fromWelcomeView, organizationAllowList, @@ -58,14 +51,6 @@ export const OpenRouter = ({ [setApiConfigurationField], ) - const { data: openRouterModelProviders } = useOpenRouterModelProviders(apiConfiguration?.openRouterModelId, { - enabled: - !!apiConfiguration?.openRouterModelId && - routerModels?.openrouter && - Object.keys(routerModels.openrouter).length > 1 && - apiConfiguration.openRouterModelId in routerModels.openrouter, - }) - return ( <> - {openRouterModelProviders && Object.keys(openRouterModelProviders).length > 0 && ( -
-
- - - - -
- -
- {t("settings:providers.openRouter.providerRouting.description")}{" "} - - {t("settings:providers.openRouter.providerRouting.learnMore")}. - -
-
- )} ) } diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 503b8c36ed..207fc88fd9 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -542,6 +542,9 @@ "description": "Quan està habilitat, el terminal hereta les variables d'entorn del procés pare de VSCode, com ara la configuració d'integració del shell definida al perfil d'usuari. Això commuta directament la configuració global de VSCode `terminal.integrated.inheritEnv`. <0>Més informació" } }, + "advancedSettings": { + "title": "Configuració avançada" + }, "advanced": { "diff": { "label": "Habilitar edició mitjançant diffs", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 48d0d41a41..68e9f8f97d 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -542,6 +542,9 @@ "description": "Wenn aktiviert, erbt das Terminal Umgebungsvariablen aus dem übergeordneten Prozess von VSCode, wie z.B. benutzerdefinierte Shell-Integrationseinstellungen. Dies schaltet direkt die globale VSCode-Einstellung `terminal.integrated.inheritEnv` um. <0>Mehr erfahren" } }, + "advancedSettings": { + "title": "Erweiterte Einstellungen" + }, "advanced": { "diff": { "label": "Bearbeitung durch Diffs aktivieren", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 69ca01154d..fa1fbab13c 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -542,6 +542,9 @@ "description": "When enabled, the terminal will inherit environment variables from VSCode's parent process, such as user-profile-defined shell integration settings. This directly toggles VSCode global setting `terminal.integrated.inheritEnv`. <0>Learn more" } }, + "advancedSettings": { + "title": "Advanced settings" + }, "advanced": { "diff": { "label": "Enable editing through diffs", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 684949488e..80de7042b0 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -542,6 +542,9 @@ "description": "Cuando está habilitado, el terminal hereda las variables de entorno del proceso padre de VSCode, como la configuración de integración del shell definida en el perfil del usuario. Esto alterna directamente la configuración global de VSCode `terminal.integrated.inheritEnv`. <0>Más información" } }, + "advancedSettings": { + "title": "Configuración avanzada" + }, "advanced": { "diff": { "label": "Habilitar edición a través de diffs", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 8080158446..e10b3ae35f 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -542,6 +542,9 @@ "description": "Lorsqu'activé, le terminal hérite des variables d'environnement du processus parent VSCode, comme les paramètres d'intégration du shell définis dans le profil utilisateur. Cela bascule directement le paramètre global VSCode `terminal.integrated.inheritEnv`. <0>En savoir plus" } }, + "advancedSettings": { + "title": "Paramètres avancés" + }, "advanced": { "diff": { "label": "Activer l'édition via des diffs", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 30a34de434..5b64359f8f 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -542,6 +542,9 @@ "description": "सक्षम होने पर, टर्मिनल VSCode के मूल प्रक्रिया से पर्यावरण चर विरासत में लेता है, जैसे उपयोगकर्ता प्रोफ़ाइल में परिभाषित शेल एकीकरण सेटिंग्स। यह VSCode की वैश्विक सेटिंग `terminal.integrated.inheritEnv` को सीधे टॉगल करता है। <0>अधिक जानें" } }, + "advancedSettings": { + "title": "उन्नत सेटिंग्स" + }, "advanced": { "diff": { "label": "diffs के माध्यम से संपादन सक्षम करें", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 6089d5874e..24404dec3d 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -546,6 +546,9 @@ "description": "Ketika diaktifkan, terminal akan mewarisi variabel environment dari proses parent VSCode, seperti pengaturan integrasi shell yang didefinisikan user-profile. Ini secara langsung mengalihkan pengaturan global VSCode `terminal.integrated.inheritEnv`. <0>Pelajari lebih lanjut" } }, + "advancedSettings": { + "title": "Pengaturan lanjutan" + }, "advanced": { "diff": { "label": "Aktifkan editing melalui diff", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 189efe0bed..bacf7a40ef 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -542,6 +542,9 @@ "description": "Quando abilitato, il terminale eredita le variabili d'ambiente dal processo padre di VSCode, come le impostazioni di integrazione della shell definite nel profilo utente. Questo attiva direttamente l'impostazione globale di VSCode `terminal.integrated.inheritEnv`. <0>Scopri di più" } }, + "advancedSettings": { + "title": "Impostazioni avanzate" + }, "advanced": { "diff": { "label": "Abilita modifica tramite diff", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index a63d0b6800..c588edead2 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -542,6 +542,9 @@ "description": "有効にすると、ターミナルは VSCode の親プロセスから環境変数を継承します。ユーザープロファイルで定義されたシェル統合設定などが含まれます。これは VSCode のグローバル設定 `terminal.integrated.inheritEnv` を直接切り替えます。 <0>詳細情報" } }, + "advancedSettings": { + "title": "詳細設定" + }, "advanced": { "diff": { "label": "diff経由の編集を有効化", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index c4da7c8602..84c329ffd7 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -542,6 +542,9 @@ "description": "활성화하면 터미널이 VSCode 부모 프로세스로부터 환경 변수를 상속받습니다. 사용자 프로필에 정의된 셸 통합 설정 등이 포함됩니다. 이는 VSCode 전역 설정 `terminal.integrated.inheritEnv`를 직접 전환합니다. <0>더 알아보기" } }, + "advancedSettings": { + "title": "고급 설정" + }, "advanced": { "diff": { "label": "diff를 통한 편집 활성화", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 535c462fe2..343008ae51 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -542,6 +542,9 @@ "description": "Indien ingeschakeld, neemt de terminal omgevingsvariabelen over van het bovenliggende VSCode-proces, zoals shell-integratie-instellingen uit het gebruikersprofiel. Dit schakelt direct de VSCode-instelling `terminal.integrated.inheritEnv` om. <0>Meer informatie" } }, + "advancedSettings": { + "title": "Geavanceerde instellingen" + }, "advanced": { "diff": { "label": "Bewerken via diffs inschakelen", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index f7d80cd1a6..2f300384e4 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -542,6 +542,9 @@ "description": "Po włączeniu terminal dziedziczy zmienne środowiskowe z procesu nadrzędnego VSCode, takie jak ustawienia integracji powłoki zdefiniowane w profilu użytkownika. Przełącza to bezpośrednio globalne ustawienie VSCode `terminal.integrated.inheritEnv`. <0>Dowiedz się więcej" } }, + "advancedSettings": { + "title": "Ustawienia zaawansowane" + }, "advanced": { "diff": { "label": "Włącz edycję przez różnice", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index a9ccd98838..11e4d01aac 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -542,6 +542,9 @@ "description": "Quando ativado, o terminal herda variáveis de ambiente do processo pai do VSCode, como configurações de integração do shell definidas no perfil do usuário. Isso alterna diretamente a configuração global do VSCode `terminal.integrated.inheritEnv`. <0>Saiba mais" } }, + "advancedSettings": { + "title": "Configurações avançadas" + }, "advanced": { "diff": { "label": "Ativar edição através de diffs", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 696c5ef641..35eb9b1966 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -542,6 +542,9 @@ "description": "Если включено, терминал будет наследовать переменные среды от родительского процесса VSCode, такие как настройки интеграции оболочки, определённые в профиле пользователя. Напрямую переключает глобальную настройку VSCode `terminal.integrated.inheritEnv`. <0>Подробнее" } }, + "advancedSettings": { + "title": "Дополнительные настройки" + }, "advanced": { "diff": { "label": "Включить редактирование через диффы", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index f81bfd98ea..9b90c97fb3 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -542,6 +542,9 @@ "description": "Etkinleştirildiğinde, terminal VSCode üst işleminden ortam değişkenlerini devralır, örneğin kullanıcı profilinde tanımlanan kabuk entegrasyon ayarları gibi. Bu, VSCode'un global ayarı olan `terminal.integrated.inheritEnv` değerini doğrudan değiştirir. <0>Daha fazla bilgi" } }, + "advancedSettings": { + "title": "Gelişmiş ayarlar" + }, "advanced": { "diff": { "label": "Diff'ler aracılığıyla düzenlemeyi etkinleştir", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 97f24b4733..19b574af36 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -542,6 +542,9 @@ "description": "Khi được bật, terminal sẽ kế thừa các biến môi trường từ tiến trình cha của VSCode, như các cài đặt tích hợp shell được định nghĩa trong hồ sơ người dùng. Điều này trực tiếp chuyển đổi cài đặt toàn cục của VSCode `terminal.integrated.inheritEnv`. <0>Tìm hiểu thêm" } }, + "advancedSettings": { + "title": "Cài đặt nâng cao" + }, "advanced": { "diff": { "label": "Bật chỉnh sửa qua diff", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index bbe85d0e84..402de1e683 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -542,6 +542,9 @@ "description": "启用后,终端将从 VSCode 父进程继承环境变量,如用户配置文件中定义的 shell 集成设置。这直接切换 VSCode 全局设置 `terminal.integrated.inheritEnv`。 <0>了解更多" } }, + "advancedSettings": { + "title": "高级设置" + }, "advanced": { "diff": { "label": "启用diff更新", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 4ca64bbc5c..068e64d21f 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -542,6 +542,9 @@ "description": "啟用後,終端機將從 VSCode 父程序繼承環境變數,如使用者設定檔中定義的 shell 整合設定。這直接切換 VSCode 全域設定 `terminal.integrated.inheritEnv`。 <0>瞭解更多" } }, + "advancedSettings": { + "title": "進階設定" + }, "advanced": { "diff": { "label": "透過差異比對編輯", From d513b9c0e15f3e4b80ba4f5a539fa7862f5d3b06 Mon Sep 17 00:00:00 2001 From: Murilo Pires <50873657+MuriloFP@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:50:55 -0300 Subject: [PATCH 2/4] fix: Exclude Terraform and Terragrunt cache directories from checkpoints (#4601) (#5750) * feat: add Issue Fixer Orchestrator mode * fix: Exclude Terraform and Terragrunt cache directories from checkpoints (#4601) --- src/services/checkpoints/excludes.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/checkpoints/excludes.ts b/src/services/checkpoints/excludes.ts index b7bbe81ae5..382e400f18 100644 --- a/src/services/checkpoints/excludes.ts +++ b/src/services/checkpoints/excludes.ts @@ -11,6 +11,8 @@ const getBuildArtifactPatterns = () => [ ".next/", ".nuxt/", ".sass-cache/", + ".terraform/", + ".terragrunt-cache/", ".vs/", ".vscode/", "Pods/", From 8c8888a977dd2a9e03428847cf83fe6e4036b4ee Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Wed, 16 Jul 2025 08:30:33 -0500 Subject: [PATCH 3/4] feat: increase Ollama API timeout values and extract as constants (#5778) - Increase embedding request timeout from 10s to 60s - Increase validation request timeouts from 5s to 30s - Extract timeout values as module-level constants for better maintainability - OLLAMA_EMBEDDING_TIMEOUT_MS = 60000 (60 seconds) - OLLAMA_VALIDATION_TIMEOUT_MS = 30000 (30 seconds) --- src/services/code-index/embedders/ollama.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/services/code-index/embedders/ollama.ts b/src/services/code-index/embedders/ollama.ts index 20b22b92bf..c160d39490 100644 --- a/src/services/code-index/embedders/ollama.ts +++ b/src/services/code-index/embedders/ollama.ts @@ -7,6 +7,10 @@ import { withValidationErrorHandling, sanitizeErrorMessage } from "../shared/val import { TelemetryService } from "@roo-code/telemetry" import { TelemetryEventName } from "@roo-code/types" +// Timeout constants for Ollama API requests +const OLLAMA_EMBEDDING_TIMEOUT_MS = 60000 // 60 seconds for embedding requests +const OLLAMA_VALIDATION_TIMEOUT_MS = 30000 // 30 seconds for validation requests + /** * Implements the IEmbedder interface using a local Ollama instance. */ @@ -61,7 +65,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { // Add timeout to prevent indefinite hanging const controller = new AbortController() - const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout + const timeoutId = setTimeout(() => controller.abort(), OLLAMA_EMBEDDING_TIMEOUT_MS) const response = await fetch(url, { method: "POST", @@ -140,7 +144,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { // Add timeout to prevent indefinite hanging const controller = new AbortController() - const timeoutId = setTimeout(() => controller.abort(), 5000) // 5 second timeout + const timeoutId = setTimeout(() => controller.abort(), OLLAMA_VALIDATION_TIMEOUT_MS) const modelsResponse = await fetch(modelsUrl, { method: "GET", @@ -197,7 +201,7 @@ export class CodeIndexOllamaEmbedder implements IEmbedder { // Add timeout for test request too const testController = new AbortController() - const testTimeoutId = setTimeout(() => testController.abort(), 5000) + const testTimeoutId = setTimeout(() => testController.abort(), OLLAMA_VALIDATION_TIMEOUT_MS) const testResponse = await fetch(testUrl, { method: "POST", From 0f994fcf2285d350ac6dab59c1f6eb6000cb96b1 Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 16 Jul 2025 10:57:34 -0400 Subject: [PATCH 4/4] Fix settings dirty check (#5779) --- webview-ui/src/components/settings/ApiOptions.tsx | 4 ++-- webview-ui/src/components/settings/SettingsView.tsx | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index d0ec50abad..06994b16b9 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -167,10 +167,10 @@ const ApiOptions = ({ // Update `apiModelId` whenever `selectedModelId` changes. useEffect(() => { - if (selectedModelId) { + if (selectedModelId && apiConfiguration.apiModelId !== selectedModelId) { setApiConfigurationField("apiModelId", selectedModelId) } - }, [selectedModelId, setApiConfigurationField]) + }, [selectedModelId, setApiConfigurationField, apiConfiguration.apiModelId]) // Debounced refresh model updates, only executed 250ms after the user // stops typing. diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index cf9e779cbd..fd3a8a129b 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -218,7 +218,15 @@ const SettingsView = forwardRef(({ onDone, t return prevState } - setChangeDetected(true) + const previousValue = prevState.apiConfiguration?.[field] + + // Don't treat initial sync from undefined to a defined value as a user change + // This prevents the dirty state when the component initializes and auto-syncs the model ID + const isInitialSync = previousValue === undefined && value !== undefined + + if (!isInitialSync) { + setChangeDetected(true) + } return { ...prevState, apiConfiguration: { ...prevState.apiConfiguration, [field]: value } } }) },