forked from React-Group/interstellar_ai
		
	Merge branch 'main' into main
This commit is contained in:
		
						commit
						d657525f79
					
				
					 9 changed files with 383 additions and 78 deletions
				
			
		
							
								
								
									
										20
									
								
								app/backend/ProcessMemory.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/backend/ProcessMemory.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | import { Settings } from 'electron' | ||||||
|  | import React from 'react' | ||||||
|  | 
 | ||||||
|  | type Message = { | ||||||
|  |     role: string | ||||||
|  |     content: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Chat = { | ||||||
|  |     name: string | ||||||
|  |     messages: Message[] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Data = { | ||||||
|  |     chats: Chat[] | ||||||
|  |     settings: Settings[] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -1,13 +0,0 @@ | ||||||
| import React from 'react' |  | ||||||
| 
 |  | ||||||
| type Chat = { |  | ||||||
|     name:string |  | ||||||
|     messages:string[] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type History = { |  | ||||||
|     chats:Chat[] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  | @ -1,16 +1,96 @@ | ||||||
| import axios from "axios"; | import axios from "axios"; | ||||||
| 
 | 
 | ||||||
| const sendToDatabase = (data: any) => { | /* | ||||||
|     axios.post("http://localhost:5000/interstellar_ai/db", data) | This is the guide on how to user this function: | ||||||
|         .then(response => { |  | ||||||
|             const status = response.data.status |  | ||||||
|             console.log(status); |  | ||||||
|             postMessage({ status }) |  | ||||||
|             console.log('message posted'); |  | ||||||
| 
 | 
 | ||||||
|  | data should be the json containing everything relevant, the json can contain the following keys: | ||||||
|  | 
 | ||||||
|  | action -> contains the action you want to do, there are: create_account, change_password, get_data, change_data, check_credentials, delete_account | ||||||
|  | username -> contains the current username, required for create_account, but can be omitted in favor of email in other requests. Preffered over email authentication. | ||||||
|  | email -> contains the current email, required for create_account, but just like the username, it can be omitted, in favor of the other, sending both is possible too. | ||||||
|  | password -> contains the password, required for all requests. | ||||||
|  | new_password -> in the case you are changing your password, you will need to use this in addition to password, to specify the new password. | ||||||
|  | data -> data contains all the data you want to store, you have to always give the entire data, because the data you give here overwrites the data in the database,  | ||||||
|  | so if you only give the chat history for example, all settings will be deleted, and if you only give settings, all chat histories will get deleted. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if all went well, you will get the status 200 in response.data.status | ||||||
|  | to check if the request was accepted or declined, check response.data.response, it will be either true or false depending on if it worked, or not. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | export const sendToDatabase = (data: any): Promise<boolean> => { | ||||||
|  |   return axios.post("http://localhost:5000/interstellar_ai/db", data) | ||||||
|  |     .then(response => { | ||||||
|  |       const status = response.data.status; | ||||||
|  |       const success = response.data.response; | ||||||
|  |       postMessage({ status, success }); | ||||||
|  |       return success;  // Ensure success is returned to the caller
 | ||||||
|     }) |     }) | ||||||
|     .catch(error => { |     .catch(error => { | ||||||
|             console.log("Error calling Database:", error) |       postMessage({ status: 500, success: false }); | ||||||
|             postMessage({ status: 500 }) |       return false;  // Return false in case of an error
 | ||||||
|         }) |     }); | ||||||
| } | }; | ||||||
|  | 
 | ||||||
|  | // Functions for each action
 | ||||||
|  | export const createAccount = async (username: string, email: string, password: string) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "create_account", | ||||||
|  |     username, | ||||||
|  |     email, | ||||||
|  |     password, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const changePassword = async (usernameOrEmail: string, password: string, newPassword: string) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "change_password", | ||||||
|  |     username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail, | ||||||
|  |     email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined, | ||||||
|  |     password, | ||||||
|  |     new_password: newPassword, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const getData = async (usernameOrEmail: string, password: string) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "get_data", | ||||||
|  |     username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail, | ||||||
|  |     email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined, | ||||||
|  |     password, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const changeData = async (usernameOrEmail: string, password: string, newData: any) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "change_data", | ||||||
|  |     username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail, | ||||||
|  |     email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined, | ||||||
|  |     password, | ||||||
|  |     data: newData, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const checkCredentials = async (usernameOrEmail: string, password: string) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "check_credentials", | ||||||
|  |     username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail, | ||||||
|  |     email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined, | ||||||
|  |     password, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const deleteAccount = async (usernameOrEmail: string, password: string) => { | ||||||
|  |   const data = { | ||||||
|  |     action: "delete_account", | ||||||
|  |     username: usernameOrEmail.includes('@') ? undefined : usernameOrEmail, | ||||||
|  |     email: usernameOrEmail.includes('@') ? usernameOrEmail : undefined, | ||||||
|  |     password, | ||||||
|  |   }; | ||||||
|  |   return await sendToDatabase(data); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | @ -1,8 +1,11 @@ | ||||||
| import React, { useState, useEffect } from 'react'; | import React, { useState, useEffect } from 'react'; | ||||||
|  | import { | ||||||
|  |   createAccount, | ||||||
|  |   checkCredentials, | ||||||
|  | } from '../backend/database'; | ||||||
| import Settings from './Settings'; // Import the Settings component
 | import Settings from './Settings'; // Import the Settings component
 | ||||||
| 
 | 
 | ||||||
| const Login: React.FC = () => { | const Login: React.FC = () => { | ||||||
|    |  | ||||||
|   // State to handle popup visibility
 |   // State to handle popup visibility
 | ||||||
|   const [showLoginPopup, setShowLoginPopup] = useState(false); |   const [showLoginPopup, setShowLoginPopup] = useState(false); | ||||||
|   const [showSignUpPopup, setShowSignUpPopup] = useState(false); |   const [showSignUpPopup, setShowSignUpPopup] = useState(false); | ||||||
|  | @ -28,7 +31,11 @@ const Login: React.FC = () => { | ||||||
|       setAccountName(savedAccountName); |       setAccountName(savedAccountName); | ||||||
|       setEmail(savedAccountEmail); |       setEmail(savedAccountEmail); | ||||||
|       setPassword(savedAccountPassword); |       setPassword(savedAccountPassword); | ||||||
|       setIsLoggedIn(true); // Automatically log in
 |       const check = async () => { | ||||||
|  |         const success = await checkCredentials(savedAccountName, savedAccountPassword); | ||||||
|  |         setIsLoggedIn(success); // Automatically log in
 | ||||||
|  |       }; | ||||||
|  |       check(); | ||||||
|     } |     } | ||||||
|   }, []); |   }, []); | ||||||
| 
 | 
 | ||||||
|  | @ -42,15 +49,17 @@ const Login: React.FC = () => { | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Function to handle login
 |   // Function to handle login
 | ||||||
|   const handleLogin = () => { |   const handleLogin = async () => { | ||||||
|     const savedAccountEmail = localStorage.getItem('accountEmail'); |     const savedAccountEmail = localStorage.getItem('accountEmail'); | ||||||
|     const savedAccountPassword = localStorage.getItem('accountPassword'); |     const savedAccountPassword = localStorage.getItem('accountPassword'); | ||||||
|     const savedAccountName = localStorage.getItem('accountName'); |     const savedAccountName = localStorage.getItem('accountName'); | ||||||
| 
 | 
 | ||||||
|     if ( |     // Check if savedAccountName or savedAccountEmail is not null before passing to checkCredentials
 | ||||||
|       (email === savedAccountEmail || accountName === savedAccountName) && |     const accountIdentifier = savedAccountName || savedAccountEmail; | ||||||
|       password === savedAccountPassword | 
 | ||||||
|     ) { |     if (accountIdentifier && password === savedAccountPassword) { | ||||||
|  |       const success = await checkCredentials(accountIdentifier, password); | ||||||
|  |       if (success) { | ||||||
|         setIsLoggedIn(true); // Successful login
 |         setIsLoggedIn(true); // Successful login
 | ||||||
|         setShowLoginPopup(false); // Close the login popup
 |         setShowLoginPopup(false); // Close the login popup
 | ||||||
|         // Save credentials to localStorage (optional in case of changes)
 |         // Save credentials to localStorage (optional in case of changes)
 | ||||||
|  | @ -60,15 +69,20 @@ const Login: React.FC = () => { | ||||||
|       } else { |       } else { | ||||||
|         alert('Incorrect credentials'); |         alert('Incorrect credentials'); | ||||||
|       } |       } | ||||||
|  |     } else { | ||||||
|  |       alert('Incorrect credentials'); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Function to handle account creation
 |   // Function to handle account creation
 | ||||||
|   const handleCreateAccount = () => { |   const handleCreateAccount = async () => { | ||||||
|     localStorage.setItem('accountName', newAccountName); |     const success = await createAccount(newAccountName, newAccountEmail, newAccountPassword); | ||||||
|     localStorage.setItem('accountEmail', newAccountEmail); |     if (success) { | ||||||
|     localStorage.setItem('accountPassword', newAccountPassword); |  | ||||||
|       alert('Account created successfully! You can now log in.'); |       alert('Account created successfully! You can now log in.'); | ||||||
|       toggleSignUpPopup(); // Close sign-up popup
 |       toggleSignUpPopup(); // Close sign-up popup
 | ||||||
|  |     } else { | ||||||
|  |       alert('Account creation failed. Please try again.'); | ||||||
|  |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   // Function to toggle the settings popup
 |   // Function to toggle the settings popup
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,143 @@ | ||||||
| "use client"; | "use client"; | ||||||
| import React, { useState, useEffect } from 'react'; | import React, { useState, useEffect } from 'react'; | ||||||
| 
 | 
 | ||||||
| // Define the available model options
 | // Define all models that should be available.
 | ||||||
|  | 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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   }, | ||||||
|  |   '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' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Define the available category options
 | ||||||
| const modelDropdown = { | const modelDropdown = { | ||||||
|   offlineWithoutFoss: ['Offline Fast', 'Offline Slow'], |   offlineWithoutFoss: ['Offline Fast', 'Offline Slow'], | ||||||
|   offlineFoss: ['Offline Fast (FOSS)', 'Offline Slow (FOSS)'], |   offlineFoss: ['Offline Fast (FOSS)', 'Offline Slow (FOSS)'], | ||||||
|  | @ -12,6 +148,7 @@ const modelDropdown = { | ||||||
|     'Online Expensive (Anthropic)', |     'Online Expensive (Anthropic)', | ||||||
|     'Online Cheap (Google)', |     'Online Cheap (Google)', | ||||||
|     'Online Expensive (Google)', |     'Online Expensive (Google)', | ||||||
|  |     'Online (La Plateforme)' | ||||||
|   ], |   ], | ||||||
|   onlineFoss: ['Online (FOSS) (La Plateforme)'], |   onlineFoss: ['Online (FOSS) (La Plateforme)'], | ||||||
| }; | }; | ||||||
|  | @ -98,6 +235,13 @@ const Models: React.FC = () => { | ||||||
|   const isOfflineModel = (model: string) => |   const isOfflineModel = (model: string) => | ||||||
|     modelDropdown.offlineWithoutFoss.includes(model) || modelDropdown.offlineFoss.includes(model); |     modelDropdown.offlineWithoutFoss.includes(model) || modelDropdown.offlineFoss.includes(model); | ||||||
| 
 | 
 | ||||||
|  |   const modelClicked = (model: string) => { | ||||||
|  |     const category = selectedModel as keyof typeof modelList; | ||||||
|  |     console.log(model) | ||||||
|  |     console.log(category) | ||||||
|  |     console.log(modelList[category][model as keyof typeof modelList[typeof category]]); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="model-background"> |     <div className="model-background"> | ||||||
|       <div className="models"> |       <div className="models"> | ||||||
|  | @ -122,7 +266,7 @@ const Models: React.FC = () => { | ||||||
|         <div className="grid"> |         <div className="grid"> | ||||||
|           {['Code', 'Math', 'Language', 'Character', 'Finance', 'Weather', 'Time', 'Image', 'Custom1', 'Custom2'].map( |           {['Code', 'Math', 'Language', 'Character', 'Finance', 'Weather', 'Time', 'Image', 'Custom1', 'Custom2'].map( | ||||||
|             (category) => ( |             (category) => ( | ||||||
|               <button key={category} className={`${category.toLowerCase()}-model model-box`}> |               <button key={category} className={`${category.toLowerCase()}-model model-box`} onClick={() => modelClicked(category)}> | ||||||
|                 <div className="overlay"> |                 <div className="overlay"> | ||||||
|                   <h3>{category}</h3> |                   <h3>{category}</h3> | ||||||
|                   {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} |                   {isOfflineModel(selectedModel) && <img src="/img/nowifi.svg" alt="No Wi-Fi" />} | ||||||
|  |  | ||||||
|  | @ -2,6 +2,15 @@ import React, { useState, useEffect } from 'react'; | ||||||
| import { applyIOMarketTheme, applyWhiteTheme, applyBlackTheme } from './theme'; | import { applyIOMarketTheme, applyWhiteTheme, applyBlackTheme } from './theme'; | ||||||
| import { exportSettings, importSettings } from './settingUtils'; // Import utility functions
 | import { exportSettings, importSettings } from './settingUtils'; // Import utility functions
 | ||||||
| import { getAllLocalStorageItems } from '../backend/GetLocalStorage'; | import { getAllLocalStorageItems } from '../backend/GetLocalStorage'; | ||||||
|  | import { | ||||||
|  |   sendToDatabase, | ||||||
|  |   createAccount, | ||||||
|  |   changePassword, | ||||||
|  |   getData, | ||||||
|  |   changeData, | ||||||
|  |   checkCredentials, | ||||||
|  |   deleteAccount, | ||||||
|  | } from '../backend/database'; | ||||||
| 
 | 
 | ||||||
| const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ({ closeSettings, accountName }) => { | const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ({ closeSettings, accountName }) => { | ||||||
| 
 | 
 | ||||||
|  | @ -50,6 +59,7 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|     const [newName, setNewName] = useState(() => localStorage.getItem('newName') || ''); |     const [newName, setNewName] = useState(() => localStorage.getItem('newName') || ''); | ||||||
|     const [newEmail, setNewEmail] = useState(() => localStorage.getItem('newEmail') || ''); |     const [newEmail, setNewEmail] = useState(() => localStorage.getItem('newEmail') || ''); | ||||||
|     const [newPassword, setNewPassword] = useState(() => localStorage.getItem('newPassword') || ''); |     const [newPassword, setNewPassword] = useState(() => localStorage.getItem('newPassword') || ''); | ||||||
|  |     const [currentPassword, setCurrentPassword] = useState(''); | ||||||
| 
 | 
 | ||||||
|     // Measurement setting
 |     // Measurement setting
 | ||||||
|     const [preferredMeasurement, setPreferredMeasurement] = useState(() => localStorage.getItem('preferredMeasurement') || 'Metric'); |     const [preferredMeasurement, setPreferredMeasurement] = useState(() => localStorage.getItem('preferredMeasurement') || 'Metric'); | ||||||
|  | @ -80,8 +90,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|     const [selectedTheme, setSelectedTheme] = useState(() => localStorage.getItem('selectedTheme') || 'default'); |     const [selectedTheme, setSelectedTheme] = useState(() => localStorage.getItem('selectedTheme') || 'default'); | ||||||
| 
 | 
 | ||||||
|     // API Keys
 |     // API Keys
 | ||||||
|     const [laPlateforme, setLaPlateforme] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-la-plateforme').trim()); |     const [mistral, setmistral] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-la-plateforme').trim()); | ||||||
|     const [openAI, setOpenAI] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-openai').trim()); |     const [openai, setopenai] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-openai').trim()); | ||||||
|     const [anthropic, setAnthropic] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-anthropic').trim()); |     const [anthropic, setAnthropic] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-anthropic').trim()); | ||||||
|     const [google, setGoogle] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-google').trim()); |     const [google, setGoogle] = useState(() => getComputedStyle(document.documentElement).getPropertyValue('--online-cheap-google').trim()); | ||||||
| 
 | 
 | ||||||
|  | @ -132,8 +142,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|           fontSize, |           fontSize, | ||||||
|           burgerMenu, |           burgerMenu, | ||||||
|           selectedTheme, |           selectedTheme, | ||||||
|           laPlateforme, |           mistral, | ||||||
|           openAI, |           openai, | ||||||
|           anthropic, |           anthropic, | ||||||
|           google, |           google, | ||||||
|       }; |       }; | ||||||
|  | @ -182,8 +192,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|       fontSize, |       fontSize, | ||||||
|       burgerMenu, |       burgerMenu, | ||||||
|       selectedTheme, |       selectedTheme, | ||||||
|       laPlateforme, |       mistral, | ||||||
|       openAI, |       openai, | ||||||
|       anthropic, |       anthropic, | ||||||
|       google, |       google, | ||||||
|   ]); |   ]); | ||||||
|  | @ -306,7 +316,41 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|     }   |     }   | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |     // Function to handle updating all credentials
 | ||||||
|  |     const handleUpdateCredentials = async () => { | ||||||
|  |       // Update account information
 | ||||||
|  |       const newData = { | ||||||
|  |         name: newName || accountName, // Keep old name if new name is not provided
 | ||||||
|  |         email: newEmail || '', // Optionally use empty string if not provided
 | ||||||
|  |       }; | ||||||
|    |    | ||||||
|  |       // First change the data
 | ||||||
|  |       const dataSuccess = await changeData(accountName, currentPassword, newData); | ||||||
|  |        | ||||||
|  |       // Then change the password if a new password is provided
 | ||||||
|  |       const passwordSuccess = newPassword ?  | ||||||
|  |         await changePassword(accountName, currentPassword, newPassword) :  | ||||||
|  |         true; // If no new password, treat as success
 | ||||||
|  |    | ||||||
|  |       if (dataSuccess && passwordSuccess) { | ||||||
|  |         alert('Credentials updated successfully!'); | ||||||
|  |         closeSettings(); // Close settings after updating
 | ||||||
|  |       } else { | ||||||
|  |         alert('Failed to update credentials. Please check your current password.'); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |    | ||||||
|  |     // Function to handle account deletion
 | ||||||
|  |     const handleDeleteAccount = async () => { | ||||||
|  |       const success = await deleteAccount(accountName, currentPassword); | ||||||
|  |       if (success) { | ||||||
|  |         alert('Account deleted successfully!'); | ||||||
|  |         closeSettings(); // Close settings after deletion
 | ||||||
|  |         // Optionally, redirect or reset state here
 | ||||||
|  |       } else { | ||||||
|  |         alert('Account deletion failed. Please check your password.'); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|   // Render settings content based on the active section
 |   // Render settings content based on the active section
 | ||||||
|  | @ -860,15 +904,28 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|                 onChange={(e) => setNewPassword(e.target.value)} |                 onChange={(e) => setNewPassword(e.target.value)} | ||||||
|               /> |               /> | ||||||
|             </div> |             </div> | ||||||
|  |             <div className="settings-option"> | ||||||
|  |               <label>Current Password</label> | ||||||
|  |               <input | ||||||
|  |                 type="password" | ||||||
|  |                 value={currentPassword} | ||||||
|  |                 onChange={(e) => setCurrentPassword(e.target.value)} | ||||||
|  |               /> | ||||||
|  |             </div> | ||||||
|             <div className="settings-option"> |             <div className="settings-option"> | ||||||
|               <button |               <button | ||||||
|                 onClick={() => { |                 onClick={handleUpdateCredentials} // Update all credentials
 | ||||||
|                   handleLogout(); |                 className="update-credentials-button" | ||||||
|                   closeSettings(); // Optionally close settings after logout
 |  | ||||||
|                 }} |  | ||||||
|                 className="logout-button" |  | ||||||
|               > |               > | ||||||
|                 Logout |                 Update Credentials | ||||||
|  |               </button> | ||||||
|  |             </div> | ||||||
|  |             <div className="settings-option"> | ||||||
|  |               <button | ||||||
|  |                 onClick={handleDeleteAccount} // Delete account
 | ||||||
|  |                 className="delete-account-button" | ||||||
|  |               > | ||||||
|  |                 Delete Account | ||||||
|               </button> |               </button> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|  | @ -881,16 +938,16 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|                 <label>La Plateforme</label> |                 <label>La Plateforme</label> | ||||||
|                 <input |                 <input | ||||||
|                   type="text" |                   type="text" | ||||||
|                   value={laPlateforme} |                   value={mistral} | ||||||
|                   onChange={(e) => setLaPlateforme(e.target.value)} |                   onChange={(e) => setmistral(e.target.value)} | ||||||
|                 /> |                 /> | ||||||
|               </div> |               </div> | ||||||
|               <div className="settings-option"> |               <div className="settings-option"> | ||||||
|                 <label>OpenAI</label> |                 <label>OpenAI</label> | ||||||
|                 <input |                 <input | ||||||
|                   type="text" |                   type="text" | ||||||
|                   value={openAI} |                   value={openai} | ||||||
|                   onChange={(e) => setOpenAI(e.target.value)} |                   onChange={(e) => setopenai(e.target.value)} | ||||||
|                 /> |                 /> | ||||||
|               </div> |               </div> | ||||||
|               <div className="settings-option"> |               <div className="settings-option"> | ||||||
|  | @ -973,8 +1030,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( | ||||||
|     openSourceMode, |     openSourceMode, | ||||||
| 
 | 
 | ||||||
|     // API Keys
 |     // API Keys
 | ||||||
|    laPlateforme, |    mistral, | ||||||
|    openAI, |    openai, | ||||||
|    anthropic, |    anthropic, | ||||||
|    google |    google | ||||||
| }; | }; | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								py/ai.py
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								py/ai.py
									
										
									
									
									
								
							|  | @ -80,11 +80,6 @@ class AI: | ||||||
|         message = messages[-1]['content'] |         message = messages[-1]['content'] | ||||||
|         messages.pop() |         messages.pop() | ||||||
| 
 | 
 | ||||||
|         system = None |  | ||||||
|         if messages and messages[0]['role'] == 'system': |  | ||||||
|             system = messages[0]['content'] |  | ||||||
|             messages.pop(0) |  | ||||||
| 
 |  | ||||||
|         for msg in messages: |         for msg in messages: | ||||||
|             msg['parts'] = msg.pop('content') |             msg['parts'] = msg.pop('content') | ||||||
| 
 | 
 | ||||||
|  | @ -97,8 +92,8 @@ class AI: | ||||||
|         model = genai.GenerativeModel(model) |         model = genai.GenerativeModel(model) | ||||||
| 
 | 
 | ||||||
|         chat = model.start_chat( |         chat = model.start_chat( | ||||||
|             system_instruction=system, |             history=messages, | ||||||
|             history=messages | 
 | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         response = chat.send_message(message, stream=True) |         response = chat.send_message(message, stream=True) | ||||||
|  |  | ||||||
|  | @ -70,6 +70,13 @@ class API: | ||||||
|                 thread.start() |                 thread.start() | ||||||
|                 thread.join() |                 thread.join() | ||||||
|                 return jsonify({'status': 200}) |                 return jsonify({'status': 200}) | ||||||
|  |             elif model_type == "google": | ||||||
|  |                 api_key = data.get('api_key') | ||||||
|  |                 thread = threading.Thread(target=self.ai.process_google, | ||||||
|  |                                           args=(ai_model, messages, self, access_token, api_key)) | ||||||
|  |                 thread.start() | ||||||
|  |                 thread.join() | ||||||
|  |                 return jsonify({'status': 200}) | ||||||
| 
 | 
 | ||||||
|             return jsonify({'status': 401, 'error': 'Invalid AI model type'}) |             return jsonify({'status': 401, 'error': 'Invalid AI model type'}) | ||||||
| 
 | 
 | ||||||
|  | @ -94,6 +101,8 @@ class API: | ||||||
|                 return jsonify({'status': 200, 'response': self.db.change_data(data)}) |                 return jsonify({'status': 200, 'response': self.db.change_data(data)}) | ||||||
|             elif action == "check_credentials": |             elif action == "check_credentials": | ||||||
|                 return jsonify({'status': 200, 'response': self.db.check_credentials(data)}) |                 return jsonify({'status': 200, 'response': self.db.check_credentials(data)}) | ||||||
|  |             elif action == "delete_account": | ||||||
|  |                 return jsonify({'status': 200, 'response': self.db.delete_user(data)}) | ||||||
| 
 | 
 | ||||||
|             return jsonify({'status': 401, 'response': "Invalid action"}) |             return jsonify({'status': 401, 'response': "Invalid action"}) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| import io | import io | ||||||
| import numpy as np |  | ||||||
| from faster_whisper import WhisperModel | from faster_whisper import WhisperModel | ||||||
| from pydub import AudioSegment | from pydub import AudioSegment | ||||||
| 
 | 
 | ||||||
|  | @ -19,7 +18,7 @@ class VoiceRecognition: | ||||||
|             print("audio to wav failed") |             print("audio to wav failed") | ||||||
|          |          | ||||||
|         model_size = "base" |         model_size = "base" | ||||||
|         model = WhisperModel(model_size, device="cpu", compute_type="int8") |         model = WhisperModel(model_size, device="cpu", compute_type=" ") | ||||||
|          |          | ||||||
|         segments, _ = model.transcribe(wav_io) |         segments, _ = model.transcribe(wav_io) | ||||||
|         transcription = "" |         transcription = "" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue