diff --git a/app/components/Models.tsx b/app/components/Models.tsx index ce8dfbe..469d9cb 100644 --- a/app/components/Models.tsx +++ b/app/components/Models.tsx @@ -1,21 +1,8 @@ "use client"; import React, { useState, useEffect } from 'react'; -// Define the types for ModelType and ModelListType -type ModelType = { - model_type: string; - Math: string; - Code: string; - Language: string; - Weather: string; -}; - -type ModelListType = { - [key: string]: ModelType; -}; - -// Define the AI models list -const modelList: ModelListType = { +// Define all models that should be available. +const modelList = { 'Offline Fast': { model_type: 'local', Math: 'qwen2-math:1.5b', @@ -99,47 +86,161 @@ const modelList: ModelListType = { Code: 'open-codestral-mamba', Language: 'open-mistral-nemo', Weather: 'open-mistral-nemo', - }, + } +} + + +// Define the available selectedAIFunction options +const modelDropdown = { + offlineNonFoss: ['Offline Fast', 'Offline Slow'], + offlineFoss: ['Offline Fast (FOSS)', 'Offline Slow (FOSS)'], + onlineNonFoss: [ + 'Online Cheap (OpenAI)', + 'Online Expensive (OpenAI)', + 'Online Cheap (Anthropic)', + 'Online Expensive (Anthropic)', + 'Online Cheap (Google)', + 'Online Expensive (Google)', + 'Online (La Plateforme)' + ], + onlineFoss: ['Online (FOSS) (La Plateforme)'], }; -// AI Functions list -const aiFunctions = ['Math', 'Code', 'Language', 'Weather'] as const; -type AIFunction = typeof aiFunctions[number]; // Restrict to these exact function names +const selectedAIFunction = [ + 'Code', + 'Math', + 'Language', + 'Weather' +] const ModelSection: React.FC = () => { - const [selectedModelDropdown, setSelectedModelDropdown] = useState(() => "Offline Fast"); - const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(() => "Code"); - const [, setSelectedModel] = useState(""); - const [, setSelectedModelType] = useState(""); + // Initialize state with value from localStorage or default to '' + const [selectedModelDropdown, setSelectedModelDropdown] = useState(''); + const [radioSelection, setRadioSelection] = useState("") + const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(''); + const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState(""); + const [isOpenSourceMode, setIsOpenSourceMode] = useState("false") useEffect(() => { - setSelectedModelDropdown(localStorage.getItem("selectedModelDropdown")|| "Offline Fast"); - setActiveSelectedAIFunction(localStorage.getItem("activeSelectedAIFunction") || "Code"); + if (typeof localStorage !== 'undefined') { + const defaultValues = { + selectedModelDropdown: 'Offline Fast', + activeSelectedAIFunction: 'Code', + model: 'starcoder2', + radioSelection: 'None', + type: 'local', + }; + + Object.entries(defaultValues).forEach(([key, value]) => { + if (!localStorage.getItem(key)) { + localStorage.setItem(key, value); + } + }); + + setIsOpenSourceMode(localStorage.getItem("openSourceMode")); + setActiveSelectedAIFunction(localStorage.getItem("activeSelectedAIFunction") || ''); + setRadioSelection(localStorage.getItem("radioSelection") || ''); + setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); + + const handleStorageChange = () => { + setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); + }; + + // Update immediately when localStorage changes + window.addEventListener('storage', handleStorageChange); + + // Cleanup listener on component unmount + return () => { + window.removeEventListener('storage', handleStorageChange); + }; + } }, []); + - // Update the model and type when the dropdown or function changes useEffect(() => { - const aiFunctionsActiveSelectedAIFunction = activeSelectedAIFunction as AIFunction - const newSelectedModel = modelList[selectedModelDropdown]?.[aiFunctionsActiveSelectedAIFunction] || ""; - const newModelType = modelList[selectedModelDropdown]?.model_type || ""; - - setSelectedModel(newSelectedModel); - setSelectedModelType(newModelType); - - localStorage.setItem("model", newSelectedModel); - localStorage.setItem("type", newModelType); - }, [selectedModelDropdown, activeSelectedAIFunction]); + if (typeof localStorage !== 'undefined') { + const storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || ""; + if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) { + setCurrentSelectedAIFunction(storedActiveSelectedAIFunction); + } + } + }, [activeSelectedAIFunction]); const handleModelChange = (event: React.ChangeEvent) => { const newModel = event.target.value; setSelectedModelDropdown(newModel); - localStorage.setItem('selectedModelDropdown', newModel); + if (typeof localStorage !== 'undefined') { + localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly + const model = localStorage.getItem('activeSelectedAIFunction') || "Code" + modelClicked(model) + } }; - const modelClicked = (functionName: AIFunction) => { - setActiveSelectedAIFunction(functionName); - localStorage.setItem('activeSelectedAIFunction', functionName); - }; + // Determine the filtered models based on current radioSelection + const filteredModels = (() => { + let models = []; + switch (radioSelection) { + case 'Offline': + models = [ + ...modelDropdown.onlineNonFoss, + ...modelDropdown.onlineFoss, + ]; + if (isOpenSourceMode == "true") { + models = [ + ...modelDropdown.onlineFoss, + ]; + } // Show only offline models without FOSS + break; + case 'Online': + models = [ + ...modelDropdown.offlineNonFoss, + ...modelDropdown.offlineFoss, + ]; + if (isOpenSourceMode == "true") { + models = [ + ...modelDropdown.offlineFoss, + ]; + } // Show only online models without FOSS + break; + case 'None': + models = [ + ...modelDropdown.offlineNonFoss, + ...modelDropdown.offlineFoss, + ...modelDropdown.onlineNonFoss, + ...modelDropdown.onlineFoss, + ]; + if (isOpenSourceMode == "true") { + models = [ + ...modelDropdown.offlineFoss, + ...modelDropdown.onlineFoss, + ]; + } // Show all models if nothing matches + break; + default: + models = [ + ...modelDropdown.offlineNonFoss, + ...modelDropdown.offlineFoss, + ...modelDropdown.onlineNonFoss, + ...modelDropdown.onlineFoss, + ]; // Show all models if nothing matches + break; + } + return Array.from(new Set(models)); // Remove duplicates using Set + })(); + + const isOfflineModel = (model: string) => + modelDropdown.offlineNonFoss.includes(model) || modelDropdown.offlineFoss.includes(model); + + const modelClicked = (model: string) => { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('activeSelectedAIFunction', model) + setActiveSelectedAIFunction(model) + const modelDropdown = localStorage.getItem('selectedModelDropdown') || 'Offline Fast' + const selectedAIFunction = modelDropdown as keyof typeof modelList; + localStorage.setItem("model", modelList[selectedAIFunction][model as keyof typeof modelList[typeof selectedAIFunction]]) + localStorage.setItem("type", modelList[selectedAIFunction]['model_type' as keyof typeof modelList[typeof selectedAIFunction]]) + } + } return (
@@ -148,29 +249,33 @@ const ModelSection: React.FC = () => {

Different AI Models

+ {/* Model Selection Dropdown */}
- + {/* Model Grid with Cards */}
- {aiFunctions.map((functionName) => ( - - ))} + {selectedAIFunction.map( + (displayedCategory) => ( + + ) + )}
diff --git a/app/styles/models.css b/app/styles/models.css index 1ccd862..e657d6c 100644 --- a/app/styles/models.css +++ b/app/styles/models.css @@ -49,8 +49,8 @@ border-radius: 5%; overflow: hidden; position: relative; - height: 8vw; - width: 8vw; + height: 18vh; + width: 18vh; margin: auto; /* Center each model box in the grid cell */ } .model-box.selected { diff --git a/app/styles/responsive.css b/app/styles/responsive.css index 4a9c70f..dd0d3b0 100644 --- a/app/styles/responsive.css +++ b/app/styles/responsive.css @@ -57,8 +57,8 @@ } /* Model box styles */ .model-box { - width: 50vw; - height: 50vw; + max-width: none; /* Remove max-width */ + margin: 0 auto; /* Center each model-box */ } /* Input styles */ .input {