33 * Preventing TS checks with files presented in the video for a better presentation.
44 */
55import type { Message } from 'ai' ;
6- import React , { type RefCallback , useEffect , useState } from 'react' ;
6+ import React , { type RefCallback , useCallback , useEffect , useState } from 'react' ;
77import { ClientOnly } from 'remix-utils/client-only' ;
88import { Menu } from '~/components/sidebar/Menu.client' ;
99import { IconButton } from '~/components/ui/IconButton' ;
@@ -31,6 +31,7 @@ import { toast } from 'react-toastify';
3131import StarterTemplates from './StarterTemplates' ;
3232import type { ActionAlert } from '~/types/actions' ;
3333import ChatAlert from './ChatAlert' ;
34+ import { LLMManager } from '~/lib/modules/llm/manager' ;
3435
3536const TEXTAREA_MIN_HEIGHT = 76 ;
3637
@@ -100,26 +101,36 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
100101 ref ,
101102 ) => {
102103 const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200 ;
103- const [ apiKeys , setApiKeys ] = useState < Record < string , string > > ( ( ) => {
104- const savedKeys = Cookies . get ( 'apiKeys' ) ;
105-
106- if ( savedKeys ) {
107- try {
108- return JSON . parse ( savedKeys ) ;
109- } catch ( error ) {
110- console . error ( 'Failed to parse API keys from cookies:' , error ) ;
111- return { } ;
112- }
113- }
114-
115- return { } ;
116- } ) ;
104+ const [ apiKeys , setApiKeys ] = useState < Record < string , string > > ( getApiKeysFromCookies ( ) ) ;
117105 const [ modelList , setModelList ] = useState ( MODEL_LIST ) ;
118106 const [ isModelSettingsCollapsed , setIsModelSettingsCollapsed ] = useState ( false ) ;
119107 const [ isListening , setIsListening ] = useState ( false ) ;
120108 const [ recognition , setRecognition ] = useState < SpeechRecognition | null > ( null ) ;
121109 const [ transcript , setTranscript ] = useState ( '' ) ;
110+ const [ isModelLoading , setIsModelLoading ] = useState < string | undefined > ( 'all' ) ;
111+
112+ const getProviderSettings = useCallback ( ( ) => {
113+ let providerSettings : Record < string , IProviderSetting > | undefined = undefined ;
114+
115+ try {
116+ const savedProviderSettings = Cookies . get ( 'providers' ) ;
117+
118+ if ( savedProviderSettings ) {
119+ const parsedProviderSettings = JSON . parse ( savedProviderSettings ) ;
120+
121+ if ( typeof parsedProviderSettings === 'object' && parsedProviderSettings !== null ) {
122+ providerSettings = parsedProviderSettings ;
123+ }
124+ }
125+ } catch ( error ) {
126+ console . error ( 'Error loading Provider Settings from cookies:' , error ) ;
127+
128+ // Clear invalid cookie data
129+ Cookies . remove ( 'providers' ) ;
130+ }
122131
132+ return providerSettings ;
133+ } , [ ] ) ;
123134 useEffect ( ( ) => {
124135 console . log ( transcript ) ;
125136 } , [ transcript ] ) ;
@@ -157,25 +168,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
157168 } , [ ] ) ;
158169
159170 useEffect ( ( ) => {
160- let providerSettings : Record < string , IProviderSetting > | undefined = undefined ;
161-
162- try {
163- const savedProviderSettings = Cookies . get ( 'providers' ) ;
164-
165- if ( savedProviderSettings ) {
166- const parsedProviderSettings = JSON . parse ( savedProviderSettings ) ;
167-
168- if ( typeof parsedProviderSettings === 'object' && parsedProviderSettings !== null ) {
169- providerSettings = parsedProviderSettings ;
170- }
171- }
172- } catch ( error ) {
173- console . error ( 'Error loading Provider Settings from cookies:' , error ) ;
174-
175- // Clear invalid cookie data
176- Cookies . remove ( 'providers' ) ;
177- }
178-
171+ const providerSettings = getProviderSettings ( ) ;
179172 let parsedApiKeys : Record < string , string > | undefined = { } ;
180173
181174 try {
@@ -187,12 +180,49 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
187180 // Clear invalid cookie data
188181 Cookies . remove ( 'apiKeys' ) ;
189182 }
183+ setIsModelLoading ( 'all' ) ;
184+ initializeModelList ( { apiKeys : parsedApiKeys , providerSettings } )
185+ . then ( ( modelList ) => {
186+ console . log ( 'Model List: ' , modelList ) ;
187+ setModelList ( modelList ) ;
188+ } )
189+ . catch ( ( error ) => {
190+ console . error ( 'Error initializing model list:' , error ) ;
191+ } )
192+ . finally ( ( ) => {
193+ setIsModelLoading ( undefined ) ;
194+ } ) ;
195+ } , [ providerList ] ) ;
196+
197+ const onApiKeysChange = async ( providerName : string , apiKey : string ) => {
198+ const newApiKeys = { ...apiKeys , [ providerName ] : apiKey } ;
199+ setApiKeys ( newApiKeys ) ;
200+ Cookies . set ( 'apiKeys' , JSON . stringify ( newApiKeys ) ) ;
201+
202+ const provider = LLMManager . getInstance ( import . meta. env || process . env || { } ) . getProvider ( providerName ) ;
203+
204+ if ( provider && provider . getDynamicModels ) {
205+ setIsModelLoading ( providerName ) ;
190206
191- initializeModelList ( { apiKeys : parsedApiKeys , providerSettings } ) . then ( ( modelList ) => {
192- console . log ( 'Model List: ' , modelList ) ;
193- setModelList ( modelList ) ;
194- } ) ;
195- } , [ apiKeys ] ) ;
207+ try {
208+ const providerSettings = getProviderSettings ( ) ;
209+ const staticModels = provider . staticModels ;
210+ const dynamicModels = await provider . getDynamicModels (
211+ newApiKeys ,
212+ providerSettings ,
213+ import . meta. env || process . env || { } ,
214+ ) ;
215+
216+ setModelList ( ( preModels ) => {
217+ const filteredOutPreModels = preModels . filter ( ( x ) => x . provider !== providerName ) ;
218+ return [ ...filteredOutPreModels , ...staticModels , ...dynamicModels ] ;
219+ } ) ;
220+ } catch ( error ) {
221+ console . error ( 'Error loading dynamic models:' , error ) ;
222+ }
223+ setIsModelLoading ( undefined ) ;
224+ }
225+ } ;
196226
197227 const startListening = ( ) => {
198228 if ( recognition ) {
@@ -381,15 +411,14 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
381411 setProvider = { setProvider }
382412 providerList = { providerList || ( PROVIDER_LIST as ProviderInfo [ ] ) }
383413 apiKeys = { apiKeys }
414+ modelLoading = { isModelLoading }
384415 />
385416 { ( providerList || [ ] ) . length > 0 && provider && (
386417 < APIKeyManager
387418 provider = { provider }
388419 apiKey = { apiKeys [ provider . name ] || '' }
389420 setApiKey = { ( key ) => {
390- const newApiKeys = { ...apiKeys , [ provider . name ] : key } ;
391- setApiKeys ( newApiKeys ) ;
392- Cookies . set ( 'apiKeys' , JSON . stringify ( newApiKeys ) ) ;
421+ onApiKeysChange ( provider . name , key ) ;
393422 } }
394423 />
395424 ) }
0 commit comments