diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index c549442f3a..377bc752bf 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -263,16 +263,29 @@ const ApiOptions = ({ setApiConfigurationField("requestyModelId", requestyDefaultModelId) } break - case "litellm": - if (!apiConfiguration.litellmModelId) { + case "litellm": { + let currentLitellmModelId = apiConfiguration.litellmModelId + if (!currentLitellmModelId) { setApiConfigurationField("litellmModelId", litellmDefaultModelId) + currentLitellmModelId = litellmDefaultModelId // Use the default for the next step + } + // Ensure apiModelId is also set to the specific litellm model id + if (apiConfiguration.apiModelId !== currentLitellmModelId) { + setApiConfigurationField("apiModelId", currentLitellmModelId) } break + } } - setApiConfigurationField("apiProvider", value) + // Only update the apiProvider if it's actually changing. + // This should be called after model-specific IDs are handled for the new provider. + if (apiConfiguration.apiProvider !== value) { + setApiConfigurationField("apiProvider", value) + } }, [ + apiConfiguration.apiProvider, + apiConfiguration.apiModelId, // Add apiModelId as it's read and potentially set setApiConfigurationField, apiConfiguration.openRouterModelId, apiConfiguration.glamaModelId, diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 735a5b67ba..889e4c2803 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -27,7 +27,7 @@ import { import { ExperimentId } from "@roo/shared/experiments" import { TelemetrySetting } from "@roo/shared/TelemetrySetting" -import { ProviderSettings } from "@roo/shared/api" +import { ProviderSettings, litellmDefaultModelId } from "@roo/shared/api" import { vscode } from "@/utils/vscode" import { ExtensionStateContextType, useExtensionState } from "@/context/ExtensionStateContext" @@ -219,6 +219,51 @@ const SettingsView = forwardRef(({ onDone, t }) }, []) + useEffect(() => { + // This effect ensures that if LiteLLM is the provider, + // its specific configuration fields have default values in the cached state. + const config = cachedState.apiConfiguration + if (config && config.apiProvider === "litellm") { + const baseUrlMissing = config.litellmBaseUrl === undefined + const apiKeyMissing = config.litellmApiKey === undefined + + if (baseUrlMissing || apiKeyMissing) { + setCachedState((prevState) => { + // Ensure we are working with the latest apiConfiguration from prevState + const currentApiConfig = prevState.apiConfiguration ?? {} + let updatedApiConfig = { ...currentApiConfig } // Clone to modify + let madeChanges = false + + // Check and apply defaults based on the fresh currentApiConfig + if (currentApiConfig.litellmBaseUrl === undefined) { + updatedApiConfig.litellmBaseUrl = "http://localhost:4000" + madeChanges = true + } + if (currentApiConfig.litellmApiKey === undefined) { + updatedApiConfig.litellmApiKey = "sk-1234" + madeChanges = true + } + if (currentApiConfig.litellmModelId === undefined) { + updatedApiConfig.litellmModelId = litellmDefaultModelId + madeChanges = true + } + + if (madeChanges) { + // setChangeDetected is not directly available here unless passed to setCachedState's scope or handled differently + // For now, we focus on updating apiConfiguration correctly. + // The parent component (SettingsView) already calls setChangeDetected(true) when setApiConfigurationField is used. + // If we bypass setApiConfigurationField, we need to call setChangeDetected here. + setChangeDetected(true) // Call setChangeDetected as we are modifying the state that tracks changes. + return { ...prevState, apiConfiguration: updatedApiConfig } + } + return prevState // No changes were actually needed based on the fresh check + }) + } + } + // Adding setCachedState and setChangeDetected to dependencies as they are used directly or indirectly. + // setApiConfigurationField is removed as we are not calling it from here for these specific defaults. + }, [cachedState.apiConfiguration, setCachedState, setChangeDetected]) + const setTelemetrySetting = useCallback((setting: TelemetrySetting) => { setCachedState((prevState) => { if (prevState.telemetrySetting === setting) { diff --git a/webview-ui/src/components/settings/providers/LiteLLM.tsx b/webview-ui/src/components/settings/providers/LiteLLM.tsx index 758d35d86c..fd2071383f 100644 --- a/webview-ui/src/components/settings/providers/LiteLLM.tsx +++ b/webview-ui/src/components/settings/providers/LiteLLM.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from "react" +import { useCallback, useState, useEffect, useRef } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { useEvent } from "react-use" @@ -24,6 +24,7 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode const { t } = useAppTranslation() const [refreshStatus, setRefreshStatus] = useState<"idle" | "loading" | "success" | "error">("idle") const [refreshError, setRefreshError] = useState() + const initialRefreshPerformedRef = useRef(false) const handleInputChange = useCallback( ( @@ -36,14 +37,18 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode [setApiConfigurationField], ) - const handleRefreshModels = () => { + const handleRefreshModels = useCallback(() => { setRefreshStatus("loading") setRefreshError(undefined) - // Due to the button's disabled state logic, litellmApiKey and litellmBaseUrl are guaranteed to be non-empty strings here. - // We use non-null assertions (!) to reflect this guarantee for type safety. - const key = apiConfiguration.litellmApiKey! - const url = apiConfiguration.litellmBaseUrl! + const key = apiConfiguration.litellmApiKey + const url = apiConfiguration.litellmBaseUrl + + if (!key || !url) { + setRefreshStatus("error") + setRefreshError(t("settings:providers.refreshModels.missingConfig")) + return + } const message: WebviewMessage = { type: "requestProviderModels", @@ -54,9 +59,34 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode }, } vscode.postMessage(message) - } + }, [apiConfiguration.litellmApiKey, apiConfiguration.litellmBaseUrl, setRefreshStatus, setRefreshError, t]) + + // Effect to trigger initial model refresh, once per component instance when conditions are met + useEffect(() => { + // Only proceed if the initial refresh for this component instance hasn't been done + if (initialRefreshPerformedRef.current) { + return + } + + // Check if the necessary configuration is available + if (apiConfiguration.litellmApiKey && apiConfiguration.litellmBaseUrl) { + // Mark that we are performing the refresh for this instance + initialRefreshPerformedRef.current = true + // Directly execute refresh logic + setRefreshStatus("loading") + setRefreshError(undefined) + const message: WebviewMessage = { + type: "requestProviderModels", + payload: { + provider: "litellm", + apiKey: apiConfiguration.litellmApiKey, + baseUrl: apiConfiguration.litellmBaseUrl, + }, + } + vscode.postMessage(message) + } + }, [apiConfiguration.litellmApiKey, apiConfiguration.litellmBaseUrl]) - // Listen for model refresh responses using useEvent useEvent("message", (event: MessageEvent) => { const message = event.data if (message.type === "providerModelsResponse") { @@ -67,7 +97,6 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode setRefreshError(message.payload.error) } else { setRefreshStatus("success") - // Parent (ApiOptions.tsx) will handle updating the routerModels prop for ModelPicker } } else { console.log( @@ -77,7 +106,6 @@ export const LiteLLM = ({ apiConfiguration, setApiConfigurationField, routerMode } } }) - console.log("apiconfig1212", apiConfiguration) return ( <> diff --git a/webview-ui/src/components/welcome/WelcomeView.tsx b/webview-ui/src/components/welcome/WelcomeView.tsx index 536a654844..2836f95821 100644 --- a/webview-ui/src/components/welcome/WelcomeView.tsx +++ b/webview-ui/src/components/welcome/WelcomeView.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from "react" +import { useCallback, useState, useEffect } from "react" import { VSCodeButton, VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { useExtensionState } from "@src/context/ExtensionStateContext" import { validateApiConfiguration } from "@src/utils/validate" @@ -10,12 +10,67 @@ import { useAppTranslation } from "@src/i18n/TranslationContext" import { getRequestyAuthUrl, getOpenRouterAuthUrl } from "@src/oauth/urls" import RooHero from "./RooHero" import knuthShuffle from "knuth-shuffle-seeded" +import { ProviderSettings, litellmDefaultModelId } from "@roo/shared/api" const WelcomeView = () => { const { apiConfiguration, currentApiConfigName, setApiConfiguration, uriScheme, machineId } = useExtensionState() const { t } = useAppTranslation() const [errorMessage, setErrorMessage] = useState(undefined) + // Memoize the setApiConfigurationField function to pass to ApiOptions + const setApiConfigurationFieldForApiOptions = useCallback( + (field: K, value: ProviderSettings[K]) => { + setApiConfiguration({ [field]: value }) + }, + [setApiConfiguration], // setApiConfiguration from context is stable + ) + + useEffect(() => { + if (!apiConfiguration) { + // If no apiConfig at all, nothing to default yet. + // This can happen before the initial state hydration from the extension. + return + } + + const currentProvider = apiConfiguration.apiProvider + // Needs provider default if apiProvider is undefined, null, or an empty string. + const needsProviderDefault = !currentProvider + const isLiteLLMSelectedOrShouldBeDefault = currentProvider === "litellm" || needsProviderDefault + + if (isLiteLLMSelectedOrShouldBeDefault) { + const updates: Partial = {} + let madeChanges = false + + if (apiConfiguration.litellmBaseUrl === undefined) { + updates.litellmBaseUrl = "http://localhost:4000" + madeChanges = true + } + if (apiConfiguration.litellmApiKey === undefined) { + updates.litellmApiKey = "sk-1234" + madeChanges = true + } + if (apiConfiguration.litellmModelId === undefined) { + updates.litellmModelId = litellmDefaultModelId + madeChanges = true + } + + // If apiProvider was initially missing or falsy, set it to "litellm". + if (needsProviderDefault) { + updates.apiProvider = "litellm" + madeChanges = true + } + + if (madeChanges) { + // This log helps confirm if we are about to call setApiConfiguration + setApiConfiguration(updates) + } else { + // This log helps confirm that on subsequent runs, no changes are deemed necessary. + } + } + }, [apiConfiguration, setApiConfiguration]) + + useEffect(() => {}, [apiConfiguration]) + const handleSubmit = useCallback(() => { const error = apiConfiguration ? validateApiConfiguration(apiConfiguration) : undefined @@ -106,7 +161,7 @@ const WelcomeView = () => { fromWelcomeView apiConfiguration={apiConfiguration || {}} uriScheme={uriScheme} - setApiConfigurationField={(field, value) => setApiConfiguration({ [field]: value })} + setApiConfigurationField={setApiConfigurationFieldForApiOptions} errorMessage={errorMessage} setErrorMessage={setErrorMessage} /> diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 63c895f034..d4e76dc325 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -188,6 +188,16 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode [], ) + const setApiConfiguration = useCallback((value: ProviderSettings) => { + setState((prevState) => ({ + ...prevState, + apiConfiguration: { + ...prevState.apiConfiguration, + ...value, + }, + })) + }, []) + const handleMessage = useCallback( (event: MessageEvent) => { const message: ExtensionMessage = event.data @@ -266,14 +276,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode screenshotQuality: state.screenshotQuality, setExperimentEnabled: (id, enabled) => setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })), - setApiConfiguration: (value) => - setState((prevState) => ({ - ...prevState, - apiConfiguration: { - ...prevState.apiConfiguration, - ...value, - }, - })), + setApiConfiguration, setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })), setAlwaysAllowReadOnly: (value) => setState((prevState) => ({ ...prevState, alwaysAllowReadOnly: value })), setAlwaysAllowReadOnlyOutsideWorkspace: (value) => diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index e9af71f562..81dbea909b 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -121,7 +121,8 @@ "hint": "Si us plau, torneu a obrir la configuració per veure els models més recents.", "loading": "Actualitzant models...", "success": "Models actualitzats correctament.", - "error": "No s'han pogut actualitzar els models. Si us plau, comproveu la vostra configuració i torneu-ho a provar." + "error": "No s'han pogut actualitzar els models. Si us plau, comproveu la vostra configuració i torneu-ho a provar.", + "missingConfig": "Falta la clau API o l'URL base. Si us plau, proporcioneu ambdós per actualitzar els models." }, "getRequestyApiKey": "Obtenir clau API de Requesty", "openRouterTransformsText": "Comprimir prompts i cadenes de missatges a la mida del context (Transformacions d'OpenRouter)", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index f55a6acd18..82c46e0d19 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -121,7 +121,8 @@ "hint": "Bitte öffne die Einstellungen erneut, um die neuesten Modelle zu sehen.", "loading": "Modelle werden aktualisiert...", "success": "Modelle erfolgreich aktualisiert.", - "error": "Fehler beim Aktualisieren der Modelle. Bitte überprüfe deine Konfiguration und versuche es erneut." + "error": "Fehler beim Aktualisieren der Modelle. Bitte überprüfe deine Konfiguration und versuche es erneut.", + "missingConfig": "API-Schlüssel oder Basis-URL fehlt. Bitte gib beides an, um Modelle zu aktualisieren." }, "getRequestyApiKey": "Requesty API-Schlüssel erhalten", "openRouterTransformsText": "Prompts und Nachrichtenketten auf Kontextgröße komprimieren (OpenRouter Transformationen)", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 2f757fab10..f0fa791de5 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -121,7 +121,8 @@ "hint": "Please reopen the settings to see the latest models.", "loading": "Refreshing models...", "success": "Models refreshed successfully.", - "error": "Failed to refresh models. Please check your configuration and try again." + "error": "Failed to refresh models. Please check your configuration and try again.", + "missingConfig": "API key or base URL missing. Please provide both to refresh models." }, "getRequestyApiKey": "Get Requesty API Key", "openRouterTransformsText": "Compress prompts and message chains to the context size (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 0df4a4931d..6042bab728 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -121,7 +121,8 @@ "hint": "Por favor, vuelve a abrir la configuración para ver los modelos más recientes.", "loading": "Actualizando modelos...", "success": "Modelos actualizados correctamente.", - "error": "Error al actualizar los modelos. Por favor, verifica tu configuración e inténtalo de nuevo." + "error": "Error al actualizar los modelos. Por favor, verifica tu configuración e inténtalo de nuevo.", + "missingConfig": "Falta la clave API o la URL base. Por favor, proporciona ambos para actualizar los modelos." }, "getRequestyApiKey": "Obtener clave API de Requesty", "openRouterTransformsText": "Comprimir prompts y cadenas de mensajes al tamaño del contexto (Transformaciones de OpenRouter)", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index fd867f276b..6e724a080f 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -121,7 +121,8 @@ "hint": "Veuillez rouvrir les paramètres pour voir les modèles les plus récents.", "loading": "Actualisation des modèles...", "success": "Modèles actualisés avec succès.", - "error": "Échec de l'actualisation des modèles. Veuillez vérifier votre configuration et réessayer." + "error": "Échec de l'actualisation des modèles. Veuillez vérifier votre configuration et réessayer.", + "missingConfig": "Clé API ou URL de base manquante. Veuillez fournir les deux pour actualiser les modèles." }, "getRequestyApiKey": "Obtenir la clé API Requesty", "openRouterTransformsText": "Compresser les prompts et chaînes de messages à la taille du contexte (Transformations OpenRouter)", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 1cecc7242f..81cf1477d5 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -121,7 +121,8 @@ "hint": "नवीनतम मॉडल देखने के लिए कृपया सेटिंग्स को फिर से खोलें।", "loading": "मॉडल रिफ्रेश हो रहे हैं...", "success": "मॉडल सफलतापूर्वक रिफ्रेश हो गए।", - "error": "मॉडल रिफ्रेश करने में विफल। कृपया अपनी कॉन्फ़िगरेशन जांचें और पुनः प्रयास करें।" + "error": "मॉडल रिफ्रेश करने में विफल। कृपया अपनी कॉन्फ़िगरेशन जांचें और पुनः प्रयास करें।", + "missingConfig": "API कुंजी या बेस URL अनुपलब्ध है। मॉडल रिफ्रेश करने के लिए कृपया दोनों प्रदान करें।" }, "getRequestyApiKey": "Requesty API कुंजी प्राप्त करें", "openRouterTransformsText": "संदर्भ आकार के लिए प्रॉम्प्ट और संदेश श्रृंखलाओं को संपीड़ित करें (OpenRouter ट्रांसफॉर्म)", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 561671026e..c7c147cc7c 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -121,7 +121,8 @@ "hint": "Riapri le impostazioni per vedere i modelli più recenti.", "loading": "Aggiornamento modelli in corso...", "success": "Modelli aggiornati con successo.", - "error": "Impossibile aggiornare i modelli. Verifica la tua configurazione e riprova." + "error": "Impossibile aggiornare i modelli. Verifica la tua configurazione e riprova.", + "missingConfig": "Chiave API o URL base mancante. Fornisci entrambi per aggiornare i modelli." }, "getRequestyApiKey": "Ottieni chiave API Requesty", "openRouterTransformsText": "Comprimi prompt e catene di messaggi alla dimensione del contesto (Trasformazioni OpenRouter)", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index f9c1efe140..8e58f506ac 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -121,7 +121,8 @@ "hint": "最新のモデルを表示するには設定を再度開いてください。", "loading": "モデルを更新中...", "success": "モデルが正常に更新されました。", - "error": "モデルの更新に失敗しました。設定を確認して再試行してください。" + "error": "モデルの更新に失敗しました。設定を確認して再試行してください。", + "missingConfig": "APIキーまたはベースURLが不足しています。モデルを更新するには両方を提供してください。" }, "getRequestyApiKey": "Requesty APIキーを取得", "openRouterTransformsText": "プロンプトとメッセージチェーンをコンテキストサイズに圧縮 (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index a612e8d2cd..a2cf4ec38c 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -121,7 +121,8 @@ "hint": "최신 모델을 보려면 설정을 다시 열어주세요.", "loading": "모델 새로고침 중...", "success": "모델이 성공적으로 새로고침되었습니다.", - "error": "모델 새로고침에 실패했습니다. 설정을 확인하고 다시 시도해주세요." + "error": "모델 새로고침에 실패했습니다. 설정을 확인하고 다시 시도해주세요.", + "missingConfig": "API 키 또는 기본 URL이 누락되었습니다. 모델을 새로고침하려면 둘 다 제공해주세요." }, "getRequestyApiKey": "Requesty API 키 받기", "openRouterTransformsText": "프롬프트와 메시지 체인을 컨텍스트 크기로 압축 (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 268c552b2f..7cdf655d22 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -121,7 +121,8 @@ "hint": "Open de instellingen opnieuw om de nieuwste modellen te zien.", "loading": "Modellen verversen...", "success": "Modellen succesvol ververst.", - "error": "Modellen verversen mislukt. Controleer je configuratie en probeer het opnieuw." + "error": "Modellen verversen mislukt. Controleer je configuratie en probeer het opnieuw.", + "missingConfig": "API-sleutel of basis-URL ontbreekt. Geef beide op om modellen te verversen." }, "getRequestyApiKey": "Requesty API-sleutel ophalen", "openRouterTransformsText": "Comprimeer prompts en berichtreeksen tot de contextgrootte (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 155ccf1007..9711a32dd0 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -121,7 +121,8 @@ "hint": "Proszę ponownie otworzyć ustawienia, aby zobaczyć najnowsze modele.", "loading": "Odświeżanie modeli...", "success": "Modele zostały pomyślnie odświeżone.", - "error": "Nie udało się odświeżyć modeli. Sprawdź konfigurację i spróbuj ponownie." + "error": "Nie udało się odświeżyć modeli. Sprawdź konfigurację i spróbuj ponownie.", + "missingConfig": "Brak klucza API lub podstawowego URL. Podaj oba, aby odświeżyć modele." }, "getRequestyApiKey": "Uzyskaj klucz API Requesty", "openRouterTransformsText": "Kompresuj podpowiedzi i łańcuchy wiadomości do rozmiaru kontekstu (Transformacje OpenRouter)", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 71e2b72013..6afd153e28 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -121,7 +121,8 @@ "hint": "Por favor, reabra as configurações para ver os modelos mais recentes.", "loading": "Atualizando modelos...", "success": "Modelos atualizados com sucesso.", - "error": "Falha ao atualizar modelos. Verifique sua configuração e tente novamente." + "error": "Falha ao atualizar modelos. Verifique sua configuração e tente novamente.", + "missingConfig": "Chave API ou URL base ausente. Por favor, forneça ambos para atualizar os modelos." }, "getRequestyApiKey": "Obter chave de API Requesty", "openRouterTransformsText": "Comprimir prompts e cadeias de mensagens para o tamanho do contexto (Transformações OpenRouter)", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index fe72a8dcb7..587c1e57d4 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -121,7 +121,8 @@ "hint": "Пожалуйста, откройте настройки заново, чтобы увидеть последние модели.", "loading": "Обновление моделей...", "success": "Модели успешно обновлены.", - "error": "Не удалось обновить модели. Пожалуйста, проверьте вашу конфигурацию и попробуйте снова." + "error": "Не удалось обновить модели. Пожалуйста, проверьте вашу конфигурацию и попробуйте снова.", + "missingConfig": "Отсутствует API-ключ или базовый URL. Пожалуйста, укажите оба параметра для обновления моделей." }, "getRequestyApiKey": "Получить Requesty API-ключ", "openRouterTransformsText": "Сжимать подсказки и цепочки сообщений до размера контекста (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 744b9d1a6d..00783a1389 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -121,7 +121,8 @@ "hint": "En son modelleri görmek için lütfen ayarları yeniden açın.", "loading": "Modeller yenileniyor...", "success": "Modeller başarıyla yenilendi.", - "error": "Modeller yenilenemedi. Lütfen yapılandırmanızı kontrol edin ve tekrar deneyin." + "error": "Modeller yenilenemedi. Lütfen yapılandırmanızı kontrol edin ve tekrar deneyin.", + "missingConfig": "API anahtarı veya temel URL eksik. Modelleri yenilemek için lütfen her ikisini de sağlayın." }, "getRequestyApiKey": "Requesty API Anahtarı Al", "openRouterTransformsText": "İstem ve mesaj zincirlerini bağlam boyutuna sıkıştır (OpenRouter Dönüşümleri)", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index b37343bdf0..951cdf2e7c 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -121,7 +121,8 @@ "hint": "Vui lòng mở lại cài đặt để xem các mô hình mới nhất.", "loading": "Đang làm mới mô hình...", "success": "Làm mới mô hình thành công.", - "error": "Không thể làm mới mô hình. Vui lòng kiểm tra cấu hình của bạn và thử lại." + "error": "Không thể làm mới mô hình. Vui lòng kiểm tra cấu hình của bạn và thử lại.", + "missingConfig": "Thiếu khóa API hoặc URL cơ sở. Vui lòng cung cấp cả hai để làm mới mô hình." }, "getRequestyApiKey": "Lấy khóa API Requesty", "openRouterTransformsText": "Nén lời nhắc và chuỗi tin nhắn theo kích thước ngữ cảnh (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 31da60ad63..d4f157f506 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -121,7 +121,8 @@ "hint": "请重新打开设置以查看最新模型。", "loading": "正在刷新模型...", "success": "模型刷新成功。", - "error": "刷新模型失败。请检查您的配置并重试。" + "error": "刷新模型失败。请检查您的配置并重试。", + "missingConfig": "缺少 API 密钥或基础 URL。请提供两者以刷新模型。" }, "getRequestyApiKey": "获取 Requesty API 密钥", "openRouterTransformsText": "自动压缩提示词和消息链到上下文长度限制内 (OpenRouter转换)", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 4a88715555..02e57f2c57 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -121,7 +121,8 @@ "hint": "請重新開啟設定以查看最新模型。", "loading": "正在重新整理模型...", "success": "模型重新整理成功。", - "error": "重新整理模型失敗。請檢查您的設定並重試。" + "error": "重新整理模型失敗。請檢查您的設定並重試。", + "missingConfig": "缺少 API 金鑰或基礎 URL。請提供兩者以重新整理模型。" }, "getRequestyApiKey": "取得 Requesty API 金鑰", "openRouterTransformsText": "將提示和訊息鏈壓縮到上下文大小 (OpenRouter 轉換)",