diff --git a/app/components/Models.tsx b/app/components/Models.tsx index 24ba852..79f9124 100644 --- a/app/components/Models.tsx +++ b/app/components/Models.tsx @@ -1,328 +1,255 @@ -"use client"; -import React, { useState, useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; -// Define all models that should be available. +// Sample modelList definition; replace this with your actual modelList const modelList = { 'Offline Fast': { - 'model_type': 'local', - 'Math': 'qwen2-math:1.5b', - 'Code': 'starcoder2', - 'Language': 'llama3.2', - 'Character': 'dolphin-phi', - 'Finance': 'qwen2-math:1.5b', - 'Weather': 'llama3.2', - 'Time': 'llama3.2', - 'Image': 'llava-phi3' + model_type: 'local', + Math: 'qwen2-math:1.5b', + Code: 'starcoder2', + Language: 'llama3.2', + Character: 'dolphin-phi', + Finance: 'qwen2-math:1.5b', + Weather: 'llama3.2', + Time: 'llama3.2', + Image: 'llava-phi3' }, 'Offline Slow': { - 'model_type': 'local', - 'Math': 'wizard-math', - 'Code': 'starcoder2:7b', - 'Language': 'llama3.1', - 'Character': 'dolphin-llama3', - 'Finance': 'wizard-math', - 'Weather': 'llama3.1', - 'Time': 'llama3.1', - 'Image': 'llava' + model_type: 'local', + Math: 'wizard-math', + Code: 'starcoder2:7b', + Language: 'llama3.1', + Character: 'dolphin-llama3', + Finance: 'wizard-math', + Weather: 'llama3.1', + Time: 'llama3.1', + Image: 'llava' }, 'Offline Fast (FOSS)': { - 'model_type': 'local', - 'Math': 'qwen2-math:1.5b', - 'Code': 'qwen2.5-coder:1.5b', - 'Language': 'phi3.5', - 'Character': 'dolphin-mistral', - 'Finance': 'qwen2-math:1.5b', - 'Weather': 'phi3.5', - 'Time': 'phi3.5', - 'Image': 'llava' + model_type: 'local', + Math: 'qwen2-math:1.5b', + Code: 'qwen2.5-coder:1.5b', + Language: 'phi3.5', + Character: 'dolphin-mistral', + Finance: 'qwen2-math:1.5b', + Weather: 'phi3.5', + Time: 'phi3.5', + Image: 'llava' }, 'Offline Slow (FOSS)': { - 'model_type': 'local', - 'Math': 'mathstral', - 'Code': 'qwen2.5-coder', - 'Language': 'qwen2.5', - 'Character': 'dolphin-mistral', - 'Finance': 'mathstral', - 'Weather': 'qwen2.5', - 'Time': 'qwen2.5', - 'Image': 'llava' + model_type: 'local', + Math: 'mathstral', + Code: 'qwen2.5-coder', + Language: 'qwen2.5', + Character: 'dolphin-mistral', + Finance: 'mathstral', + Weather: 'qwen2.5', + Time: 'qwen2.5', + Image: 'llava' }, 'Online Cheap (OpenAI)': { - 'model_type': 'openai', - 'Math': 'gpt-4o-mini', - 'Code': 'gpt-4o-mini', - 'Language': 'gpt-4o-mini', - 'Character': 'gpt-4o-mini', - 'Finance': 'gpt-4o-mini', - 'Weather': 'gpt-4o-mini', - 'Time': 'gpt-4o-mini', - 'Image': 'gpt-4o-mini' + model_type: 'openai', + Math: 'gpt-4o-mini', + Code: 'gpt-4o-mini', + Language: 'gpt-4o-mini', + Character: 'gpt-4o-mini', + Finance: 'gpt-4o-mini', + Weather: 'gpt-4o-mini', + Time: 'gpt-4o-mini', + Image: 'gpt-4o-mini' }, 'Online Expensive (OpenAI)': { - 'model_type': 'openai', - 'Math': 'gpt-4o', - 'Code': 'gpt-4o', - 'Language': 'gpt-4o', - 'Character': 'gpt-4o', - 'Finance': 'gpt-4o', - 'Weather': 'gpt-4o', - 'Time': 'gpt-4o', - 'Image': 'gpt-4o' + model_type: 'openai', + Math: 'gpt-4o', + Code: 'gpt-4o', + Language: 'gpt-4o', + Character: 'gpt-4o', + Finance: 'gpt-4o', + Weather: 'gpt-4o', + Time: 'gpt-4o', + Image: 'gpt-4o' }, 'Online Cheap (Anthropic)': { - 'model_type': 'anthropic', - 'Math': 'claude-3-haiku', - 'Code': 'claude-3-haiku', - 'Language': 'claude-3-haiku', - 'Character': 'claude-3-haiku', - 'Finance': 'claude-3-haiku', - 'Weather': 'claude-3-haiku', - 'Time': 'claude-3-haiku', - 'Image': 'claude-3-haiku' + model_type: 'anthropic', + Math: 'claude-3-haiku', + Code: 'claude-3-haiku', + Language: 'claude-3-haiku', + Character: 'claude-3-haiku', + Finance: 'claude-3-haiku', + Weather: 'claude-3-haiku', + Time: 'claude-3-haiku', + Image: 'claude-3-haiku' }, 'Online Expensive (Anthropic)': { - 'model_type': 'anthropic', - 'Math': 'claude-3-5-sonnet', - 'Code': 'claude-3-5-sonnet', - 'Language': 'claude-3-5-sonnet', - 'Character': 'claude-3-5-sonnet', - 'Finance': 'claude-3-5-sonnet', - 'Weather': 'claude-3-5-sonnet', - 'Time': 'claude-3-5-sonnet', - 'Image': 'claude-3-5-sonnet' + model_type: 'anthropic', + Math: 'claude-3-5-sonnet', + Code: 'claude-3-5-sonnet', + Language: 'claude-3-5-sonnet', + Character: 'claude-3-5-sonnet', + Finance: 'claude-3-5-sonnet', + Weather: 'claude-3-5-sonnet', + Time: 'claude-3-5-sonnet', + Image: 'claude-3-5-sonnet' }, 'Online Cheap (Google)': { - 'model_type': 'google', - 'Math': 'gemini-1.5-flash-latest', - 'Code': 'gemini-1.5-flash-latest', - 'Language': 'gemini-1.5-flash-latest', - 'Character': 'gemini-1.5-flash-latest', - 'Finance': 'gemini-1.5-flash-latest', - 'Weather': 'gemini-1.5-flash-latest', - 'Time': 'gemini-1.5-flash-latest', - 'Image': 'gemini-1.5-flash-latest' + model_type: 'google', + Math: 'gemini-1.5-flash-latest', + Code: 'gemini-1.5-flash-latest', + Language: 'gemini-1.5-flash-latest', + Character: 'gemini-1.5-flash-latest', + Finance: 'gemini-1.5-flash-latest', + Weather: 'gemini-1.5-flash-latest', + Time: 'gemini-1.5-flash-latest', + Image: 'gemini-1.5-flash-latest' }, 'Online Expensive (Google)': { - 'model_type': 'google', - 'Math': 'gemini-1.5-pro-latest', - 'Code': 'gemini-1.5-pro-latest', - 'Language': 'gemini-1.5-pro-latest', - 'Character': 'gemini-1.5-pro-latest', - 'Finance': 'gemini-1.5-pro-latest', - 'Weather': 'gemini-1.5-pro-latest', - 'Time': 'gemini-1.5-pro-latest', - 'Image': 'gemini-1.5-pro-latest' + model_type: 'google', + Math: 'gemini-1.5-pro-latest', + Code: 'gemini-1.5-pro-latest', + Language: 'gemini-1.5-pro-latest', + Character: 'gemini-1.5-pro-latest', + Finance: 'gemini-1.5-pro-latest', + Weather: 'gemini-1.5-pro-latest', + Time: 'gemini-1.5-pro-latest', + Image: 'gemini-1.5-pro-latest' }, 'Online (La Plateforme)': { - 'model_type': 'mistral', - 'Math': 'open-mistral-nemo', - 'Code': 'codestral-latest', - 'Language': 'mistral-small-latest', - 'Character': 'mistral-large-latest', - 'Finance': 'open-mistral-nemo', - 'Weather': 'mistral-small-latest', - 'Time': 'mistral-small-latest', - 'Image': 'pixtral-12b-2409' + model_type: 'mistral', + Math: 'open-mistral-nemo', + Code: 'codestral-latest', + Language: 'mistral-small-latest', + Character: 'mistral-large-latest', + Finance: 'open-mistral-nemo', + Weather: 'mistral-small-latest', + Time: 'mistral-small-latest', + Image: 'pixtral-12b-2409' }, 'Online (FOSS) (La Plateforme)': { - 'model_type': 'mistral', - 'Math': 'open-mistral-nemo', - 'Code': 'open-codestral-mamba', - 'Language': 'open-mistral-nemo', - 'Character': 'open-mixtral-8x22b', - 'Finance': 'open-mixtral-8x22b', - 'Weather': 'open-mistral-nemo', - 'Time': 'open-mistral-nemo', - 'Image': 'pixtral-12b-2409' + model_type: 'mistral', + Math: 'open-mistral-nemo', + Code: 'open-codestral-mamba', + Language: 'open-mistral-nemo', + Character: 'open-mixtral-8x22b', + Finance: 'open-mixtral-8x22b', + Weather: 'open-mistral-nemo', + Time: 'open-mistral-nemo', + Image: 'pixtral-12b-2409' } } + // Define the keys of modelList + type ModelKeys = keyof typeof modelList; -// 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)'], -}; + const ModelSection: React.FC = () => { + // Initialize state with value from localStorage or default to '' + const [selectedModelDropdown, setSelectedModelDropdown] = useState('Offline Fast'); + const [radioSelection, setRadioSelection] = useState(""); + const [activeSelectedAIFunction, setActiveSelectedAIFunction] = useState(''); + const [currentSelectedAIFunction, setCurrentSelectedAIFunction] = useState(""); -const selectedAIFunction = [ - 'Code', - 'Math', - 'Language', - 'Character', - 'Finance', - 'Weather', - 'Time', - 'Image', - 'Custom1', - 'Custom2' -] + useEffect(() => { + // Load initial values from localStorage + const temp = localStorage.getItem("activeSelectedAIFunction") || ""; + setActiveSelectedAIFunction(temp); -const ModelSection: React.FC = () => { - // 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(""); - - useEffect(() => { - var temp = localStorage.getItem("activeSelectedAIFunction") || "" - setActiveSelectedAIFunction(temp) - if (!localStorage.getItem('selectedModelDropdown')) { - localStorage.setItem("selectedModelDropdown", "Offline Fast" ) - } + // Check if localStorage keys exist, else set defaults + if (!localStorage.getItem('selectedModelDropdown')) { + localStorage.setItem("selectedModelDropdown", "Offline Fast"); + } - if (!localStorage.getItem("activeSelectedAIFunction")) { - setActiveSelectedAIFunction('Code') - localStorage.setItem('activeSelectedAIFunction' ,'Code') - } + // Set the dropdown and selected AI function from localStorage + const storedSelectedModel = localStorage.getItem('selectedModelDropdown') as ModelKeys; + const storedActiveFunction = localStorage.getItem("activeSelectedAIFunction") || 'Code'; - if (!localStorage.getItem("model")) { - localStorage.setItem("model" ,'starcoder2') - } + setSelectedModelDropdown(storedSelectedModel); + setCurrentSelectedAIFunction(storedActiveFunction); - if (!localStorage.getItem("radioSelection")) { - localStorage.setItem("radioSelection" ,'None') - } + if (!localStorage.getItem("model")) { + localStorage.setItem("model", 'starcoder2'); + } - const handleStorageChange = () => { - setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); + if (!localStorage.getItem("radioSelection")) { + localStorage.setItem("radioSelection", 'None'); + } + + // Load radio selection from localStorage + setRadioSelection(localStorage.getItem('radioSelection') || ''); + }, []); + + const filteredModels = Object.keys(modelList).filter(model => modelList[model as ModelKeys]); + + const handleModelChange = (event: React.ChangeEvent) => { + const selectedModel = event.target.value as ModelKeys; + setSelectedModelDropdown(selectedModel); + localStorage.setItem('selectedModelDropdown', selectedModel); + + // Update model and type in local storage + const modelType = modelList[selectedModel].model_type; + const model = modelList[selectedModel][activeSelectedAIFunction as keyof typeof modelList[typeof selectedModel]]; + + localStorage.setItem('model', model); + localStorage.setItem('type', modelType); }; - // Update immediately when localStorage changes - window.addEventListener('storage', handleStorageChange); - - setRadioSelection(localStorage.getItem('radioSelection') || ''); - setSelectedModelDropdown(localStorage.getItem('selectedModelDropdown') || ''); - // Cleanup listener on component unmount - return () => { - window.removeEventListener('storage', handleStorageChange); + const isOfflineModel = (model: string) => { + return modelList[model as ModelKeys].model_type === 'local'; }; - }, []); // Dependency array can remain empty if you only want this to run on mount - useEffect(() => { - var storedActiveSelectedAIFunction = localStorage.getItem("activeSelectedAIFunction") || ""; - if (storedActiveSelectedAIFunction !== currentSelectedAIFunction) { - setCurrentSelectedAIFunction(storedActiveSelectedAIFunction); - } - }, [activeSelectedAIFunction]); + const modelClicked = (model: string) => { + const selectedAIFunction = currentSelectedAIFunction as keyof typeof modelList; - const handleModelChange = (event: React.ChangeEvent) => { - const newModel = event.target.value; - setSelectedModelDropdown(newModel); - localStorage.setItem('selectedModelDropdown', newModel); // Update localStorage directly - }; + if (modelList[selectedModelDropdown] && modelList[selectedModelDropdown][model as keyof typeof modelList[typeof selectedModelDropdown]]) { + const newModel = modelList[selectedModelDropdown][model as keyof typeof modelList[typeof selectedModelDropdown]]; + const modelType = modelList[selectedModelDropdown]['model_type' as keyof typeof modelList[typeof selectedModelDropdown]]; - // Determine the filtered models based on current radioSelection - const filteredModels = (() => { - let models = []; - switch (radioSelection) { - case 'Offline': - models = [ - ...modelDropdown.onlineNonFoss, - ...modelDropdown.onlineFoss, - ]; // Show only offline models without FOSS - break; - case 'Offline (FOSS)': - models = [ - ...modelDropdown.onlineFoss, - ]; // Show only offline models with FOSS - break; - case 'Online': - models = [ - ...modelDropdown.offlineNonFoss, - ...modelDropdown.offlineFoss, - ]; // Show only online models without FOSS - break; - case 'Online (FOSS)': - models = [ - ...modelDropdown.offlineFoss, - ]; // Show only online models with FOSS - break; - case 'None': - models = [ - ...modelDropdown.offlineNonFoss, - ...modelDropdown.offlineFoss, - ...modelDropdown.onlineNonFoss, - ...modelDropdown.onlineFoss, - ]; // Show all models if nothing matches - break; - case 'None (FOSS)': - 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 - })(); + localStorage.setItem('activeSelectedAIFunction', model); + setActiveSelectedAIFunction(model); + localStorage.setItem('model', newModel); + localStorage.setItem('type', modelType); + setCurrentSelectedAIFunction(model); // Ensure to set current function when model is clicked + } else { + console.error(`Model ${model} not found for function ${selectedModelDropdown}`); + } + }; - const isOfflineModel = (model: string) => - modelDropdown.offlineNonFoss.includes(model) || modelDropdown.offlineFoss.includes(model); + return ( +
+
+
+

Different AI Models

+
- const modelClicked = (model: string) => { - localStorage.setItem('activeSelectedAIFunction' , model) - setActiveSelectedAIFunction(model) - const selectedAIFunction = selectedModelDropdown 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]]) - } + {/* Model Selection Dropdown */} +
+ + +
- return ( -
-
-
-

Different AI Models

-
- - {/* Model Selection Dropdown */} -
- - -
- - {/* Model Grid with Cards */} -
- {selectedAIFunction.map( - (displayedCategory) => ( - - ) - )} + {/* Model Grid with Cards */} +
+ {Object.keys(modelList[selectedModelDropdown]) + .filter((key) => key !== 'model_type') // Exclude model_type from display + .map((displayedCategory) => ( + + )) + } +
-
- ); -}; + ); + }; export default ModelSection; diff --git a/app/styles/models.css b/app/styles/models.css index 258f71a..7b833ae 100644 --- a/app/styles/models.css +++ b/app/styles/models.css @@ -61,8 +61,8 @@ } .model-box.selected { - box-shadow: 0 0 15px 5px rgba(255, 255, 0, 0.7); /* Glowing border */ - border-color: yellow; + box-shadow: 0 0 25px 5px var(--apply-button-hover-color); /* Glowing border */ + border-color: var(--apply-button-hover-color); } .overlay {