From 91fac110c0a63a1ac69c9f5a741306cc5ab01794 Mon Sep 17 00:00:00 2001 From: cte Date: Mon, 5 May 2025 21:51:28 -0700 Subject: [PATCH 1/5] Move remaining provider settings into separate components --- src/core/webview/ClineProvider.ts | 4 +- src/shared/api.ts | 2 +- .../src/components/settings/ApiOptions.tsx | 508 ++++-------------- .../src/components/settings/constants.ts | 16 +- .../settings/providers/BedrockCustomArn.tsx | 51 ++ .../components/settings/providers/Chutes.tsx | 50 ++ .../settings/providers/DeepSeek.tsx | 50 ++ .../components/settings/providers/Glama.tsx | 63 +++ .../components/settings/providers/Groq.tsx | 50 ++ .../components/settings/providers/Mistral.tsx | 67 +++ .../settings/providers/OpenRouter.tsx | 65 ++- .../settings/providers/Requesty.tsx | 97 ++++ .../RequestyBalanceDisplay.tsx | 0 .../components/settings/providers/Unbound.tsx | 61 +++ .../src/components/settings/providers/XAI.tsx | 50 ++ .../components/settings/providers/index.ts | 18 + webview-ui/src/i18n/locales/ca/settings.json | 2 - webview-ui/src/i18n/locales/de/settings.json | 2 - webview-ui/src/i18n/locales/en/settings.json | 6 +- webview-ui/src/i18n/locales/es/settings.json | 2 - webview-ui/src/i18n/locales/fr/settings.json | 2 - webview-ui/src/i18n/locales/hi/settings.json | 2 - webview-ui/src/i18n/locales/it/settings.json | 2 - webview-ui/src/i18n/locales/ja/settings.json | 2 - webview-ui/src/i18n/locales/ko/settings.json | 2 - webview-ui/src/i18n/locales/pl/settings.json | 2 - .../src/i18n/locales/pt-BR/settings.json | 2 - webview-ui/src/i18n/locales/ru/settings.json | 2 - webview-ui/src/i18n/locales/tr/settings.json | 2 - webview-ui/src/i18n/locales/vi/settings.json | 2 - .../src/i18n/locales/zh-CN/settings.json | 2 - .../src/i18n/locales/zh-TW/settings.json | 2 - webview-ui/src/oauth/urls.ts | 7 +- 33 files changed, 728 insertions(+), 467 deletions(-) create mode 100644 webview-ui/src/components/settings/providers/BedrockCustomArn.tsx create mode 100644 webview-ui/src/components/settings/providers/Chutes.tsx create mode 100644 webview-ui/src/components/settings/providers/DeepSeek.tsx create mode 100644 webview-ui/src/components/settings/providers/Glama.tsx create mode 100644 webview-ui/src/components/settings/providers/Groq.tsx create mode 100644 webview-ui/src/components/settings/providers/Mistral.tsx create mode 100644 webview-ui/src/components/settings/providers/Requesty.tsx rename webview-ui/src/components/settings/{ => providers}/RequestyBalanceDisplay.tsx (100%) create mode 100644 webview-ui/src/components/settings/providers/Unbound.tsx create mode 100644 webview-ui/src/components/settings/providers/XAI.tsx create mode 100644 webview-ui/src/components/settings/providers/index.ts diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index ca9b63d4ae..899d16aae2 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -13,8 +13,8 @@ import { GlobalState, ProviderSettings, RooCodeSettings } from "../../schemas" import { t } from "../../i18n" import { setPanel } from "../../activate/registerCommands" import { + ProviderName, ApiConfiguration, - ApiProvider, requestyDefaultModelId, openRouterDefaultModelId, glamaDefaultModelId, @@ -1297,7 +1297,7 @@ export class ClineProvider extends EventEmitter implements const customModes = await this.customModesManager.getCustomModes() // Determine apiProvider with the same logic as before. - const apiProvider: ApiProvider = stateValues.apiProvider ? stateValues.apiProvider : "anthropic" + const apiProvider: ProviderName = stateValues.apiProvider ? stateValues.apiProvider : "anthropic" // Build the apiConfiguration object combining state values and secrets. const providerSettings = this.contextProxy.getProviderSettings() diff --git a/src/shared/api.ts b/src/shared/api.ts index 43b7ad7643..7b635a8174 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -1,6 +1,6 @@ import { ModelInfo, ProviderName, ProviderSettings } from "../schemas" -export type { ModelInfo, ProviderName as ApiProvider } +export type { ModelInfo, ProviderName } export type ApiHandlerOptions = Omit diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index f75724ba26..101effc916 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -1,55 +1,55 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from "react" import { useDebounce } from "react-use" -import { VSCodeLink, VSCodeTextField } from "@vscode/webview-ui-toolkit/react" -import { ExternalLinkIcon } from "@radix-ui/react-icons" +import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { - ApiConfiguration, - glamaDefaultModelId, - mistralDefaultModelId, + type ProviderName, + type ApiConfiguration, openRouterDefaultModelId, - unboundDefaultModelId, requestyDefaultModelId, - ApiProvider, + glamaDefaultModelId, + unboundDefaultModelId, } from "@roo/shared/api" import { vscode } from "@src/utils/vscode" -import { validateApiConfiguration, validateModelId, validateBedrockArn } from "@src/utils/validate" +import { validateApiConfiguration, validateModelId } from "@src/utils/validate" import { useAppTranslation } from "@src/i18n/TranslationContext" import { useRouterModels } from "@src/components/ui/hooks/useRouterModels" import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel" +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@src/components/ui" + import { - useOpenRouterModelProviders, - OPENROUTER_DEFAULT_PROVIDER_NAME, -} from "@src/components/ui/hooks/useOpenRouterModelProviders" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Button } from "@src/components/ui" -import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" -import { getRequestyApiKeyUrl, getGlamaAuthUrl } from "@src/oauth/urls" - -// Providers -import { Anthropic } from "./providers/Anthropic" -import { Bedrock } from "./providers/Bedrock" -import { Gemini } from "./providers/Gemini" -import { LMStudio } from "./providers/LMStudio" -import { Ollama } from "./providers/Ollama" -import { OpenAI } from "./providers/OpenAI" -import { OpenAICompatible } from "./providers/OpenAICompatible" -import { OpenRouter } from "./providers/OpenRouter" -import { Vertex } from "./providers/Vertex" -import { VSCodeLM } from "./providers/VSCodeLM" + Anthropic, + Bedrock, + Chutes, + DeepSeek, + Gemini, + Glama, + Groq, + LMStudio, + Mistral, + Ollama, + OpenAI, + OpenAICompatible, + OpenRouter, + Requesty, + Unbound, + Vertex, + VSCodeLM, + XAI, +} from "./providers" import { MODELS_BY_PROVIDER, PROVIDERS, REASONING_MODELS } from "./constants" import { inputEventTransform, noTransform } from "./transforms" import { ModelInfoView } from "./ModelInfoView" -import { ModelPicker } from "./ModelPicker" import { ApiErrorMessage } from "./ApiErrorMessage" import { ThinkingBudget } from "./ThinkingBudget" -import { RequestyBalanceDisplay } from "./RequestyBalanceDisplay" import { ReasoningEffort } from "./ReasoningEffort" import { PromptCachingControl } from "./PromptCachingControl" import { DiffSettingsControl } from "./DiffSettingsControl" import { TemperatureControl } from "./TemperatureControl" import { RateLimitSecondsControl } from "./RateLimitSecondsControl" +import { BedrockCustomArn } from "./providers/BedrockCustomArn" export interface ApiOptionsProps { uriScheme: string | undefined @@ -75,8 +75,6 @@ const ApiOptions = ({ return Object.entries(headers) }) - const [requestyShowRefreshHint, setRequestyShowRefreshHint] = useState() - useEffect(() => { const propHeaders = apiConfiguration?.openAiHeaders || {} @@ -193,16 +191,7 @@ const ApiOptions = ({ setErrorMessage(apiValidationResult) }, [apiConfiguration, routerModels, setErrorMessage]) - const { data: openRouterModelProviders } = useOpenRouterModelProviders(apiConfiguration?.openRouterModelId, { - enabled: - selectedProvider === "openrouter" && - !!apiConfiguration?.openRouterModelId && - routerModels?.openrouter && - Object.keys(routerModels.openrouter).length > 1 && - apiConfiguration.openRouterModelId in routerModels.openrouter, - }) - - const selectedProviderModelOptions = useMemo( + const selectedProviderModels = useMemo( () => MODELS_BY_PROVIDER[selectedProvider] ? Object.keys(MODELS_BY_PROVIDER[selectedProvider]).map((modelId) => ({ @@ -213,37 +202,8 @@ const ApiOptions = ({ [selectedProvider], ) - // Custom URL path mappings for providers with different slugs. - const providerUrlSlugs: Record = { - "openai-native": "openai", - openai: "openai-compatible", - } - - // Helper function to get provider display name from PROVIDERS constant. - const getProviderDisplayName = (providerKey: string): string | undefined => { - const provider = PROVIDERS.find((p) => p.value === providerKey) - return provider?.label - } - - // Helper function to get the documentation URL and name for the currently selected provider - const getSelectedProviderDocUrl = (): { url: string; name: string } | undefined => { - const displayName = getProviderDisplayName(selectedProvider) - - if (!displayName) { - return undefined - } - - // Get the URL slug - use custom mapping if available, otherwise use the provider key - const urlSlug = providerUrlSlugs[selectedProvider] || selectedProvider - - return { - url: `https://docs.roocode.com/providers/${urlSlug}`, - name: displayName, - } - } - - const onApiProviderChange = useCallback( - (value: ApiProvider) => { + const onProviderChange = useCallback( + (value: ProviderName) => { // It would be much easier to have a single attribute that stores // the modelId, but we have a separate attribute for each of // OpenRouter, Glama, Unbound, and Requesty. @@ -285,25 +245,40 @@ const ApiOptions = ({ ], ) + const docs = useMemo(() => { + const provider = PROVIDERS.find(({ value }) => value === selectedProvider) + const name = provider?.label + + if (!name) { + return undefined + } + + // Get the URL slug - use custom mapping if available, otherwise use the provider key. + const slugs: Record = { + "openai-native": "openai", + openai: "openai-compatible", + } + + return { + url: `https://docs.roocode.com/providers/${slugs[selectedProvider] || selectedProvider}`, + name, + } + }, [selectedProvider]) + return (
- {getSelectedProviderDocUrl() && ( + {docs && (
- - {t("settings:providers.providerDocumentation", { - provider: getSelectedProviderDocUrl()!.name, - })} + + {t("settings:providers.providerDocumentation", { provider: docs.name })}
)}
- onProviderChange(value as ProviderName)}> @@ -323,81 +298,41 @@ const ApiOptions = ({ )} - {selectedProvider === "anthropic" && ( - + {selectedProvider === "requesty" && ( + )} {selectedProvider === "glama" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.glamaApiKey && ( - - {t("settings:providers.getGlamaApiKey")} - - )} - + )} - {selectedProvider === "requesty" && ( - <> - -
- - {apiConfiguration?.requestyApiKey && ( - - )} -
-
-
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.requestyApiKey && ( - - {t("settings:providers.getRequestyApiKey")} - - )} - - {requestyShowRefreshHint && ( -
- {t("settings:providers.flushedModelsCache")} -
- )} - + {selectedProvider === "unbound" && ( + + )} + + {selectedProvider === "anthropic" && ( + )} {selectedProvider === "openai-native" && ( @@ -405,42 +340,7 @@ const ApiOptions = ({ )} {selectedProvider === "mistral" && ( - <> - - {t("settings:providers.mistralApiKey")} - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.mistralApiKey && ( - - {t("settings:providers.getMistralApiKey")} - - )} - {(apiConfiguration?.apiModelId?.startsWith("codestral-") || - (!apiConfiguration?.apiModelId && mistralDefaultModelId.startsWith("codestral-"))) && ( - <> - - - -
- {t("settings:providers.codestralBaseUrlDesc")} -
- - )} - + )} {selectedProvider === "bedrock" && ( @@ -471,24 +371,7 @@ const ApiOptions = ({ )} {selectedProvider === "deepseek" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.deepSeekApiKey && ( - - {t("settings:providers.getDeepSeekApiKey")} - - )} - + )} {selectedProvider === "vscode-lm" && ( @@ -500,87 +383,15 @@ const ApiOptions = ({ )} {selectedProvider === "xai" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.xaiApiKey && ( - - {t("settings:providers.getXaiApiKey")} - - )} - + )} {selectedProvider === "groq" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.groqApiKey && ( - - {t("settings:providers.getGroqApiKey")} - - )} - + )} {selectedProvider === "chutes" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.chutesApiKey && ( - - {t("settings:providers.getChutesApiKey")} - - )} - - )} - - {selectedProvider === "unbound" && ( - <> - - - -
- {t("settings:providers.apiKeyStorageNotice")} -
- {!apiConfiguration?.unboundApiKey && ( - - {t("settings:providers.getUnboundApiKey")} - - )} - + )} {selectedProvider === "human-relay" && ( @@ -594,99 +405,10 @@ const ApiOptions = ({ )} - {/* Model Pickers */} - - {selectedProvider === "openrouter" && ( - - )} - - {selectedProvider === "openrouter" && - openRouterModelProviders && - Object.keys(openRouterModelProviders).length > 0 && ( -
-
- - - - -
- -
- {t("settings:providers.openRouter.providerRouting.description")}{" "} - - {t("settings:providers.openRouter.providerRouting.learnMore")}. - -
-
- )} - - {selectedProvider === "glama" && ( - - )} - - {selectedProvider === "unbound" && ( - - )} - - {selectedProvider === "requesty" && ( - - )} - - {selectedProviderModelOptions.length > 0 && ( + {selectedProviderModels.length > 0 && ( <>
- setApiConfigurationField("openRouterSpecificProvider", value)}> + + + + + + {OPENROUTER_DEFAULT_PROVIDER_NAME} + + {Object.entries(openRouterModelProviders).map(([value, { label }]) => ( + + {label} + + ))} + + +
+ {t("settings:providers.openRouter.providerRouting.description")}{" "} + + {t("settings:providers.openRouter.providerRouting.learnMore")}. + +
+
+ )} ) } diff --git a/webview-ui/src/components/settings/providers/Requesty.tsx b/webview-ui/src/components/settings/providers/Requesty.tsx new file mode 100644 index 0000000000..a8c8fc8099 --- /dev/null +++ b/webview-ui/src/components/settings/providers/Requesty.tsx @@ -0,0 +1,97 @@ +import { useCallback, useState } from "react" +import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" + +import { ApiConfiguration, RouterModels, requestyDefaultModelId } from "@roo/shared/api" + +import { vscode } from "@src/utils/vscode" +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" +import { Button } from "@src/components/ui" + +import { inputEventTransform } from "../transforms" +import { ModelPicker } from "../ModelPicker" +import { RequestyBalanceDisplay } from "./RequestyBalanceDisplay" + +type RequestyProps = { + apiConfiguration: ApiConfiguration + setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + routerModels?: RouterModels + refetchRouterModels: () => void +} + +export const Requesty = ({ + apiConfiguration, + setApiConfigurationField, + routerModels, + refetchRouterModels, +}: RequestyProps) => { + const { t } = useAppTranslation() + + const [didRefetch, setDidRefetch] = useState() + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + +
+ + {apiConfiguration?.requestyApiKey && ( + + )} +
+
+
+ {t("settings:providers.apiKeyStorageNotice")} +
+ {!apiConfiguration?.requestyApiKey && ( + + {t("settings:providers.getRequestyApiKey")} + + )} + + {didRefetch && ( +
+ {t("settings:providers.refreshModels.hint")} +
+ )} + + + ) +} diff --git a/webview-ui/src/components/settings/RequestyBalanceDisplay.tsx b/webview-ui/src/components/settings/providers/RequestyBalanceDisplay.tsx similarity index 100% rename from webview-ui/src/components/settings/RequestyBalanceDisplay.tsx rename to webview-ui/src/components/settings/providers/RequestyBalanceDisplay.tsx diff --git a/webview-ui/src/components/settings/providers/Unbound.tsx b/webview-ui/src/components/settings/providers/Unbound.tsx new file mode 100644 index 0000000000..7467d2b7c6 --- /dev/null +++ b/webview-ui/src/components/settings/providers/Unbound.tsx @@ -0,0 +1,61 @@ +import { useCallback } from "react" +import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" + +import { ApiConfiguration, RouterModels, unboundDefaultModelId } from "@roo/shared/api" + +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" + +import { inputEventTransform } from "../transforms" +import { ModelPicker } from "../ModelPicker" + +type UnboundProps = { + apiConfiguration: ApiConfiguration + setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void + routerModels?: RouterModels +} + +export const Unbound = ({ apiConfiguration, setApiConfigurationField, routerModels }: UnboundProps) => { + const { t } = useAppTranslation() + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+ {!apiConfiguration?.unboundApiKey && ( + + {t("settings:providers.getUnboundApiKey")} + + )} + + + ) +} diff --git a/webview-ui/src/components/settings/providers/XAI.tsx b/webview-ui/src/components/settings/providers/XAI.tsx new file mode 100644 index 0000000000..39b0e53d34 --- /dev/null +++ b/webview-ui/src/components/settings/providers/XAI.tsx @@ -0,0 +1,50 @@ +import { useCallback } from "react" +import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" + +import { ApiConfiguration } from "@roo/shared/api" + +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" + +import { inputEventTransform } from "../transforms" + +type XAIProps = { + apiConfiguration: ApiConfiguration + setApiConfigurationField: (field: keyof ApiConfiguration, value: ApiConfiguration[keyof ApiConfiguration]) => void +} + +export const XAI = ({ apiConfiguration, setApiConfigurationField }: XAIProps) => { + const { t } = useAppTranslation() + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ApiConfiguration[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+ {!apiConfiguration?.xaiApiKey && ( + + {t("settings:providers.getXaiApiKey")} + + )} + + ) +} diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts new file mode 100644 index 0000000000..e83c858628 --- /dev/null +++ b/webview-ui/src/components/settings/providers/index.ts @@ -0,0 +1,18 @@ +export { Anthropic } from "./Anthropic" +export { Bedrock } from "./Bedrock" +export { Chutes } from "./Chutes" +export { DeepSeek } from "./DeepSeek" +export { Gemini } from "./Gemini" +export { Glama } from "./Glama" +export { Groq } from "./Groq" +export { LMStudio } from "./LMStudio" +export { Mistral } from "./Mistral" +export { Ollama } from "./Ollama" +export { OpenAI } from "./OpenAI" +export { OpenAICompatible } from "./OpenAICompatible" +export { OpenRouter } from "./OpenRouter" +export { Requesty } from "./Requesty" +export { Unbound } from "./Unbound" +export { Vertex } from "./Vertex" +export { VSCodeLM } from "./VSCodeLM" +export { XAI } from "./XAI" diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 38dc4c67bd..ca7546b2a5 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -119,8 +119,6 @@ "glamaApiKey": "Clau API de Glama", "getGlamaApiKey": "Obtenir clau API de Glama", "requestyApiKey": "Clau API de Requesty", - "flushModelsCache": "Netejar memòria cau de models", - "flushedModelsCache": "Memòria cau netejada, si us plau torna a obrir la vista de configuració", "getRequestyApiKey": "Obtenir clau API de Requesty", "anthropicApiKey": "Clau API d'Anthropic", "getAnthropicApiKey": "Obtenir clau API d'Anthropic", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index e12ad8fa46..db4398402f 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -106,8 +106,6 @@ "awsCustomArnUse": "Geben Sie eine gültige Amazon Bedrock ARN für das Modell ein, das Sie verwenden möchten. Formatbeispiele:", "awsCustomArnDesc": "Stellen Sie sicher, dass die Region in der ARN mit Ihrer oben ausgewählten AWS-Region übereinstimmt.", "openRouterApiKey": "OpenRouter API-Schlüssel", - "flushModelsCache": "Modell-Cache leeren", - "flushedModelsCache": "Cache geleert, bitte öffnen Sie die Einstellungsansicht erneut", "getOpenRouterApiKey": "OpenRouter API-Schlüssel erhalten", "apiKeyStorageNotice": "API-Schlüssel werden sicher im VSCode Secret Storage gespeichert", "glamaApiKey": "Glama API-Schlüssel", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 6c042baf21..c3b67d8e33 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -118,8 +118,10 @@ "headerValue": "Header value", "noCustomHeaders": "No custom headers defined. Click the + button to add one.", "requestyApiKey": "Requesty API Key", - "flushModelsCache": "Flush cached models", - "flushedModelsCache": "Flushed cache, please reopen the settings view", + "refreshModels": { + "label": "Refresh Models", + "hint": "Please reopen the settings to see the latest models." + }, "getRequestyApiKey": "Get Requesty API Key", "openRouterTransformsText": "Compress prompts and message chains to the context size (OpenRouter Transforms)", "anthropicApiKey": "Anthropic API Key", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index cedc110bf5..4a7191ffeb 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -106,8 +106,6 @@ "awsCustomArnUse": "Ingrese un ARN de Amazon Bedrock válido para el modelo que desea utilizar. Ejemplos de formato:", "awsCustomArnDesc": "Asegúrese de que la región en el ARN coincida con la región de AWS seleccionada anteriormente.", "openRouterApiKey": "Clave API de OpenRouter", - "flushModelsCache": "Limpiar modelos en caché", - "flushedModelsCache": "Caché limpiada, por favor vuelva a abrir la vista de configuración", "getOpenRouterApiKey": "Obtener clave API de OpenRouter", "apiKeyStorageNotice": "Las claves API se almacenan de forma segura en el Almacenamiento Secreto de VSCode", "glamaApiKey": "Clave API de Glama", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 615b252d7f..b2a1ef33e4 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -106,8 +106,6 @@ "awsCustomArnUse": "Entrez un ARN Amazon Bedrock valide pour le modèle que vous souhaitez utiliser. Exemples de format :", "awsCustomArnDesc": "Assurez-vous que la région dans l'ARN correspond à la région AWS sélectionnée ci-dessus.", "openRouterApiKey": "Clé API OpenRouter", - "flushModelsCache": "Vider le cache des modèles", - "flushedModelsCache": "Cache vidé, veuillez rouvrir la vue des paramètres", "getOpenRouterApiKey": "Obtenir la clé API OpenRouter", "apiKeyStorageNotice": "Les clés API sont stockées en toute sécurité dans le stockage sécurisé de VSCode", "glamaApiKey": "Clé API Glama", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index d5c948b30d..f62d637356 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -118,8 +118,6 @@ "headerValue": "हेडर मूल्य", "noCustomHeaders": "कोई कस्टम हेडर परिभाषित नहीं है। एक जोड़ने के लिए + बटन पर क्लिक करें।", "requestyApiKey": "Requesty API कुंजी", - "flushModelsCache": "मॉडल कैश साफ़ करें", - "flushedModelsCache": "कैश साफ़ किया गया, कृपया सेटिंग्स व्यू को फिर से खोलें", "getRequestyApiKey": "Requesty API कुंजी प्राप्त करें", "openRouterTransformsText": "संदर्भ आकार के लिए प्रॉम्प्ट और संदेश श्रृंखलाओं को संपीड़ित करें (OpenRouter ट्रांसफॉर्म)", "anthropicApiKey": "Anthropic API कुंजी", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index d7dfefda36..1c20c2d595 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -118,8 +118,6 @@ "headerValue": "Valore intestazione", "noCustomHeaders": "Nessuna intestazione personalizzata definita. Fai clic sul pulsante + per aggiungerne una.", "requestyApiKey": "Chiave API Requesty", - "flushModelsCache": "Svuota cache dei modelli", - "flushedModelsCache": "Cache svuotata, riapri la vista delle impostazioni", "getRequestyApiKey": "Ottieni chiave API Requesty", "openRouterTransformsText": "Comprimi prompt e catene di messaggi alla dimensione del contesto (Trasformazioni OpenRouter)", "anthropicApiKey": "Chiave API Anthropic", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 98e3054121..1ed0ab7c26 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -118,8 +118,6 @@ "headerValue": "ヘッダー値", "noCustomHeaders": "カスタムヘッダーが定義されていません。+ ボタンをクリックして追加してください。", "requestyApiKey": "Requesty APIキー", - "flushModelsCache": "モデルキャッシュをクリア", - "flushedModelsCache": "キャッシュをクリアしました。設定ビューを再開してください", "getRequestyApiKey": "Requesty APIキーを取得", "openRouterTransformsText": "プロンプトとメッセージチェーンをコンテキストサイズに圧縮 (OpenRouter Transforms)", "anthropicApiKey": "Anthropic APIキー", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 9431a9bc5b..b0ceaee530 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -118,8 +118,6 @@ "headerValue": "헤더 값", "noCustomHeaders": "정의된 사용자 정의 헤더가 없습니다. + 버튼을 클릭하여 추가하세요.", "requestyApiKey": "Requesty API 키", - "flushModelsCache": "모델 캐시 지우기", - "flushedModelsCache": "캐시가 지워졌습니다. 설정 보기를 다시 열어주세요", "getRequestyApiKey": "Requesty API 키 받기", "openRouterTransformsText": "프롬프트와 메시지 체인을 컨텍스트 크기로 압축 (OpenRouter Transforms)", "anthropicApiKey": "Anthropic API 키", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index ad3da8d9a8..c4f28f19f6 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -118,8 +118,6 @@ "headerValue": "Wartość nagłówka", "noCustomHeaders": "Brak zdefiniowanych niestandardowych nagłówków. Kliknij przycisk +, aby dodać.", "requestyApiKey": "Klucz API Requesty", - "flushModelsCache": "Wyczyść pamięć podręczną modeli", - "flushedModelsCache": "Pamięć podręczna wyczyszczona, proszę ponownie otworzyć widok ustawień", "getRequestyApiKey": "Uzyskaj klucz API Requesty", "openRouterTransformsText": "Kompresuj podpowiedzi i łańcuchy wiadomości do rozmiaru kontekstu (Transformacje OpenRouter)", "anthropicApiKey": "Klucz API Anthropic", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index b6f1f75253..76b3f597d2 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -106,8 +106,6 @@ "awsCustomArnUse": "Insira um ARN Amazon Bedrock válido para o modelo que deseja usar. Exemplos de formato:", "awsCustomArnDesc": "Certifique-se de que a região no ARN corresponde à região AWS selecionada acima.", "openRouterApiKey": "Chave de API OpenRouter", - "flushModelsCache": "Limpar cache de modelos", - "flushedModelsCache": "Cache limpo, por favor reabra a visualização de configurações", "getOpenRouterApiKey": "Obter chave de API OpenRouter", "apiKeyStorageNotice": "As chaves de API são armazenadas com segurança no Armazenamento Secreto do VSCode", "glamaApiKey": "Chave de API Glama", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 6fa1cc0326..f46d1d9837 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -118,8 +118,6 @@ "headerValue": "Значение заголовка", "noCustomHeaders": "Пользовательские заголовки не определены. Нажмите кнопку +, чтобы добавить.", "requestyApiKey": "Requesty API-ключ", - "flushModelsCache": "Очистить кэш моделей", - "flushedModelsCache": "Кэш очищен, пожалуйста, переоткройте представление настроек", "getRequestyApiKey": "Получить Requesty API-ключ", "openRouterTransformsText": "Сжимать подсказки и цепочки сообщений до размера контекста (OpenRouter Transforms)", "anthropicApiKey": "Anthropic API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index af7b4a217b..580e35ee04 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -106,8 +106,6 @@ "awsCustomArnUse": "Kullanmak istediğiniz model için geçerli bir Amazon Bedrock ARN'si girin. Format örnekleri:", "awsCustomArnDesc": "ARN içindeki bölgenin yukarıda seçilen AWS Bölgesiyle eşleştiğinden emin olun.", "openRouterApiKey": "OpenRouter API Anahtarı", - "flushModelsCache": "Model önbelleğini temizle", - "flushedModelsCache": "Önbellek temizlendi, lütfen ayarlar görünümünü yeniden açın", "getOpenRouterApiKey": "OpenRouter API Anahtarı Al", "apiKeyStorageNotice": "API anahtarları VSCode'un Gizli Depolamasında güvenli bir şekilde saklanır", "glamaApiKey": "Glama API Anahtarı", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index fe5a0bfd75..51174c4d4f 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -118,8 +118,6 @@ "headerValue": "Giá trị tiêu đề", "noCustomHeaders": "Chưa có tiêu đề tùy chỉnh nào được định nghĩa. Nhấp vào nút + để thêm.", "requestyApiKey": "Khóa API Requesty", - "flushModelsCache": "Xóa bộ nhớ đệm mô hình", - "flushedModelsCache": "Đã xóa bộ nhớ đệm, vui lòng mở lại chế độ xem cài đặt", "getRequestyApiKey": "Lấy khóa API Requesty", "anthropicApiKey": "Khóa API Anthropic", "getAnthropicApiKey": "Lấy khóa API Anthropic", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 0e0cf7f0fe..6a706361e2 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -118,8 +118,6 @@ "glamaApiKey": "Glama API 密钥", "getGlamaApiKey": "获取 Glama API 密钥", "requestyApiKey": "Requesty API 密钥", - "flushModelsCache": "清除模型缓存", - "flushedModelsCache": "缓存已清除,请重新打开设置视图", "getRequestyApiKey": "获取 Requesty API 密钥", "openRouterTransformsText": "自动压缩提示词和消息链到上下文长度限制内 (OpenRouter转换)", "anthropicApiKey": "Anthropic API 密钥", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 6a58cc8a6f..75afc650dd 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -118,8 +118,6 @@ "headerValue": "標頭值", "noCustomHeaders": "尚未定義自訂標頭。點擊 + 按鈕以新增。", "requestyApiKey": "Requesty API 金鑰", - "flushModelsCache": "清除模型快取", - "flushedModelsCache": "快取已清除,請重新開啟設定視圖", "getRequestyApiKey": "取得 Requesty API 金鑰", "openRouterTransformsText": "將提示和訊息鏈壓縮到上下文大小 (OpenRouter 轉換)", "anthropicApiKey": "Anthropic API 金鑰", diff --git a/webview-ui/src/oauth/urls.ts b/webview-ui/src/oauth/urls.ts index e75b65b9c7..205c19cf53 100644 --- a/webview-ui/src/oauth/urls.ts +++ b/webview-ui/src/oauth/urls.ts @@ -1,6 +1,5 @@ export function getCallbackUrl(provider: string, uriScheme?: string) { - const callbackUrl = `${uriScheme || "vscode"}://rooveterinaryinc.roo-cline/${provider}` - return encodeURIComponent(callbackUrl) + return encodeURIComponent(`${uriScheme || "vscode"}://rooveterinaryinc.roo-cline/${provider}`) } export function getGlamaAuthUrl(uriScheme?: string) { @@ -14,7 +13,3 @@ export function getOpenRouterAuthUrl(uriScheme?: string) { export function getRequestyAuthUrl(uriScheme?: string) { return `https://app.requesty.ai/oauth/authorize?callback_url=${getCallbackUrl("requesty", uriScheme)}` } - -export function getRequestyApiKeyUrl() { - return "https://app.requesty.ai/api-keys" -} From d5044dd5ca190716752b6b729c1b9b6da12976ab Mon Sep 17 00:00:00 2001 From: cte Date: Mon, 5 May 2025 21:59:00 -0700 Subject: [PATCH 2/5] Add missing translations --- webview-ui/src/i18n/locales/ca/settings.json | 4 ++++ webview-ui/src/i18n/locales/de/settings.json | 4 ++++ webview-ui/src/i18n/locales/es/settings.json | 4 ++++ webview-ui/src/i18n/locales/fr/settings.json | 4 ++++ webview-ui/src/i18n/locales/hi/settings.json | 4 ++++ webview-ui/src/i18n/locales/it/settings.json | 4 ++++ webview-ui/src/i18n/locales/ja/settings.json | 4 ++++ webview-ui/src/i18n/locales/ko/settings.json | 4 ++++ webview-ui/src/i18n/locales/pl/settings.json | 4 ++++ webview-ui/src/i18n/locales/pt-BR/settings.json | 4 ++++ webview-ui/src/i18n/locales/ru/settings.json | 4 ++++ webview-ui/src/i18n/locales/tr/settings.json | 4 ++++ webview-ui/src/i18n/locales/vi/settings.json | 4 ++++ webview-ui/src/i18n/locales/zh-CN/settings.json | 4 ++++ webview-ui/src/i18n/locales/zh-TW/settings.json | 4 ++++ 15 files changed, 60 insertions(+) diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index ca7546b2a5..c375463fa0 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -120,6 +120,10 @@ "getGlamaApiKey": "Obtenir clau API de Glama", "requestyApiKey": "Clau API de Requesty", "getRequestyApiKey": "Obtenir clau API de Requesty", + "refreshModels": { + "label": "Actualitzar models", + "hint": "Si us plau, torneu a obrir la configuració per veure els models més recents." + }, "anthropicApiKey": "Clau API d'Anthropic", "getAnthropicApiKey": "Obtenir clau API d'Anthropic", "anthropicUseAuthToken": "Passar la clau API d'Anthropic com a capçalera d'autorització en lloc de X-Api-Key", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index db4398402f..e3afa643b5 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Keine benutzerdefinierten Headers definiert. Klicke auf die + Schaltfläche, um einen hinzuzufügen.", "requestyApiKey": "Requesty API-Schlüssel", "getRequestyApiKey": "Requesty API-Schlüssel erhalten", + "refreshModels": { + "label": "Modelle aktualisieren", + "hint": "Bitte öffne die Einstellungen erneut, um die neuesten Modelle zu sehen." + }, "openRouterTransformsText": "Prompts und Nachrichtenketten auf Kontextgröße komprimieren (OpenRouter Transformationen)", "anthropicApiKey": "Anthropic API-Schlüssel", "getAnthropicApiKey": "Anthropic API-Schlüssel erhalten", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 4a7191ffeb..eb732605ff 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "No hay encabezados personalizados definidos. Haga clic en el botón + para añadir uno.", "requestyApiKey": "Clave API de Requesty", "getRequestyApiKey": "Obtener clave API de Requesty", + "refreshModels": { + "label": "Actualizar modelos", + "hint": "Por favor, vuelve a abrir la configuración para ver los modelos más recientes." + }, "openRouterTransformsText": "Comprimir prompts y cadenas de mensajes al tamaño del contexto (Transformaciones de OpenRouter)", "anthropicApiKey": "Clave API de Anthropic", "getAnthropicApiKey": "Obtener clave API de Anthropic", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index b2a1ef33e4..7e55b4a43f 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Aucun en-tête personnalisé défini. Cliquez sur le bouton + pour en ajouter un.", "requestyApiKey": "Clé API Requesty", "getRequestyApiKey": "Obtenir la clé API Requesty", + "refreshModels": { + "label": "Actualiser les modèles", + "hint": "Veuillez rouvrir les paramètres pour voir les modèles les plus récents." + }, "openRouterTransformsText": "Compresser les prompts et chaînes de messages à la taille du contexte (Transformations OpenRouter)", "anthropicApiKey": "Clé API Anthropic", "getAnthropicApiKey": "Obtenir la clé API Anthropic", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index f62d637356..6dc671782f 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "कोई कस्टम हेडर परिभाषित नहीं है। एक जोड़ने के लिए + बटन पर क्लिक करें।", "requestyApiKey": "Requesty API कुंजी", "getRequestyApiKey": "Requesty API कुंजी प्राप्त करें", + "refreshModels": { + "label": "मॉडल रिफ्रेश करें", + "hint": "नवीनतम मॉडल देखने के लिए कृपया सेटिंग्स को फिर से खोलें।" + }, "openRouterTransformsText": "संदर्भ आकार के लिए प्रॉम्प्ट और संदेश श्रृंखलाओं को संपीड़ित करें (OpenRouter ट्रांसफॉर्म)", "anthropicApiKey": "Anthropic API कुंजी", "getAnthropicApiKey": "Anthropic API कुंजी प्राप्त करें", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 1c20c2d595..b47f31aa25 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Nessuna intestazione personalizzata definita. Fai clic sul pulsante + per aggiungerne una.", "requestyApiKey": "Chiave API Requesty", "getRequestyApiKey": "Ottieni chiave API Requesty", + "refreshModels": { + "label": "Aggiorna modelli", + "hint": "Riapri le impostazioni per vedere i modelli più recenti." + }, "openRouterTransformsText": "Comprimi prompt e catene di messaggi alla dimensione del contesto (Trasformazioni OpenRouter)", "anthropicApiKey": "Chiave API Anthropic", "getAnthropicApiKey": "Ottieni chiave API Anthropic", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 1ed0ab7c26..3430fb835a 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "カスタムヘッダーが定義されていません。+ ボタンをクリックして追加してください。", "requestyApiKey": "Requesty APIキー", "getRequestyApiKey": "Requesty APIキーを取得", + "refreshModels": { + "label": "モデルを更新", + "hint": "最新のモデルを表示するには設定を再度開いてください。" + }, "openRouterTransformsText": "プロンプトとメッセージチェーンをコンテキストサイズに圧縮 (OpenRouter Transforms)", "anthropicApiKey": "Anthropic APIキー", "getAnthropicApiKey": "Anthropic APIキーを取得", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index b0ceaee530..1816c1ab10 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "정의된 사용자 정의 헤더가 없습니다. + 버튼을 클릭하여 추가하세요.", "requestyApiKey": "Requesty API 키", "getRequestyApiKey": "Requesty API 키 받기", + "refreshModels": { + "label": "모델 새로고침", + "hint": "최신 모델을 보려면 설정을 다시 열어주세요." + }, "openRouterTransformsText": "프롬프트와 메시지 체인을 컨텍스트 크기로 압축 (OpenRouter Transforms)", "anthropicApiKey": "Anthropic API 키", "getAnthropicApiKey": "Anthropic API 키 받기", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index c4f28f19f6..564a4fac50 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Brak zdefiniowanych niestandardowych nagłówków. Kliknij przycisk +, aby dodać.", "requestyApiKey": "Klucz API Requesty", "getRequestyApiKey": "Uzyskaj klucz API Requesty", + "refreshModels": { + "label": "Odśwież modele", + "hint": "Proszę ponownie otworzyć ustawienia, aby zobaczyć najnowsze modele." + }, "openRouterTransformsText": "Kompresuj podpowiedzi i łańcuchy wiadomości do rozmiaru kontekstu (Transformacje OpenRouter)", "anthropicApiKey": "Klucz API Anthropic", "getAnthropicApiKey": "Uzyskaj klucz API Anthropic", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 76b3f597d2..628378a754 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Nenhum cabeçalho personalizado definido. Clique no botão + para adicionar um.", "requestyApiKey": "Chave de API Requesty", "getRequestyApiKey": "Obter chave de API Requesty", + "refreshModels": { + "label": "Atualizar modelos", + "hint": "Por favor, reabra as configurações para ver os modelos mais recentes." + }, "openRouterTransformsText": "Comprimir prompts e cadeias de mensagens para o tamanho do contexto (Transformações OpenRouter)", "anthropicApiKey": "Chave de API Anthropic", "getAnthropicApiKey": "Obter chave de API Anthropic", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index f46d1d9837..3d03429ea7 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Пользовательские заголовки не определены. Нажмите кнопку +, чтобы добавить.", "requestyApiKey": "Requesty API-ключ", "getRequestyApiKey": "Получить Requesty API-ключ", + "refreshModels": { + "label": "Обновить модели", + "hint": "Пожалуйста, откройте настройки заново, чтобы увидеть последние модели." + }, "openRouterTransformsText": "Сжимать подсказки и цепочки сообщений до размера контекста (OpenRouter Transforms)", "anthropicApiKey": "Anthropic API-ключ", "getAnthropicApiKey": "Получить Anthropic API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 580e35ee04..f6c0db8856 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "Tanımlanmış özel başlık yok. Eklemek için + düğmesine tıklayın.", "requestyApiKey": "Requesty API Anahtarı", "getRequestyApiKey": "Requesty API Anahtarı Al", + "refreshModels": { + "label": "Modelleri Yenile", + "hint": "En son modelleri görmek için lütfen ayarları yeniden açın." + }, "openRouterTransformsText": "İstem ve mesaj zincirlerini bağlam boyutuna sıkıştır (OpenRouter Dönüşümleri)", "anthropicApiKey": "Anthropic API Anahtarı", "getAnthropicApiKey": "Anthropic API Anahtarı Al", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 51174c4d4f..284ea759be 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -179,6 +179,10 @@ "warning": "Lưu ý: Roo Code sử dụng các lời nhắc phức tạp và hoạt động tốt nhất với các mô hình Claude. Các mô hình kém mạnh hơn có thể không hoạt động như mong đợi." }, "openRouterTransformsText": "Nén lời nhắc và chuỗi tin nhắn theo kích thước ngữ cảnh (OpenRouter Transforms)", + "refreshModels": { + "label": "Làm mới mô hình", + "hint": "Vui lòng mở lại cài đặt để xem các mô hình mới nhất." + }, "unboundApiKey": "Khóa API Unbound", "getUnboundApiKey": "Lấy khóa API Unbound", "humanRelay": { diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 6a706361e2..28fc887170 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -119,6 +119,10 @@ "getGlamaApiKey": "获取 Glama API 密钥", "requestyApiKey": "Requesty API 密钥", "getRequestyApiKey": "获取 Requesty API 密钥", + "refreshModels": { + "label": "刷新模型", + "hint": "请重新打开设置以查看最新模型。" + }, "openRouterTransformsText": "自动压缩提示词和消息链到上下文长度限制内 (OpenRouter转换)", "anthropicApiKey": "Anthropic API 密钥", "getAnthropicApiKey": "获取 Anthropic API 密钥", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 75afc650dd..cbbf1575de 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -119,6 +119,10 @@ "noCustomHeaders": "尚未定義自訂標頭。點擊 + 按鈕以新增。", "requestyApiKey": "Requesty API 金鑰", "getRequestyApiKey": "取得 Requesty API 金鑰", + "refreshModels": { + "label": "重新整理模型", + "hint": "請重新開啟設定以查看最新模型。" + }, "openRouterTransformsText": "將提示和訊息鏈壓縮到上下文大小 (OpenRouter 轉換)", "anthropicApiKey": "Anthropic API 金鑰", "getAnthropicApiKey": "取得 Anthropic API 金鑰", From 1851b44011557d3516e8ca1fcf75d0e7718e4e44 Mon Sep 17 00:00:00 2001 From: cte Date: Mon, 5 May 2025 22:57:16 -0700 Subject: [PATCH 3/5] More progress --- evals/packages/types/src/roo-code.ts | 2 - src/exports/roo-code.d.ts | 1 - src/exports/types.ts | 1 - src/schemas/index.ts | 2 - .../src/components/settings/ApiOptions.tsx | 7 +- .../src/components/settings/constants.ts | 2 +- .../components/ui/hooks/useSelectedModel.ts | 191 +++++++++++------- 7 files changed, 119 insertions(+), 87 deletions(-) diff --git a/evals/packages/types/src/roo-code.ts b/evals/packages/types/src/roo-code.ts index f530dc3ea1..693192f915 100644 --- a/evals/packages/types/src/roo-code.ts +++ b/evals/packages/types/src/roo-code.ts @@ -355,7 +355,6 @@ export const providerSettingsSchema = z.object({ awsRegion: z.string().optional(), awsUseCrossRegionInference: z.boolean().optional(), awsUsePromptCache: z.boolean().optional(), - awspromptCacheId: z.string().optional(), awsProfile: z.string().optional(), awsUseProfile: z.boolean().optional(), awsCustomArn: z.string().optional(), @@ -455,7 +454,6 @@ const providerSettingsRecord: ProviderSettingsRecord = { awsRegion: undefined, awsUseCrossRegionInference: undefined, awsUsePromptCache: undefined, - awspromptCacheId: undefined, awsProfile: undefined, awsUseProfile: undefined, awsCustomArn: undefined, diff --git a/src/exports/roo-code.d.ts b/src/exports/roo-code.d.ts index 8a7452dfb8..0f2250f6c2 100644 --- a/src/exports/roo-code.d.ts +++ b/src/exports/roo-code.d.ts @@ -42,7 +42,6 @@ type ProviderSettings = { awsRegion?: string | undefined awsUseCrossRegionInference?: boolean | undefined awsUsePromptCache?: boolean | undefined - awspromptCacheId?: string | undefined awsProfile?: string | undefined awsUseProfile?: boolean | undefined awsCustomArn?: string | undefined diff --git a/src/exports/types.ts b/src/exports/types.ts index b3d441e9ab..1cb395156e 100644 --- a/src/exports/types.ts +++ b/src/exports/types.ts @@ -43,7 +43,6 @@ type ProviderSettings = { awsRegion?: string | undefined awsUseCrossRegionInference?: boolean | undefined awsUsePromptCache?: boolean | undefined - awspromptCacheId?: string | undefined awsProfile?: string | undefined awsUseProfile?: boolean | undefined awsCustomArn?: string | undefined diff --git a/src/schemas/index.ts b/src/schemas/index.ts index e69fff6dcc..0a59e5f13c 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -366,7 +366,6 @@ export const providerSettingsSchema = z.object({ awsRegion: z.string().optional(), awsUseCrossRegionInference: z.boolean().optional(), awsUsePromptCache: z.boolean().optional(), - awspromptCacheId: z.string().optional(), awsProfile: z.string().optional(), awsUseProfile: z.boolean().optional(), awsCustomArn: z.string().optional(), @@ -471,7 +470,6 @@ const providerSettingsRecord: ProviderSettingsRecord = { awsRegion: undefined, awsUseCrossRegionInference: undefined, awsUsePromptCache: undefined, - awspromptCacheId: undefined, awsProfile: undefined, awsUseProfile: undefined, awsCustomArn: undefined, diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 101effc916..70aa53aee6 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -104,13 +104,14 @@ const ApiOptions = ({ return result } - // Debounced effect to update the main configuration when local customHeaders state stabilizes. + // Debounced effect to update the main configuration when local + // customHeaders state stabilizes. useDebounce( () => { const currentConfigHeaders = apiConfiguration?.openAiHeaders || {} const newHeadersObject = convertHeadersToObject(customHeaders) - // Only update if the processed object is different from the current config + // Only update if the processed object is different from the current config. if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(newHeadersObject)) { setApiConfigurationField("openAiHeaders", newHeadersObject) } @@ -140,7 +141,7 @@ const ApiOptions = ({ const { data: routerModels, refetch: refetchRouterModels } = useRouterModels() - // Update apiConfiguration.aiModelId whenever selectedModelId changes. + // Update `apiModelId` whenever `selectedModelId` changes. useEffect(() => { if (selectedModelId) { setApiConfigurationField("apiModelId", selectedModelId) diff --git a/webview-ui/src/components/settings/constants.ts b/webview-ui/src/components/settings/constants.ts index 2226f70907..1367ed7858 100644 --- a/webview-ui/src/components/settings/constants.ts +++ b/webview-ui/src/components/settings/constants.ts @@ -47,7 +47,7 @@ export const PROVIDERS = [ { value: "unbound", label: "Unbound" }, { value: "requesty", label: "Requesty" }, { value: "human-relay", label: "Human Relay" }, - { value: "xai", label: "xAI" }, + { value: "xai", label: "xAI (Grok)" }, { value: "groq", label: "Groq" }, { value: "chutes", label: "Chutes AI" }, ].sort((a, b) => a.label.localeCompare(b.label)) diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index b02a4d024b..46ced90e64 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -36,97 +36,134 @@ import { useRouterModels } from "./useRouterModels" export const useSelectedModel = (apiConfiguration?: ApiConfiguration) => { const { data: routerModels, isLoading, isError } = useRouterModels() const provider = apiConfiguration?.apiProvider || "anthropic" - const id = apiConfiguration ? getSelectedModelId({ provider, apiConfiguration }) : anthropicDefaultModelId - const info = routerModels ? getSelectedModelInfo({ provider, id, apiConfiguration, routerModels }) : undefined - return { provider, id, info, isLoading, isError } -} -function getSelectedModelId({ provider, apiConfiguration }: { provider: string; apiConfiguration: ApiConfiguration }) { - switch (provider) { - case "openrouter": - return apiConfiguration.openRouterModelId ?? openRouterDefaultModelId - case "requesty": - return apiConfiguration.requestyModelId ?? requestyDefaultModelId - case "glama": - return apiConfiguration.glamaModelId ?? glamaDefaultModelId - case "unbound": - return apiConfiguration.unboundModelId ?? unboundDefaultModelId - case "openai": - return apiConfiguration.openAiModelId || "" - case "ollama": - return apiConfiguration.ollamaModelId || "" - case "lmstudio": - return apiConfiguration.lmStudioModelId || "" - case "vscode-lm": - return apiConfiguration?.vsCodeLmModelSelector - ? `${apiConfiguration.vsCodeLmModelSelector.vendor}/${apiConfiguration.vsCodeLmModelSelector.family}` - : "" - default: - return apiConfiguration.apiModelId ?? anthropicDefaultModelId - } + const { id, info } = + apiConfiguration && routerModels + ? getSelectedModel({ provider, apiConfiguration, routerModels }) + : { id: anthropicDefaultModelId, info: undefined } + + return { provider, id, info, isLoading, isError } } -function getSelectedModelInfo({ +function getSelectedModel({ provider, - id, apiConfiguration, routerModels, }: { provider: string - id: string - apiConfiguration?: ApiConfiguration + apiConfiguration: ApiConfiguration routerModels: RouterModels -}): ModelInfo { +}): { id: string; info: ModelInfo } { switch (provider) { - case "openrouter": - return routerModels.openrouter[id] ?? routerModels.openrouter[openRouterDefaultModelId] - case "requesty": - return routerModels.requesty[id] ?? routerModels.requesty[requestyDefaultModelId] - case "glama": - return routerModels.glama[id] ?? routerModels.glama[glamaDefaultModelId] - case "unbound": - return routerModels.unbound[id] ?? routerModels.unbound[unboundDefaultModelId] - case "xai": - return xaiModels[id as keyof typeof xaiModels] ?? xaiModels[xaiDefaultModelId] - case "groq": - return groqModels[id as keyof typeof groqModels] ?? groqModels[groqDefaultModelId] - case "chutes": - return chutesModels[id as keyof typeof chutesModels] ?? chutesModels[chutesDefaultModelId] - case "bedrock": + case "openrouter": { + const id = apiConfiguration.openRouterModelId ?? openRouterDefaultModelId + const info = routerModels.openrouter[id] + return info + ? { id, info } + : { id: openRouterDefaultModelId, info: routerModels.openrouter[openRouterDefaultModelId] } + } + case "requesty": { + const id = apiConfiguration.requestyModelId ?? requestyDefaultModelId + const info = routerModels.requesty[id] + return info + ? { id, info } + : { id: requestyDefaultModelId, info: routerModels.requesty[requestyDefaultModelId] } + } + case "glama": { + const id = apiConfiguration.glamaModelId ?? glamaDefaultModelId + const info = routerModels.glama[id] + return info ? { id, info } : { id: glamaDefaultModelId, info: routerModels.glama[glamaDefaultModelId] } + } + case "unbound": { + const id = apiConfiguration.unboundModelId ?? unboundDefaultModelId + const info = routerModels.unbound[id] + return info + ? { id, info } + : { id: unboundDefaultModelId, info: routerModels.unbound[unboundDefaultModelId] } + } + case "xai": { + const id = apiConfiguration.apiModelId ?? xaiDefaultModelId + const info = xaiModels[id as keyof typeof xaiModels] + return info ? { id, info } : { id: xaiDefaultModelId, info: xaiModels[xaiDefaultModelId] } + } + case "groq": { + const id = apiConfiguration.apiModelId ?? groqDefaultModelId + const info = groqModels[id as keyof typeof groqModels] + return info ? { id, info } : { id: groqDefaultModelId, info: groqModels[groqDefaultModelId] } + } + case "chutes": { + const id = apiConfiguration.apiModelId ?? chutesDefaultModelId + const info = chutesModels[id as keyof typeof chutesModels] + return info ? { id, info } : { id: chutesDefaultModelId, info: chutesModels[chutesDefaultModelId] } + } + case "bedrock": { + const id = apiConfiguration.apiModelId ?? bedrockDefaultModelId + const info = bedrockModels[id as keyof typeof bedrockModels] + // Special case for custom ARN. if (id === "custom-arn") { - return { maxTokens: 5000, contextWindow: 128_000, supportsPromptCache: false, supportsImages: true } + return { + id, + info: { maxTokens: 5000, contextWindow: 128_000, supportsPromptCache: false, supportsImages: true }, + } } - return bedrockModels[id as keyof typeof bedrockModels] ?? bedrockModels[bedrockDefaultModelId] - case "vertex": - return vertexModels[id as keyof typeof vertexModels] ?? vertexModels[vertexDefaultModelId] - case "gemini": - return geminiModels[id as keyof typeof geminiModels] ?? geminiModels[geminiDefaultModelId] - case "deepseek": - return deepSeekModels[id as keyof typeof deepSeekModels] ?? deepSeekModels[deepSeekDefaultModelId] - case "openai-native": - return ( - openAiNativeModels[id as keyof typeof openAiNativeModels] ?? - openAiNativeModels[openAiNativeDefaultModelId] - ) - case "mistral": - return mistralModels[id as keyof typeof mistralModels] ?? mistralModels[mistralDefaultModelId] - case "openai": - return apiConfiguration?.openAiCustomModelInfo || openAiModelInfoSaneDefaults - case "ollama": - return openAiModelInfoSaneDefaults - case "lmstudio": - return openAiModelInfoSaneDefaults - case "vscode-lm": + return info ? { id, info } : { id: bedrockDefaultModelId, info: bedrockModels[bedrockDefaultModelId] } + } + case "vertex": { + const id = apiConfiguration.apiModelId ?? vertexDefaultModelId + const info = vertexModels[id as keyof typeof vertexModels] + return info ? { id, info } : { id: vertexDefaultModelId, info: vertexModels[vertexDefaultModelId] } + } + case "gemini": { + const id = apiConfiguration.apiModelId ?? geminiDefaultModelId + const info = geminiModels[id as keyof typeof geminiModels] + return info ? { id, info } : { id: geminiDefaultModelId, info: geminiModels[geminiDefaultModelId] } + } + case "deepseek": { + const id = apiConfiguration.apiModelId ?? deepSeekDefaultModelId + const info = deepSeekModels[id as keyof typeof deepSeekModels] + return info ? { id, info } : { id: deepSeekDefaultModelId, info: deepSeekModels[deepSeekDefaultModelId] } + } + case "openai-native": { + const id = apiConfiguration.apiModelId ?? openAiNativeDefaultModelId + const info = openAiNativeModels[id as keyof typeof openAiNativeModels] + return info + ? { id, info } + : { id: openAiNativeDefaultModelId, info: openAiNativeModels[openAiNativeDefaultModelId] } + } + case "mistral": { + const id = apiConfiguration.apiModelId ?? mistralDefaultModelId + const info = mistralModels[id as keyof typeof mistralModels] + return info ? { id, info } : { id: mistralDefaultModelId, info: mistralModels[mistralDefaultModelId] } + } + case "openai": { + const id = apiConfiguration.openAiModelId ?? "" + const info = apiConfiguration?.openAiCustomModelInfo ?? openAiModelInfoSaneDefaults + return { id, info } + } + case "ollama": { + const id = apiConfiguration.ollamaModelId ?? "" + const info = openAiModelInfoSaneDefaults + return { id, info } + } + case "lmstudio": { + const id = apiConfiguration.lmStudioModelId ?? "" + const info = openAiModelInfoSaneDefaults + return { id, info } + } + case "vscode-lm": { + const id = apiConfiguration?.vsCodeLmModelSelector + ? `${apiConfiguration.vsCodeLmModelSelector.vendor}/${apiConfiguration.vsCodeLmModelSelector.family}` + : vscodeLlmDefaultModelId const modelFamily = apiConfiguration?.vsCodeLmModelSelector?.family ?? vscodeLlmDefaultModelId - - return { - ...openAiModelInfoSaneDefaults, - ...vscodeLlmModels[modelFamily as keyof typeof vscodeLlmModels], - supportsImages: false, // VSCode LM API currently doesn't support images. - } - default: - return anthropicModels[id as keyof typeof anthropicModels] ?? anthropicModels[anthropicDefaultModelId] + const info = vscodeLlmModels[modelFamily as keyof typeof vscodeLlmModels] + return { id, info: { ...openAiModelInfoSaneDefaults, ...info, supportsImages: false } } // VSCode LM API currently doesn't support images. + } + default: { + const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId + const info = anthropicModels[id as keyof typeof anthropicModels] + return info ? { id, info } : { id: anthropicDefaultModelId, info: anthropicModels[anthropicDefaultModelId] } + } } } From 74fe2aed98978a30c3988d01fa03c2f5c9c16fbb Mon Sep 17 00:00:00 2001 From: cte Date: Mon, 5 May 2025 23:01:48 -0700 Subject: [PATCH 4/5] Fix error messages in BedrockCustomArn --- .../settings/providers/BedrockCustomArn.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx b/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx index 42ac75d27f..f24d9ef81c 100644 --- a/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx +++ b/webview-ui/src/components/settings/providers/BedrockCustomArn.tsx @@ -1,9 +1,10 @@ +import { useMemo } from "react" import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" import { ApiConfiguration } from "@roo/shared/api" + import { validateBedrockArn } from "@src/utils/validate" import { useAppTranslation } from "@src/i18n/TranslationContext" -import { useMemo } from "react" type BedrockCustomArnProps = { apiConfiguration: ApiConfiguration @@ -38,13 +39,14 @@ export const BedrockCustomArn = ({ apiConfiguration, setApiConfigurationField }: {t("settings:providers.awsCustomArnDesc")}
- {!validation.isValid && ( + {!validation.isValid ? (
{validation.errorMessage || t("settings:providers.invalidArnFormat")}
- )} - {validation.errorMessage && ( -
{validation.errorMessage}
+ ) : ( + validation.errorMessage && ( +
{validation.errorMessage}
+ ) )} ) From 0329e3544ef3cde5b24fb1ebf53a5ce78a39920a Mon Sep 17 00:00:00 2001 From: cte Date: Mon, 5 May 2025 23:03:51 -0700 Subject: [PATCH 5/5] PR feedback --- .../src/components/ui/hooks/useSelectedModel.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 46ced90e64..e82e6670a9 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -1,7 +1,8 @@ import { - ApiConfiguration, - RouterModels, - ModelInfo, + type ProviderName, + type ApiConfiguration, + type RouterModels, + type ModelInfo, anthropicDefaultModelId, anthropicModels, bedrockDefaultModelId, @@ -50,7 +51,7 @@ function getSelectedModel({ apiConfiguration, routerModels, }: { - provider: string + provider: ProviderName apiConfiguration: ApiConfiguration routerModels: RouterModels }): { id: string; info: ModelInfo } { @@ -160,6 +161,9 @@ function getSelectedModel({ const info = vscodeLlmModels[modelFamily as keyof typeof vscodeLlmModels] return { id, info: { ...openAiModelInfoSaneDefaults, ...info, supportsImages: false } } // VSCode LM API currently doesn't support images. } + // case "anthropic": + // case "human-relay": + // case "fake-ai": default: { const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId const info = anthropicModels[id as keyof typeof anthropicModels]