diff --git a/app/backend/ProcessMemory.ts b/app/backend/ProcessMemory.ts deleted file mode 100644 index d66d8e5..0000000 --- a/app/backend/ProcessMemory.ts +++ /dev/null @@ -1,20 +0,0 @@ -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[] -} - - - diff --git a/app/backend/ProcessMemory.tsx b/app/backend/ProcessMemory.tsx new file mode 100644 index 0000000..c402e15 --- /dev/null +++ b/app/backend/ProcessMemory.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +type Chat = { + name:string + messages:string[] +} + +type History = { + chats:Chat[] +} + + + diff --git a/app/backend/database.ts b/app/backend/database.ts index 054302b..7b7437d 100644 --- a/app/backend/database.ts +++ b/app/backend/database.ts @@ -1,96 +1,16 @@ import axios from "axios"; -/* -This is the guide on how to user this function: +const sendToDatabase = (data: any) => { + axios.post("http://localhost:5000/interstellar_ai/db", data) + .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 => { - 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 => { - postMessage({ status: 500, success: false }); - 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); -}; + }) + .catch(error => { + console.log("Error calling Database:", error) + postMessage({ status: 500 }) + }) +} \ No newline at end of file diff --git a/app/components/Login.tsx b/app/components/Login.tsx index c766f09..665a7b3 100644 --- a/app/components/Login.tsx +++ b/app/components/Login.tsx @@ -1,11 +1,8 @@ import React, { useState, useEffect } from 'react'; -import { - createAccount, - checkCredentials, -} from '../backend/database'; import Settings from './Settings'; // Import the Settings component const Login: React.FC = () => { + // State to handle popup visibility const [showLoginPopup, setShowLoginPopup] = useState(false); const [showSignUpPopup, setShowSignUpPopup] = useState(false); @@ -31,11 +28,7 @@ const Login: React.FC = () => { setAccountName(savedAccountName); setEmail(savedAccountEmail); setPassword(savedAccountPassword); - const check = async () => { - const success = await checkCredentials(savedAccountName, savedAccountPassword); - setIsLoggedIn(success); // Automatically log in - }; - check(); + setIsLoggedIn(true); // Automatically log in } }, []); @@ -49,40 +42,33 @@ const Login: React.FC = () => { }; // Function to handle login - const handleLogin = async () => { + const handleLogin = () => { const savedAccountEmail = localStorage.getItem('accountEmail'); const savedAccountPassword = localStorage.getItem('accountPassword'); const savedAccountName = localStorage.getItem('accountName'); - // Check if savedAccountName or savedAccountEmail is not null before passing to checkCredentials - const accountIdentifier = savedAccountName || savedAccountEmail; - - if (accountIdentifier && password === savedAccountPassword) { - const success = await checkCredentials(accountIdentifier, password); - if (success) { - setIsLoggedIn(true); // Successful login - setShowLoginPopup(false); // Close the login popup - // Save credentials to localStorage (optional in case of changes) - localStorage.setItem('accountName', savedAccountName || accountName); - localStorage.setItem('accountEmail', savedAccountEmail || email); - localStorage.setItem('accountPassword', savedAccountPassword || password); - } else { - alert('Incorrect credentials'); - } + if ( + (email === savedAccountEmail || accountName === savedAccountName) && + password === savedAccountPassword + ) { + setIsLoggedIn(true); // Successful login + setShowLoginPopup(false); // Close the login popup + // Save credentials to localStorage (optional in case of changes) + localStorage.setItem('accountName', savedAccountName || accountName); + localStorage.setItem('accountEmail', savedAccountEmail || email); + localStorage.setItem('accountPassword', savedAccountPassword || password); } else { alert('Incorrect credentials'); } }; // Function to handle account creation - const handleCreateAccount = async () => { - const success = await createAccount(newAccountName, newAccountEmail, newAccountPassword); - if (success) { - alert('Account created successfully! You can now log in.'); - toggleSignUpPopup(); // Close sign-up popup - } else { - alert('Account creation failed. Please try again.'); - } + const handleCreateAccount = () => { + localStorage.setItem('accountName', newAccountName); + localStorage.setItem('accountEmail', newAccountEmail); + localStorage.setItem('accountPassword', newAccountPassword); + alert('Account created successfully! You can now log in.'); + toggleSignUpPopup(); // Close sign-up popup }; // Function to toggle the settings popup diff --git a/app/components/Models.tsx b/app/components/Models.tsx index 1f9dc56..894623a 100644 --- a/app/components/Models.tsx +++ b/app/components/Models.tsx @@ -1,143 +1,7 @@ "use client"; import React, { useState, useEffect } from 'react'; -// 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 +// Define the available model options const modelDropdown = { offlineWithoutFoss: ['Offline Fast', 'Offline Slow'], offlineFoss: ['Offline Fast (FOSS)', 'Offline Slow (FOSS)'], @@ -148,7 +12,6 @@ const modelDropdown = { 'Online Expensive (Anthropic)', 'Online Cheap (Google)', 'Online Expensive (Google)', - 'Online (La Plateforme)' ], onlineFoss: ['Online (FOSS) (La Plateforme)'], }; @@ -157,7 +20,7 @@ const Models: React.FC = () => { // Initialize state with value from localStorage or default to '' const [selectedModel, setSelectedModel] = useState(''); const [radioSelection, setRadioSelection] = useState("") - + useEffect(() => { setRadioSelection(localStorage.getItem('radioSelection')) const handleStorageChange = () => { @@ -235,13 +98,6 @@ const Models: React.FC = () => { const isOfflineModel = (model: string) => 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 (
@@ -266,7 +122,7 @@ const Models: React.FC = () => {
{['Code', 'Math', 'Language', 'Character', 'Finance', 'Weather', 'Time', 'Image', 'Custom1', 'Custom2'].map( (category) => ( - -
-
-
@@ -938,16 +881,16 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( setmistral(e.target.value)} + value={laPlateforme} + onChange={(e) => setLaPlateforme(e.target.value)} />
setopenai(e.target.value)} + value={openAI} + onChange={(e) => setOpenAI(e.target.value)} />
@@ -1030,8 +973,8 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = ( openSourceMode, // API Keys - mistral, - openai, + laPlateforme, + openAI, anthropic, google }; diff --git a/py/ai.py b/py/ai.py index 2554fd5..5879e9d 100644 --- a/py/ai.py +++ b/py/ai.py @@ -80,6 +80,11 @@ class AI: message = messages[-1]['content'] messages.pop() + system = None + if messages and messages[0]['role'] == 'system': + system = messages[0]['content'] + messages.pop(0) + for msg in messages: msg['parts'] = msg.pop('content') @@ -92,8 +97,8 @@ class AI: model = genai.GenerativeModel(model) chat = model.start_chat( - history=messages, - + system_instruction=system, + history=messages ) response = chat.send_message(message, stream=True) diff --git a/py/api.py b/py/api.py index 75fbfd4..18af5e4 100644 --- a/py/api.py +++ b/py/api.py @@ -70,13 +70,6 @@ class API: thread.start() thread.join() 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'}) @@ -101,8 +94,6 @@ class API: return jsonify({'status': 200, 'response': self.db.change_data(data)}) elif action == "check_credentials": 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"}) diff --git a/py/voice.py b/py/voice.py index 24d12ac..dc0d28b 100644 --- a/py/voice.py +++ b/py/voice.py @@ -1,4 +1,5 @@ import io +import numpy as np from faster_whisper import WhisperModel from pydub import AudioSegment @@ -18,7 +19,7 @@ class VoiceRecognition: print("audio to wav failed") model_size = "base" - model = WhisperModel(model_size, device="cpu", compute_type=" ") + model = WhisperModel(model_size, device="cpu", compute_type="int8") segments, _ = model.transcribe(wav_io) transcription = ""