From 55cfd5d4eebe6fd2455303503d6295d454f5259b Mon Sep 17 00:00:00 2001 From: Eduard Ruzga Date: Mon, 30 Dec 2024 20:05:08 +0200 Subject: [PATCH] fix: refresh model list after api key changes (#944) --- app/components/chat/APIKeyManager.tsx | 18 ++++++ app/components/chat/BaseChat.tsx | 86 ++++++++++++--------------- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/components/chat/APIKeyManager.tsx b/app/components/chat/APIKeyManager.tsx index 28847bc1..d4020486 100644 --- a/app/components/chat/APIKeyManager.tsx +++ b/app/components/chat/APIKeyManager.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { IconButton } from '~/components/ui/IconButton'; import type { ProviderInfo } from '~/types/model'; +import Cookies from 'js-cookie'; interface APIKeyManagerProps { provider: ProviderInfo; @@ -10,6 +11,23 @@ interface APIKeyManagerProps { labelForGetApiKey?: string; } +const apiKeyMemoizeCache: { [k: string]: Record } = {}; + +export function getApiKeysFromCookies() { + const storedApiKeys = Cookies.get('apiKeys'); + let parsedKeys = {}; + + if (storedApiKeys) { + parsedKeys = apiKeyMemoizeCache[storedApiKeys]; + + if (!parsedKeys) { + parsedKeys = apiKeyMemoizeCache[storedApiKeys] = JSON.parse(storedApiKeys); + } + } + + return parsedKeys; +} + // eslint-disable-next-line @typescript-eslint/naming-convention export const APIKeyManager: React.FC = ({ provider, apiKey, setApiKey }) => { const [isEditing, setIsEditing] = useState(false); diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 57c8829b..1777d734 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -12,7 +12,7 @@ import { classNames } from '~/utils/classNames'; import { MODEL_LIST, PROVIDER_LIST, initializeModelList } from '~/utils/constants'; import { Messages } from './Messages.client'; import { SendButton } from './SendButton.client'; -import { APIKeyManager } from './APIKeyManager'; +import { APIKeyManager, getApiKeysFromCookies } from './APIKeyManager'; import Cookies from 'js-cookie'; import * as Tooltip from '@radix-ui/react-tooltip'; @@ -125,52 +125,6 @@ export const BaseChat = React.forwardRef( }, [transcript]); useEffect(() => { - // Load API keys from cookies on component mount - - let parsedApiKeys: Record | undefined = {}; - - try { - const storedApiKeys = Cookies.get('apiKeys'); - - if (storedApiKeys) { - const parsedKeys = JSON.parse(storedApiKeys); - - if (typeof parsedKeys === 'object' && parsedKeys !== null) { - setApiKeys(parsedKeys); - parsedApiKeys = parsedKeys; - } - } - } catch (error) { - console.error('Error loading API keys from cookies:', error); - - // Clear invalid cookie data - Cookies.remove('apiKeys'); - } - - let providerSettings: Record | undefined = undefined; - - try { - const savedProviderSettings = Cookies.get('providers'); - - if (savedProviderSettings) { - const parsedProviderSettings = JSON.parse(savedProviderSettings); - - if (typeof parsedProviderSettings === 'object' && parsedProviderSettings !== null) { - providerSettings = parsedProviderSettings; - } - } - } catch (error) { - console.error('Error loading Provider Settings from cookies:', error); - - // Clear invalid cookie data - Cookies.remove('providers'); - } - - initializeModelList({ apiKeys: parsedApiKeys, providerSettings }).then((modelList) => { - console.log('Model List: ', modelList); - setModelList(modelList); - }); - if (typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; const recognition = new SpeechRecognition(); @@ -202,6 +156,44 @@ export const BaseChat = React.forwardRef( } }, []); + useEffect(() => { + let providerSettings: Record | undefined = undefined; + + try { + const savedProviderSettings = Cookies.get('providers'); + + if (savedProviderSettings) { + const parsedProviderSettings = JSON.parse(savedProviderSettings); + + if (typeof parsedProviderSettings === 'object' && parsedProviderSettings !== null) { + providerSettings = parsedProviderSettings; + } + } + } catch (error) { + console.error('Error loading Provider Settings from cookies:', error); + + // Clear invalid cookie data + Cookies.remove('providers'); + } + + let parsedApiKeys: Record | undefined = {}; + + try { + parsedApiKeys = getApiKeysFromCookies(); + setApiKeys(parsedApiKeys); + } catch (error) { + console.error('Error loading API keys from cookies:', error); + + // Clear invalid cookie data + Cookies.remove('apiKeys'); + } + + initializeModelList({ apiKeys: parsedApiKeys, providerSettings }).then((modelList) => { + console.log('Model List: ', modelList); + setModelList(modelList); + }); + }, [apiKeys]); + const startListening = () => { if (recognition) { recognition.start();