fix: eliminate model info flicker during settings save with simple React state cache

Fixes #4430

Replace complex cross-window persistence system with a minimal 3-line
React state solution that caches the last known ModelInfo and uses it
as a fallback when selectedModelInfo temporarily becomes unavailable
during settings save.

This simple in-memory approach eliminates the flicker without adding
complexity, cross-window coordination, or background revalidation.
This commit is contained in:
daniel-lxs 2025-11-07 10:40:18 -05:00
parent eedc2649ff
commit d6a42658ca
No known key found for this signature in database
GPG key ID: 21C74479048B3AA6

View file

@ -7,6 +7,7 @@ import { ExternalLinkIcon } from "@radix-ui/react-icons"
import {
type ProviderName,
type ProviderSettings,
type ModelInfo,
DEFAULT_CONSECUTIVE_MISTAKE_LIMIT,
openRouterDefaultModelId,
requestyDefaultModelId,
@ -173,6 +174,9 @@ const ApiOptions = ({
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
const [isAdvancedSettingsOpen, setIsAdvancedSettingsOpen] = useState(false)
// Simple cache to prevent flicker during settings save
const [lastKnownModelInfo, setLastKnownModelInfo] = useState<ModelInfo | undefined>()
const handleInputChange = useCallback(
<K extends keyof ProviderSettings, E>(
field: K,
@ -190,6 +194,16 @@ const ApiOptions = ({
info: selectedModelInfo,
} = useSelectedModel(apiConfiguration)
// Update cache whenever selectedModelInfo is available
useEffect(() => {
if (selectedModelInfo) {
setLastKnownModelInfo(selectedModelInfo)
}
}, [selectedModelInfo])
// Use cached info as fallback when selectedModelInfo is temporarily unavailable
const displayModelInfo = selectedModelInfo || lastKnownModelInfo
const { data: routerModels, refetch: refetchRouterModels } = useRouterModels()
const { data: openRouterModelProviders } = useOpenRouterModelProviders(apiConfiguration?.openRouterModelId, {
@ -749,11 +763,11 @@ const ApiOptions = ({
)}
{/* Only show model info if not deprecated */}
{!selectedModelInfo?.deprecated && (
{!displayModelInfo?.deprecated && (
<ModelInfoView
apiProvider={selectedProvider}
selectedModelId={selectedModelId}
modelInfo={selectedModelInfo}
modelInfo={displayModelInfo}
isDescriptionExpanded={isDescriptionExpanded}
setIsDescriptionExpanded={setIsDescriptionExpanded}
/>
@ -773,16 +787,16 @@ const ApiOptions = ({
key={`${selectedProvider}-${selectedModelId}`}
apiConfiguration={apiConfiguration}
setApiConfigurationField={setApiConfigurationField}
modelInfo={selectedModelInfo}
modelInfo={displayModelInfo}
/>
)}
{/* Gate Verbosity UI by capability flag */}
{selectedModelInfo?.supportsVerbosity && (
{displayModelInfo?.supportsVerbosity && (
<Verbosity
apiConfiguration={apiConfiguration}
setApiConfigurationField={setApiConfigurationField}
modelInfo={selectedModelInfo}
modelInfo={displayModelInfo}
/>
)}
@ -802,12 +816,12 @@ const ApiOptions = ({
fuzzyMatchThreshold={apiConfiguration.fuzzyMatchThreshold}
onChange={(field, value) => setApiConfigurationField(field, value)}
/>
{selectedModelInfo?.supportsTemperature !== false && (
{displayModelInfo?.supportsTemperature !== false && (
<TemperatureControl
value={apiConfiguration.modelTemperature}
onChange={handleInputChange("modelTemperature", noTransform)}
maxValue={2}
defaultValue={selectedModelInfo?.defaultTemperature}
defaultValue={displayModelInfo?.defaultTemperature}
/>
)}
<RateLimitSecondsControl