From e8197fb2a525f7ac25682d8406316fb8a1c2f050 Mon Sep 17 00:00:00 2001 From: Jerome Date: Thu, 12 Jun 2025 14:26:08 +0100 Subject: [PATCH] Add persistent model selection with localStorage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Features - **Sticky model selection**: Chosen model persists across browser sessions - **Automatic restoration**: Saved model is restored when loading models - **Validation**: Invalid saved models are automatically cleared - **Provider switching**: Model selection is reset when switching providers ## Implementation Details - Model ID saved to localStorage on selection - Model restored during loadModels() if still available - Saved selection cleared when: - Switching inference providers - Logging out - Model no longer exists in available models ## User Experience - Users no longer need to reselect their preferred model after refresh - Model selector maintains state across page reloads - Graceful handling when saved model becomes unavailable ## Technical Notes - Uses 'selected_model_id' localStorage key - Integrates with existing InferenceContext state management - Maintains backward compatibility with existing provider logic 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/contexts/InferenceContext.tsx | 40 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/contexts/InferenceContext.tsx b/src/contexts/InferenceContext.tsx index 15d2d33..08dea4a 100644 --- a/src/contexts/InferenceContext.tsx +++ b/src/contexts/InferenceContext.tsx @@ -42,12 +42,20 @@ export function InferenceContextProvider({ children }: InferenceProviderProps) { const [provider, setProviderState] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); - const [selectedModelId, setSelectedModelId] = useState(undefined); + const [selectedModelId, setSelectedModelId] = useState(() => { + // Load saved model selection from localStorage + return localStorage.getItem('selected_model_id') || undefined; + }); const [_, setAuthStateVersion] = useState(0); // Force re-renders on auth changes const setProvider = useCallback((newProvider: InferenceProvider) => { setProviderState(newProvider); setSelectedModelId(undefined); + + // Clear saved model selection when switching providers + // (it will be restored during loadModels if still valid) + localStorage.removeItem('selected_model_id'); + setError(null); setAuthStateVersion(prev => prev + 1); // Trigger re-render }, []); @@ -58,6 +66,10 @@ export function InferenceContextProvider({ children }: InferenceProviderProps) { } setProviderState(null); setSelectedModelId(undefined); + + // Clear saved model selection + localStorage.removeItem('selected_model_id'); + setError(null); setAuthStateVersion(prev => prev + 1); }, [provider]); @@ -115,6 +127,14 @@ export function InferenceContextProvider({ children }: InferenceProviderProps) { try { provider.selectModel(modelId); setSelectedModelId(modelId); + + // Persist model selection to localStorage + if (modelId) { + localStorage.setItem('selected_model_id', modelId); + } else { + localStorage.removeItem('selected_model_id'); + } + setError(null); } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to select model'; @@ -133,8 +153,22 @@ export function InferenceContextProvider({ children }: InferenceProviderProps) { try { const models = await provider.loadModels(); - // Update selectedModelId to match what the provider selected as default - setSelectedModelId(provider.selectedModel?.id); + + // Try to restore saved model selection + const savedModelId = localStorage.getItem('selected_model_id'); + if (savedModelId && models.find(m => m.id === savedModelId)) { + // Saved model exists in the available models, select it + provider.selectModel(savedModelId); + setSelectedModelId(savedModelId); + } else { + // Use provider's default selection or clear invalid saved selection + if (savedModelId && !models.find(m => m.id === savedModelId)) { + // Remove invalid saved model + localStorage.removeItem('selected_model_id'); + } + setSelectedModelId(provider.selectedModel?.id); + } + return models; } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to load models';