Merge pull request 'main' (#28) from React-Group/interstellar_ai:main into main
Reviewed-on: https://interstellardevelopment.org/code/code/sageTheDm/interstellar_ai/pulls/28
This commit is contained in:
		
						commit
						6af5864557
					
				
					 21 changed files with 266 additions and 141 deletions
				
			
		|  | @ -1,15 +1,13 @@ | ||||||
| import axios from "axios"; | import axios from "axios"; | ||||||
| 
 | 
 | ||||||
| 
 | export const sendToVoiceRecognition = (audio_data: Blob): Promise<string> => { | ||||||
| class VoiceSend { |  | ||||||
|     sendToVoiceRecognition(audio_data: Blob) { |  | ||||||
|     console.log("sending recording..."); |     console.log("sending recording..."); | ||||||
| 
 | 
 | ||||||
|     const formdata = new FormData() |     const formdata = new FormData() | ||||||
|     formdata.append("audio", audio_data) |     formdata.append("audio", audio_data) | ||||||
| 
 | 
 | ||||||
|     const dataSend = { option: "offline", type: "basic", audio: audio_data } |     const dataSend = { option: "offline", type: "basic", audio: audio_data } | ||||||
|         axios.post("http://localhost:5000/interstellar_ai/api/voice_recognition", formdata) |     return axios.post("http://localhost:5000/interstellar_ai/api/voice_recognition", formdata) | ||||||
|         .then((response) => { |         .then((response) => { | ||||||
|             console.log(response.data) |             console.log(response.data) | ||||||
|             return response.data.response |             return response.data.response | ||||||
|  | @ -17,10 +15,6 @@ class VoiceSend { | ||||||
|         .catch(error => { |         .catch(error => { | ||||||
|             console.log("Error calling API:", error) |             console.log("Error calling API:", error) | ||||||
|             postMessage({ status: 500 }) |             postMessage({ status: 500 }) | ||||||
|  |             return "Error" | ||||||
|         }) |         }) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export default VoiceSend; |  | ||||||
|  | @ -4,11 +4,9 @@ import InputOutputBackend from '../backend/InputOutputHandler'; | ||||||
| 
 | 
 | ||||||
| const AI: React.FC = () => { | const AI: React.FC = () => { | ||||||
|   return ( |   return ( | ||||||
|     <div> |  | ||||||
|       <div className="ai-container"> |       <div className="ai-container"> | ||||||
|         <InputOutputBackend /> |         <InputOutputBackend /> | ||||||
|       </div> |       </div> | ||||||
|     </div> |  | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,13 +17,6 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps> | ||||||
|   ({ messages, onResendClick, onEditClick, onCopyClick, isClicked}, ref: ForwardedRef<HTMLDivElement>) => { |   ({ messages, onResendClick, onEditClick, onCopyClick, isClicked}, ref: ForwardedRef<HTMLDivElement>) => { | ||||||
|     const endOfMessagesRef = useRef<HTMLDivElement>(null); |     const endOfMessagesRef = useRef<HTMLDivElement>(null); | ||||||
| 
 | 
 | ||||||
|     // Auto-scroll to the bottom of the conversation whenever a new message is added
 |  | ||||||
|     useEffect(() => { |  | ||||||
|       if (endOfMessagesRef.current) { |  | ||||||
|         endOfMessagesRef.current.scrollIntoView({ behavior: 'smooth' }); |  | ||||||
|       } |  | ||||||
|     }, [messages]); // Triggers the effect whenever the 'messages' array changes
 |  | ||||||
| 
 |  | ||||||
|     useEffect(() => { |     useEffect(() => { | ||||||
|       console.log(isClicked); |       console.log(isClicked); | ||||||
|        |        | ||||||
|  |  | ||||||
|  | @ -13,6 +13,10 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | ||||||
|   ({ message, onSendClick, onMicClick, inputDisabled, isRecording }, ref: ForwardedRef<HTMLDivElement>) => { |   ({ message, onSendClick, onMicClick, inputDisabled, isRecording }, ref: ForwardedRef<HTMLDivElement>) => { | ||||||
|     const [inputValue, setInputValue] = useState(''); |     const [inputValue, setInputValue] = useState(''); | ||||||
| 
 | 
 | ||||||
|  |     useEffect(() => { | ||||||
|  |       setInputValue(message); | ||||||
|  |     }, [message]); | ||||||
|  | 
 | ||||||
|     const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { |     const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||||||
|       setInputValue(e.target.value); |       setInputValue(e.target.value); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  | @ -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" />} | ||||||
|  |  | ||||||
|  | @ -5,6 +5,9 @@ export const metadata = { | ||||||
|   description: 'A little AI chat that is able to assist you in little tasks', |   description: 'A little AI chat that is able to assist you in little tasks', | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| export default function RootLayout({ children }: { children: ReactNode }) { | export default function RootLayout({ children }: { children: ReactNode }) { | ||||||
|   return ( |   return ( | ||||||
|     <html lang="en"> |     <html lang="en"> | ||||||
|  |  | ||||||
							
								
								
									
										25
									
								
								app/page.tsx
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								app/page.tsx
									
										
									
									
									
								
							|  | @ -15,31 +15,6 @@ const LandingPage: React.FC = () => { | ||||||
|   const [view, setView] = useState<'AI' | 'FAQ' | 'Documentation' | 'Credits'>('AI'); // Added 'Credits' here
 |   const [view, setView] = useState<'AI' | 'FAQ' | 'Documentation' | 'Credits'>('AI'); // Added 'Credits' here
 | ||||||
|   const conversationRef = useRef<HTMLDivElement>(null); |   const conversationRef = useRef<HTMLDivElement>(null); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |  | ||||||
|     const scrollToBottom = () => { |  | ||||||
|       const conversation = conversationRef.current; |  | ||||||
|       if (conversation) { |  | ||||||
|         conversation.scrollTop = conversation.scrollHeight; |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     scrollToBottom(); |  | ||||||
| 
 |  | ||||||
|     const observer = new MutationObserver(scrollToBottom); |  | ||||||
|     if (conversationRef.current) { |  | ||||||
|       observer.observe(conversationRef.current, { |  | ||||||
|         childList: true, |  | ||||||
|         subtree: true, |  | ||||||
|       }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return () => { |  | ||||||
|       if (conversationRef.current) { |  | ||||||
|         observer.disconnect(); |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|   }, []); |  | ||||||
| 
 |  | ||||||
|   const toggleDivs = () => { |   const toggleDivs = () => { | ||||||
|     setShowDivs(prevState => !prevState); |     setShowDivs(prevState => !prevState); | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     z-index: 10000; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .settings-main h2 { | .settings-main h2 { | ||||||
|  | @ -104,14 +103,14 @@ | ||||||
|     padding: 5px 10px; |     padding: 5px 10px; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     position: absolute; /* Position the button absolutely */ |     position: absolute; /* Position the button absolutely */ | ||||||
|     top: 10px; /* Distance from the top */ |     top: 15px; /* Distance from the top */ | ||||||
|     right: 10px; /* Distance from the right */ |     right: 40px; /* Distance from the right */ | ||||||
|     transition: background 0.3s; |     transition: background 0.3s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Close button positioning */ | /* Close button positioning */ | ||||||
| .apply { | .apply { | ||||||
|     background: var(--close-button-color); /* Use variable for close button color */ |     background: var(--apply-button-color); /* Use variable for close button color */ | ||||||
|     color: white; /* Use white for text color */ |     color: white; /* Use white for text color */ | ||||||
|     border: none; |     border: none; | ||||||
|     border-radius: 5px; |     border-radius: 5px; | ||||||
|  | @ -119,7 +118,7 @@ | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     position: absolute; /* Position the button absolutely */ |     position: absolute; /* Position the button absolutely */ | ||||||
|     top: 50px; /* Distance from the top */ |     top: 50px; /* Distance from the top */ | ||||||
|     right: 10px; /* Distance from the right */ |     right: 40px; /* Distance from the right */ | ||||||
|     transition: background 0.3s; |     transition: background 0.3s; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,19 +1,19 @@ | ||||||
| /* container.css */ | /* container.css */ | ||||||
| .container, | .container{ | ||||||
| .content { |  | ||||||
|     display: flex; |     display: flex; | ||||||
|     width: 100vw; |     width: 100vw; | ||||||
|     padding-top: 0.025vh; |     height: 100vh; | ||||||
|  |     padding-top: 12vh; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .left-panel { | .left-panel { | ||||||
|     margin-top: 5em; |  | ||||||
|     width: 25vw; /* Adjust as needed */ |     width: 25vw; /* Adjust as needed */ | ||||||
|     transition: width 0.3s ease, opacity 0.3s ease, visibility 0.3s ease; /* Smooth transitions for all properties */ |     transition: width 0.3s ease, opacity 0.3s ease, visibility 0.3s ease; /* Smooth transitions for all properties */ | ||||||
|     background-color: var(--left-panel-background-color); /* Use variable for background color */ |     background-color: var(--left-panel-background-color); /* Use variable for background color */ | ||||||
|     border-radius: 0 1em 0 0; |     border-radius: 0 1em 0 0; | ||||||
|     margin-left: 0; |     margin-left: 0; | ||||||
|     padding-right: 1em; |     padding-right: 1em; | ||||||
|  |     height: 100%; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .left-panel.hidden { | .left-panel.hidden { | ||||||
|  | @ -23,12 +23,11 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .conversation-container { | .conversation-container { | ||||||
|     margin-top: 5em; |  | ||||||
|     flex: 1; |     flex: 1; | ||||||
|     transition: margin-left 0.3s ease; /* Smooth margin adjustment */ |     transition: margin-left 0.3s ease; /* Smooth margin adjustment */ | ||||||
|     background-color: var(--conversation-background-color); /* Use variable for background color */ |     background-color: var(--conversation-background-color); /* Use variable for background color */ | ||||||
|     border-radius: 1em 0 0 0; |     border-radius: 1em 0 0 0; | ||||||
|     height: min-content; |     height: 100%; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Adjust margin-left when panel is shown or hidden */ | /* Adjust margin-left when panel is shown or hidden */ | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| html, | html, | ||||||
| body { | body { | ||||||
|     height: 100vh; |     height: 100vh; | ||||||
|     /* overflow: hidden; */ |     overflow: hidden; | ||||||
|     position: relative; |     position: relative; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,11 +7,14 @@ header{ | ||||||
|     height: 10vh; |     height: 10vh; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|  |     justify-content: center; | ||||||
|     font-size: 1em; |     font-size: 1em; | ||||||
|  |     z-index: 999; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .hamburger{ | .hamburger{ | ||||||
|     position: absolute; |     position: absolute; | ||||||
|  |     left: 5vw; | ||||||
|     display: none; |     display: none; | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|  | @ -39,9 +42,10 @@ header{ | ||||||
| 
 | 
 | ||||||
| .nav-links{ | .nav-links{ | ||||||
|     position: absolute; |     position: absolute; | ||||||
|  |     left: 1vw; | ||||||
|     display: flex; |     display: flex; | ||||||
|     gap: 1em; |     gap: 0.5vw; | ||||||
|     width: 35vw; |     width:max-content; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
|  | @ -52,7 +56,8 @@ header{ | ||||||
|     font-size: 0.9em; |     font-size: 0.9em; | ||||||
|     height: 50%; |     height: 50%; | ||||||
|     border-radius: 5px; |     border-radius: 5px; | ||||||
|     padding: 1px 15px; |     padding: 2px 15px; | ||||||
|  |     font-family: var(--font-family); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .nav-btn:hover{ | .nav-btn:hover{ | ||||||
|  | @ -60,7 +65,6 @@ header{ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .header-logo{ | .header-logo{ | ||||||
|     margin:auto; |  | ||||||
|     width: 250px; |     width: 250px; | ||||||
|     height: 5vh; |     height: 5vh; | ||||||
|     background-image: url(../../public/img/logo.png); |     background-image: url(../../public/img/logo.png); | ||||||
|  | @ -72,16 +76,19 @@ header{ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .login-button-container{ | .login-button-container{ | ||||||
|  |     position: absolute; | ||||||
|  |     top: 0.2vh; | ||||||
|  |     right: 1vw; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     display: flex; |     display: flex; | ||||||
|     align-items: center; |     align-items: center; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .header-login-button{ | .header-login-button{ | ||||||
|     font-size: 2vh; |     font-size: var(--font-size); | ||||||
|     position: absolute; |     /* position: absolute; | ||||||
|     top: 1.5vh; |     top: 1.5vh; | ||||||
|     right: 1vw; |     right: 1vw; */ | ||||||
|     padding: 10px 20px; |     padding: 10px 20px; | ||||||
|     background-color: var(--input-button-color); |     background-color: var(--input-button-color); | ||||||
|     color: var(--text-color); |     color: var(--text-color); | ||||||
|  | @ -89,6 +96,7 @@ header{ | ||||||
|     border-radius: 5px; |     border-radius: 5px; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     transition: background-color 0.3s; |     transition: background-color 0.3s; | ||||||
|  |     font-family: var(--font-family); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .header-login-button:hover { | .header-login-button:hover { | ||||||
|  |  | ||||||
|  | @ -1,13 +1,13 @@ | ||||||
| .history-background { | .history-background { | ||||||
|     grid-column: 1/2; |     grid-column: 1/2; | ||||||
|     grid-row: 1/2; |     grid-row: 1/2; | ||||||
|     height: 40vh; |     height: 45%; | ||||||
|     overflow: hidden; |     overflow: hidden; | ||||||
|     background-color: var(--history-background-color); |     background-color: var(--history-background-color); | ||||||
|     padding: 1em; |     padding: 1em; | ||||||
|     margin: 1em; |     margin: 1em; | ||||||
|     margin-right: 0; |     margin-right: 0; | ||||||
|     border-radius: 2em; |     border-radius: 1em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .history { | .history { | ||||||
|  | @ -37,3 +37,7 @@ | ||||||
| .history ul li a:hover { | .history ul li a:hover { | ||||||
|     background-color: var(--input-button-hover-color); |     background-color: var(--input-button-hover-color); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .history-models{ | ||||||
|  |     height: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -2,22 +2,24 @@ | ||||||
| .input { | .input { | ||||||
|     grid-column: 2/3; |     grid-column: 2/3; | ||||||
|     grid-row: 4/5; |     grid-row: 4/5; | ||||||
|     border-radius: 20px; |     border-radius: 8px; | ||||||
|     background-color: var(--input-background-color); |     background-color: var(--input-background-color); | ||||||
|     padding: 1em; |     padding: 1em; | ||||||
|     margin: 1em; |     padding-left: 0.5em; | ||||||
|  |     padding-right: 0; | ||||||
|  |     margin: 0 10px; | ||||||
|  |     margin-bottom: 10px; | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: space-between; |     justify-content: space-between; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     height: auto; |     height: auto; | ||||||
|     gap: 10px; |  | ||||||
|     height: 10vh; |     height: 10vh; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .input input { | .input input { | ||||||
|     flex-grow: 1; |     flex-grow: 1; | ||||||
|     padding: 5px; |     padding: 5px; | ||||||
|     font-size: 1.2em; |     font-size: 1em; | ||||||
|     border-radius: 8px; |     border-radius: 8px; | ||||||
|     border: 2px solid var(--input-button-color); |     border: 2px solid var(--input-button-color); | ||||||
|     outline: none; |     outline: none; | ||||||
|  | @ -33,16 +35,17 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .input button { | .input button { | ||||||
|     padding: 1em; |     padding: 5px; | ||||||
|     margin: 5px; |     margin: 5px; | ||||||
|  |     margin-left: 0; | ||||||
|     background-color: var(--input-button-color); |     background-color: var(--input-button-color); | ||||||
|     color: var(--user-message-text-color); /* Use variable for button text color */ |     color: var(--user-message-text-color); /* Use variable for button text color */ | ||||||
|     border: none; |     border: none; | ||||||
|     border-radius: 50%; |     border-radius: 8px; | ||||||
|     font-size: 1.5em; |     font-size: 1.5em; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     height: 50px; |     height: 50px; | ||||||
|     width: 50px; |     width: 75px; | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|  | @ -52,7 +55,7 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .input button img { | .input button img { | ||||||
|     height: 1em; |     height: 20px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .input button:hover { | .input button:hover { | ||||||
|  |  | ||||||
|  | @ -1,13 +1,13 @@ | ||||||
| .model-background { | .model-background { | ||||||
|     grid-column: 1/2; |     grid-column: 1/2; | ||||||
|     grid-row: 1/2; |     grid-row: 1/2; | ||||||
|     height: 45vh; |     height: 45%; | ||||||
|     overflow: hidden; |     overflow: hidden; | ||||||
|     background-color: var(--history-background-color); |     background-color: var(--history-background-color); | ||||||
|     padding: 1em; |     padding: 1em; | ||||||
|     margin: 1em; |     margin: 0 1em; | ||||||
|     margin-right: 0; |     margin-right: 0; | ||||||
|     border-radius: 2em; |     border-radius: 1em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .models { | .models { | ||||||
|  | @ -17,12 +17,12 @@ | ||||||
|     overflow-y: scroll; |     overflow-y: scroll; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .models .titel { | .models .title { | ||||||
|     padding-bottom: 1em; |  | ||||||
|     display: flex; |     display: flex; | ||||||
|     justify-content: center; |     justify-content: center; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     font-size: 0.7em; |     font-size: 1.5em; | ||||||
|  |     margin-bottom: 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .model-dropdown { | .model-dropdown { | ||||||
|  | @ -56,7 +56,6 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .overlay { | .overlay { | ||||||
|     z-index: 900; |  | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     left: 0; |     left: 0; | ||||||
|     width: 100%; |     width: 100%; | ||||||
|  |  | ||||||
|  | @ -2,24 +2,21 @@ | ||||||
| .output { | .output { | ||||||
|     grid-column: 2; |     grid-column: 2; | ||||||
|     grid-row: 1 / 4; |     grid-row: 1 / 4; | ||||||
|     border-radius: 2em; |  | ||||||
|     background-color: var(--output-background-color); |     background-color: var(--output-background-color); | ||||||
|     padding: 1em; |  | ||||||
|     margin: 1em; |     margin: 1em; | ||||||
|     margin-top: 0; |  | ||||||
|     display: flex; |     display: flex; | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     justify-content: flex-start; |     justify-content: flex-start; | ||||||
|     font-size: 1em; |     font-size: 1em; | ||||||
|     overflow-y: auto; |     overflow-y: auto; | ||||||
|     width: calc(100% - 2em); /* Corrected calculation for width */ |     width: calc(100% - 2em); /* Corrected calculation for width */ | ||||||
|     height: 75vh; |     height: 70vh; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #conversation { | #conversation { | ||||||
|     display: flex; |     display: flex; | ||||||
|     flex-direction: column; |     flex-direction: column; | ||||||
|     padding: 10px; |     padding-left: 10px; | ||||||
|     overflow-y: auto; |     overflow-y: auto; | ||||||
|     max-height: 80vh; |     max-height: 80vh; | ||||||
|     background-color: var(--output-background-color); |     background-color: var(--output-background-color); | ||||||
|  | @ -51,16 +48,17 @@ | ||||||
| /* Button Container */ | /* Button Container */ | ||||||
| .button-container { | .button-container { | ||||||
|     display: flex; |     display: flex; | ||||||
|     padding: 10px 0; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .button-container button { | .button-container button { | ||||||
|     background: none; |     background: none; | ||||||
|     border: none; |     border: none; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     border-radius: 50%; |     border-radius: 100%; | ||||||
|     padding: 10px; |     padding: 10px; | ||||||
|     transition: background-color 0.3s ease; |     transition: background-color 0.3s ease; | ||||||
|  |     height: 40px; | ||||||
|  |     width: 40px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .button-container button:hover { | .button-container button:hover { | ||||||
|  | @ -68,7 +66,8 @@ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .button-container img { | .button-container img { | ||||||
|     height: 1.5em; |     height: 20px; | ||||||
|  |     width: 20px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #copiedText{ | #copiedText{ | ||||||
|  |  | ||||||
|  | @ -27,13 +27,6 @@ | ||||||
|     padding: 7em 0 0 0 ; |     padding: 7em 0 0 0 ; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   header li { |  | ||||||
|     display: flex; |  | ||||||
|     flex-direction: column; |  | ||||||
|     justify-content: center; |  | ||||||
|     margin: 0; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   /* Left panel styles */ |   /* Left panel styles */ | ||||||
|   .left-panel { |   .left-panel { | ||||||
|     display: hidden; /* Initially hidden */ |     display: hidden; /* Initially hidden */ | ||||||
|  | @ -43,6 +36,7 @@ | ||||||
| 
 | 
 | ||||||
|   .left-panel.visible { |   .left-panel.visible { | ||||||
|     display: block; |     display: block; | ||||||
|  |     height: min-content; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /* Conversation container styles */ |   /* Conversation container styles */ | ||||||
|  | @ -104,10 +98,9 @@ | ||||||
|     color: var(--user-message-text-color); /* Use variable for button text color */ |     color: var(--user-message-text-color); /* Use variable for button text color */ | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .header-login-button{ |   .header-logo{ | ||||||
|     position: absolute; |     position: relative; | ||||||
|     top: 3.5vh; |     margin-left: -40px; | ||||||
|     right: 5vw; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .hamburger.open{ |   .hamburger.open{ | ||||||
|  | @ -130,17 +123,23 @@ | ||||||
| 
 | 
 | ||||||
|   .nav-links.active{ |   .nav-links.active{ | ||||||
|     display: flex; |     display: flex; | ||||||
|  |     height: fit-content; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .nav-btn{ |   .nav-btn{ | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     text-align: left; |     text-align: center; | ||||||
|     padding: 10px; |     padding: 10px; | ||||||
|  |     height: 50px; | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   .hamburger { |   .hamburger { | ||||||
|     display: flex; |     display: flex; | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   .header-login-button{ | ||||||
|  |     right: 5vh; | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Responsive adjustments for the settings */ | /* Responsive adjustments for the settings */ | ||||||
|  |  | ||||||
|  | @ -25,3 +25,9 @@ | ||||||
|     margin-right: auto; |     margin-right: auto; | ||||||
|     text-align: left; |     text-align: left; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .ai-container{ | ||||||
|  |     height: min-content; | ||||||
|  |     bottom: 0; | ||||||
|  |     width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ | ||||||
|     --doc-background-color: #ffffff; /* Background color for documents */ |     --doc-background-color: #ffffff; /* Background color for documents */ | ||||||
|     --close-button-color: red; |     --close-button-color: red; | ||||||
|     --close-button-hover-color: #9e0101; /*NEW*/ |     --close-button-hover-color: #9e0101; /*NEW*/ | ||||||
|  |     --apply-button-color:#8B9635; | ||||||
|  |     --apply-button-hover-color:#6b7c2b; | ||||||
|     --burger-menu-background-color: #79832e;  /*NEW*/ |     --burger-menu-background-color: #79832e;  /*NEW*/ | ||||||
|     --overlay-text-color:white; /*NEW*/ |     --overlay-text-color:white; /*NEW*/ | ||||||
|      |      | ||||||
|  |  | ||||||
							
								
								
									
										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'}) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,24 +8,18 @@ class VoiceRecognition: | ||||||
|     def recognition(audio): |     def recognition(audio): | ||||||
|         audio_buffer = io.BytesIO(audio.read()) |         audio_buffer = io.BytesIO(audio.read()) | ||||||
| 
 | 
 | ||||||
|         try: |  | ||||||
|         audio_segment = AudioSegment.from_file(audio_buffer, format="ogg") |         audio_segment = AudioSegment.from_file(audio_buffer, format="ogg") | ||||||
| 
 | 
 | ||||||
|         wav_io = io.BytesIO() |         wav_io = io.BytesIO() | ||||||
|         audio_segment.export(wav_io, format="wav") |         audio_segment.export(wav_io, format="wav") | ||||||
|         wav_io.seek(0) |         wav_io.seek(0) | ||||||
|         except: |  | ||||||
|             print("audio to wav failed") |  | ||||||
| 
 | 
 | ||||||
|         model_size = "base" |         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) |         segments, _ = model.transcribe(wav_io) | ||||||
|         transcription = "" |         transcription = "" | ||||||
|         for segment in segments: |         for segment in segments: | ||||||
|             transcription += segment.text + " " |             transcription += segment.text + " " | ||||||
|         result = transcription.strip() |         result = transcription.strip() | ||||||
|         print(result) |  | ||||||
|         return result |         return result | ||||||
| 
 |  | ||||||
| # npm install @ffmpeg/ffmpeg @ffmpeg/util @ffmpeg/types @ffmpeg/core-mt |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue