diff --git a/packages/web/src/features/chat/components/chatBox/chatBoxToolbar.tsx b/packages/web/src/features/chat/components/chatBox/chatBoxToolbar.tsx index a0aae38cf..b7f3fce8b 100644 --- a/packages/web/src/features/chat/components/chatBox/chatBoxToolbar.tsx +++ b/packages/web/src/features/chat/components/chatBox/chatBoxToolbar.tsx @@ -27,7 +27,7 @@ export const ChatBoxToolbar = ({ isContextSelectorOpen, onContextSelectorOpenChanged, }: ChatBoxToolbarProps) => { - const { selectedLanguageModel, setSelectedLanguageModel } = useSelectedLanguageModel({ + const { resolvedSelectedLanguageModel, setSelectedLanguageModel } = useSelectedLanguageModel({ languageModels, }); @@ -48,7 +48,7 @@ export const ChatBoxToolbar = ({ ) diff --git a/packages/web/src/features/chat/components/chatBox/languageModelSelector.tsx b/packages/web/src/features/chat/components/chatBox/languageModelSelector.tsx index c8fc0196a..22ead7822 100644 --- a/packages/web/src/features/chat/components/chatBox/languageModelSelector.tsx +++ b/packages/web/src/features/chat/components/chatBox/languageModelSelector.tsx @@ -126,6 +126,12 @@ export const LanguageModelSelector = ({ return ( { selectModel(model) }} diff --git a/packages/web/src/features/chat/useSelectedLanguageModel.ts b/packages/web/src/features/chat/useSelectedLanguageModel.ts index a22b59400..d42e1aa0d 100644 --- a/packages/web/src/features/chat/useSelectedLanguageModel.ts +++ b/packages/web/src/features/chat/useSelectedLanguageModel.ts @@ -9,27 +9,71 @@ type Props = { languageModels: LanguageModelInfo[]; } +const getStoredSelectedLanguageModel = (): LanguageModelInfo | undefined => { + try { + const storedValue = window.localStorage.getItem("selectedLanguageModel"); + if (!storedValue) { + return undefined; + } + + const parsedValue = JSON.parse(storedValue); + if ( + typeof parsedValue === "object" && + parsedValue !== null && + typeof parsedValue.provider === "string" && + typeof parsedValue.model === "string" && + typeof parsedValue.displayName === "string" + ) { + return parsedValue as LanguageModelInfo; + } + + return undefined; + } catch { + return undefined; + } +}; + export const useSelectedLanguageModel = ({ languageModels, }: Props) => { const fallbackLanguageModel = languageModels.length > 0 ? languageModels[0] : undefined; const [selectedLanguageModel, setSelectedLanguageModel] = useLocalStorage( "selectedLanguageModel", - fallbackLanguageModel, + undefined, { initializeWithValue: false, } ); + const availableSelectedLanguageModel = selectedLanguageModel && languageModels.find( + (model) => getLanguageModelKey(model) === getLanguageModelKey(selectedLanguageModel) + ); + + const resolvedSelectedLanguageModel = availableSelectedLanguageModel ?? fallbackLanguageModel; + // Handle the case where the selected language model is no longer // available. Reset to the fallback language model in this case. useEffect(() => { - if (!selectedLanguageModel || !languageModels.find( - (model) => getLanguageModelKey(model) === getLanguageModelKey(selectedLanguageModel) - )) { - setSelectedLanguageModel(fallbackLanguageModel); + if (languageModels.length === 0) { + return; + } + + if (selectedLanguageModel && !availableSelectedLanguageModel) { + setSelectedLanguageModel(() => { + const storedSelectedLanguageModel = getStoredSelectedLanguageModel(); + const availableStoredSelectedLanguageModel = storedSelectedLanguageModel && languageModels.find( + (model) => getLanguageModelKey(model) === getLanguageModelKey(storedSelectedLanguageModel) + ); + + if (availableStoredSelectedLanguageModel) { + return availableStoredSelectedLanguageModel; + } + + return fallbackLanguageModel; + }); } }, [ + availableSelectedLanguageModel, fallbackLanguageModel, languageModels, selectedLanguageModel, @@ -38,6 +82,7 @@ export const useSelectedLanguageModel = ({ return { selectedLanguageModel, + resolvedSelectedLanguageModel, setSelectedLanguageModel, }; -} \ No newline at end of file +}