forked from React-Group/interstellar_ai
Merge branch 'main' of interstellardevelopment.org:YasinOnm08/interstellar_ai
This commit is contained in:
commit
33eceb1f37
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:
|
||||||
.catch(error => {
|
|
||||||
console.log("Error calling Database:", error)
|
action -> contains the action you want to do, there are: create_account, change_password, get_data, change_data, check_credentials, delete_account
|
||||||
postMessage({ status: 500 })
|
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 => {
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
|
@ -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,33 +49,40 @@ 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) {
|
||||||
setIsLoggedIn(true); // Successful login
|
const success = await checkCredentials(accountIdentifier, password);
|
||||||
setShowLoginPopup(false); // Close the login popup
|
if (success) {
|
||||||
// Save credentials to localStorage (optional in case of changes)
|
setIsLoggedIn(true); // Successful login
|
||||||
localStorage.setItem('accountName', savedAccountName || accountName);
|
setShowLoginPopup(false); // Close the login popup
|
||||||
localStorage.setItem('accountEmail', savedAccountEmail || email);
|
// Save credentials to localStorage (optional in case of changes)
|
||||||
localStorage.setItem('accountPassword', savedAccountPassword || password);
|
localStorage.setItem('accountName', savedAccountName || accountName);
|
||||||
|
localStorage.setItem('accountEmail', savedAccountEmail || email);
|
||||||
|
localStorage.setItem('accountPassword', savedAccountPassword || password);
|
||||||
|
} else {
|
||||||
|
alert('Incorrect credentials');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
alert('Incorrect credentials');
|
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)'],
|
||||||
};
|
};
|
||||||
|
@ -20,7 +157,7 @@ const Models: React.FC = () => {
|
||||||
// Initialize state with value from localStorage or default to ''
|
// Initialize state with value from localStorage or default to ''
|
||||||
const [selectedModel, setSelectedModel] = useState('');
|
const [selectedModel, setSelectedModel] = useState('');
|
||||||
const [radioSelection, setRadioSelection] = useState<string | null>("")
|
const [radioSelection, setRadioSelection] = useState<string | null>("")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setRadioSelection(localStorage.getItem('radioSelection'))
|
setRadioSelection(localStorage.getItem('radioSelection'))
|
||||||
const handleStorageChange = () => {
|
const handleStorageChange = () => {
|
||||||
|
@ -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
|
||||||
|
@ -832,9 +876,9 @@ const Settings: React.FC<{ closeSettings: () => void; accountName: string }> = (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
case 'account':
|
case 'account':
|
||||||
return (
|
return (
|
||||||
<div className="settings-section">
|
<div className="settings-section">
|
||||||
<h2>Account Settings</h2>
|
<h2>Account Settings</h2>
|
||||||
<div className="settings-option">
|
<div className="settings-option">
|
||||||
<label>New Name</label>
|
<label>New Name</label>
|
||||||
|
@ -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…
Reference in a new issue