diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 38d2ceebd3..5174be4dae 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -3,6 +3,7 @@ import { convertHeadersToObject } from "./utils/headers" import { useDebounce } from "react-use" import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { ExternalLinkIcon } from "@radix-ui/react-icons" +import isEqual from "fast-deep-equal" import { type ProviderName, @@ -116,7 +117,7 @@ const ApiOptions = ({ useEffect(() => { const propHeaders = apiConfiguration?.openAiHeaders || {} - if (JSON.stringify(customHeaders) !== JSON.stringify(Object.entries(propHeaders))) { + if (!isEqual(customHeaders, Object.entries(propHeaders))) { setCustomHeaders(Object.entries(propHeaders)) } }, [apiConfiguration?.openAiHeaders, customHeaders]) @@ -131,7 +132,7 @@ const ApiOptions = ({ const newHeadersObject = convertHeadersToObject(customHeaders) // Only update if the processed object is different from the current config. - if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(newHeadersObject)) { + if (!isEqual(currentConfigHeaders, newHeadersObject)) { setApiConfigurationField("openAiHeaders", newHeadersObject) } }, @@ -213,6 +214,7 @@ const ApiOptions = ({ apiConfiguration?.lmStudioBaseUrl, apiConfiguration?.litellmBaseUrl, apiConfiguration?.litellmApiKey, + apiConfiguration?.openAiHeaders, customHeaders, ], ) diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx index 76e2183531..4770539fdb 100644 --- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx +++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx @@ -16,6 +16,7 @@ import { ExtensionMessage } from "@roo/ExtensionMessage" import { useAppTranslation } from "@src/i18n/TranslationContext" import { Button, StandardTooltip } from "@src/components/ui" +import deepEqual from "fast-deep-equal" import { convertHeadersToObject } from "../utils/headers" import { inputEventTransform, noTransform } from "../transforms" @@ -48,6 +49,12 @@ export const OpenAICompatible = ({ return Object.entries(headers) }) + // Sync local state with parent's headers when they change externally + useEffect(() => { + const headers = apiConfiguration?.openAiHeaders || {} + setCustomHeaders(Object.entries(headers)) + }, [apiConfiguration?.openAiHeaders]) + const handleAddCustomHeader = useCallback(() => { // Only update the local state to show the new row in the UI. setCustomHeaders((prev) => [...prev, ["", ""]]) @@ -91,7 +98,7 @@ export const OpenAICompatible = ({ const newHeadersObject = convertHeadersToObject(customHeaders) // Only update if the processed object is different from the current config - if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(newHeadersObject)) { + if (!deepEqual(currentConfigHeaders, newHeadersObject)) { setApiConfigurationField("openAiHeaders", newHeadersObject) } }, 300)