diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index c765fa4707..c88dcc2051 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -1834,6 +1834,12 @@ export class ClineProvider implements vscode.WebviewViewProvider { if (!apiKey) { apiKey = (await this.getSecret("requestyApiKey")) as string } + + if (!apiKey) { + this.outputChannel.appendLine("No Requesty API key found") + return models + } + if (apiKey) { config["headers"] = { Authorization: `Bearer ${apiKey}` } } diff --git a/webview-ui/src/components/settings/ModelPicker.tsx b/webview-ui/src/components/settings/ModelPicker.tsx index 82606c5aa2..f6b6197d82 100644 --- a/webview-ui/src/components/settings/ModelPicker.tsx +++ b/webview-ui/src/components/settings/ModelPicker.tsx @@ -1,6 +1,6 @@ import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import debounce from "debounce" -import { useMemo, useState, useCallback, useEffect } from "react" +import { useMemo, useState, useCallback, useEffect, useRef } from "react" import { useMount } from "react-use" import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons" @@ -54,8 +54,10 @@ export const ModelPicker = ({ const [open, setOpen] = useState(false) const [value, setValue] = useState(defaultModelId) const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) + const prevRefreshValuesRef = useRef | undefined>() + + const { apiConfiguration, [modelsKey]: models, onUpdateApiConfig, setApiConfiguration } = useExtensionState() - const { apiConfiguration, setApiConfiguration, [modelsKey]: models, onUpdateApiConfig } = useExtensionState() const modelIds = useMemo( () => (Array.isArray(models) ? models : Object.keys(models)).sort((a, b) => a.localeCompare(b)), [models], @@ -80,22 +82,42 @@ export const ModelPicker = ({ [apiConfiguration, configKey, infoKey, models, onUpdateApiConfig, setApiConfiguration], ) - const debouncedRefreshModels = useMemo( - () => - debounce(() => { - const message = refreshValues - ? { type: refreshMessageType, values: refreshValues } - : { type: refreshMessageType } - vscode.postMessage(message) - }, 50), - [refreshMessageType, refreshValues], - ) + const debouncedRefreshModels = useMemo(() => { + return debounce(() => { + const message = refreshValues + ? { type: refreshMessageType, values: refreshValues } + : { type: refreshMessageType } + vscode.postMessage(message) + }, 100) + }, [refreshMessageType, refreshValues]) useMount(() => { debouncedRefreshModels() return () => debouncedRefreshModels.clear() }) + useEffect(() => { + if (!refreshValues) { + prevRefreshValuesRef.current = undefined + return + } + + // Check if all values in refreshValues are truthy + if (Object.values(refreshValues).some((value) => !value)) { + prevRefreshValuesRef.current = undefined + return + } + + // Compare with previous values + const prevValues = prevRefreshValuesRef.current + if (prevValues && JSON.stringify(prevValues) === JSON.stringify(refreshValues)) { + return + } + + prevRefreshValuesRef.current = refreshValues + debouncedRefreshModels() + }, [debouncedRefreshModels, refreshValues]) + useEffect(() => setValue(selectedModelId), [selectedModelId]) return ( diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 6f4a196d2a..3fec42f932 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -151,7 +151,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode vscode.postMessage({ type: "upsertApiConfiguration", text: currentState.currentApiConfigName, - apiConfiguration: apiConfig, + apiConfiguration: { ...currentState.apiConfiguration, ...apiConfig }, }) return currentState // No state update needed })