Settings #41
					 6 changed files with 104 additions and 165 deletions
				
			
		|  | @ -1,86 +0,0 @@ | |||
| import React, { useState } from 'react'; | ||||
| import InputFrontend from '../components/InputFrontend'; | ||||
| import ConversationFrontend from '../components/ConversationFrontend'; | ||||
| import { Mistral } from '@mistralai/mistralai'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| const handleMicClick = () => { | ||||
|   console.log('Mic clicked!'); | ||||
|   // Do something when the mic button is clicked
 | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| const handleResendClick = () => { | ||||
|   console.log('Resend button clicked'); | ||||
|   // Handle resend action
 | ||||
| }; | ||||
| 
 | ||||
| const handleEditClick = () => { | ||||
|   console.log('Edit button clicked'); | ||||
|   // Handle edit action
 | ||||
| }; | ||||
| 
 | ||||
| const handleCopyClick = () => { | ||||
|   console.log('Copy button clicked'); | ||||
|   // Handle copy action
 | ||||
| }; | ||||
| 
 | ||||
| const InputBackend: React.FC = () => { | ||||
|   async function prompt_mistral(model: string, prompt: string, system: string) { | ||||
|     const apiKey = "m3kZRjN8DRSIo88r8Iti9hmKGWIklrLY"; | ||||
| 
 | ||||
|     const client = new Mistral({ apiKey: apiKey }); | ||||
| 
 | ||||
|     var chatResponse = await client.chat.complete({ | ||||
|       model: model, | ||||
|       messages: [{ role: 'user', content: prompt }, { role: 'system', content: system, }], | ||||
|     }); | ||||
| 
 | ||||
|     if (chatResponse && chatResponse.choices && chatResponse.choices.length > 0) { | ||||
|       if (chatResponse.choices[0].message.content) { | ||||
|         addMessage('AI: ' + chatResponse.choices[0].message.content); | ||||
|       } | ||||
|     } else { | ||||
|       console.error('Error: Unexpected API response:', chatResponse); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const handleSendClick = (message: string) => { | ||||
|     var system = "You are a helpful assistant. The following is the chat history." | ||||
|     for (let index = 0; index < messages.length; index++) { | ||||
|       system += messages[index] + " "; | ||||
|     }; | ||||
| 
 | ||||
|     addMessage('User: ' + message); | ||||
|     prompt_mistral("mistral-large-latest", message, system) | ||||
|   }; | ||||
| 
 | ||||
|   const [messages, setMessages] = useState([ | ||||
|     'User: Hello!', | ||||
|     'AI: Hi there!', | ||||
|     'User: How are you?', | ||||
|     'AI: I’m good, thank you!' | ||||
|   ]); | ||||
| 
 | ||||
|   const addMessage = (message: string) => { | ||||
|     setMessages((prevMessages) => [...prevMessages, message]); | ||||
|   }; | ||||
|   return ( | ||||
|     <div> | ||||
|       <ConversationFrontend | ||||
|         messages={messages} | ||||
|         onResendClick={handleResendClick} | ||||
|         onEditClick={handleEditClick} | ||||
|         onCopyClick={handleCopyClick} | ||||
|       /> | ||||
|       <InputFrontend | ||||
|         message="" | ||||
|         onSendClick={handleSendClick} | ||||
|         onMicClick={handleMicClick} | ||||
|       /> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| export default InputBackend; | ||||
|  | @ -3,34 +3,28 @@ import React, { useEffect, useRef, useState } from "react"; | |||
| import ConversationFrontend from "../components/ConversationFrontend"; | ||||
| import InputFrontend from "../components/InputFrontend"; | ||||
| import axios from "axios"; | ||||
| import { skip } from "node:test"; | ||||
| 
 | ||||
| const InputOutputBackend: React.FC = () => { | ||||
|   type Message = { | ||||
|     role: string | ||||
|     content:string | ||||
|     content: string | ||||
|   } | ||||
| 
 | ||||
|   const [accessToken, setAccessToken] = useState("") | ||||
|   const postWorkerRef = useRef<Worker| null>(null) | ||||
|   const postWorkerRef = useRef<Worker | null>(null) | ||||
|   const getWorkerRef = useRef<Worker | null>(null) | ||||
|   const [messages, setMessages] = useState<Message[]>([{role:"assistant", content:"Hello! How can I help you?"}]) | ||||
|   const [messages, setMessages] = useState<Message[]>([{ role: "assistant", content: "Hello! How can I help you?" }]) | ||||
|   const [liveMessage, setLiveMessage] = useState("") | ||||
|   const [inputMessage, setInputMessage] = useState<string>("") | ||||
|   const [inputDisabled, setInputDisabled] = useState(false) | ||||
|   const [lastMessage, setLastMessage] = useState<Message>({ role: "user", content: "Not supposed to happen." }) | ||||
| 
 | ||||
|   console.log(messages); | ||||
|    | ||||
| 
 | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     console.log("getting access"); | ||||
|     axios.get("http://localhost:5000/interstellar/api/ai_create") | ||||
|       .then(response => { | ||||
|         setAccessToken(response.data.access_token) | ||||
|         console.log(response.data.access_token); | ||||
|       }) | ||||
|       .catch(error => { | ||||
|       console.log("error:", error.message); | ||||
|        | ||||
|     }) | ||||
|     getNewToken() | ||||
| 
 | ||||
|     postWorkerRef.current = new Worker(new URL("./threads/PostWorker.js", import.meta.url)) | ||||
| 
 | ||||
|  | @ -48,7 +42,7 @@ const InputOutputBackend: React.FC = () => { | |||
|         } | ||||
|       } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     return () => { | ||||
|       if (postWorkerRef.current) { | ||||
|         postWorkerRef.current.terminate() | ||||
|  | @ -58,20 +52,33 @@ const InputOutputBackend: React.FC = () => { | |||
|         getWorkerRef.current.terminate() | ||||
|       } | ||||
|     } | ||||
|   },[]) | ||||
|   }, []) | ||||
| 
 | ||||
|   const getNewToken = () => { | ||||
|     console.log("getting access"); | ||||
|     axios.get("http://localhost:5000/interstellar_ai/api/ai_create") | ||||
|       .then(response => { | ||||
|         setAccessToken(response.data.access_token) | ||||
|         console.log(response.data.access_token); | ||||
|       }) | ||||
|       .catch(error => { | ||||
|         console.log("error:", error.message); | ||||
| 
 | ||||
|       }) | ||||
|   } | ||||
| 
 | ||||
|   const startGetWorker = () => { | ||||
|     if (!getWorkerRef.current) { | ||||
|       getWorkerRef.current = new Worker(new URL("./threads/GetWorker.js", import.meta.url)) | ||||
|    | ||||
|       getWorkerRef.current.postMessage({ action: "start", access_token:accessToken}) | ||||
|    | ||||
|       addMessage("assistant","") | ||||
| 
 | ||||
|       getWorkerRef.current.postMessage({ action: "start", access_token: accessToken }) | ||||
| 
 | ||||
|       addMessage("assistant", "") | ||||
|       getWorkerRef.current.onmessage = (event) => { | ||||
|         const data = event.data | ||||
|          | ||||
| 
 | ||||
|         if (event.data == "error") { | ||||
|           setLiveMessage("error getting AI response: "+ data.error) | ||||
|           setLiveMessage("error getting AI response: " + data.error) | ||||
|         } else { | ||||
|           console.log("Received data:", data); | ||||
|           editLastMessage(data.response) | ||||
|  | @ -81,12 +88,12 @@ const InputOutputBackend: React.FC = () => { | |||
|       getWorkerRef.current.onerror = (error) => { | ||||
|         console.error("Worker error:", error) | ||||
|       } | ||||
|     }   | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const endGetWorker = () => { | ||||
|     if (getWorkerRef.current) { | ||||
|       getWorkerRef.current.postMessage({action:"terminate"}) | ||||
|       getWorkerRef.current.postMessage({ action: "terminate" }) | ||||
|       getWorkerRef.current.terminate() | ||||
|       getWorkerRef.current = null | ||||
|       console.log(messages); | ||||
|  | @ -97,31 +104,32 @@ const InputOutputBackend: React.FC = () => { | |||
|     if (newContent == "") { | ||||
|       newContent = "Generating answer..." | ||||
|     } | ||||
|   setMessages((prevMessages) => { | ||||
|     const updatedMessages = prevMessages.slice(); // Create a shallow copy of the current messages
 | ||||
|     if (updatedMessages.length > 0) { | ||||
|       const lastMessage = updatedMessages[updatedMessages.length - 1]; | ||||
|       updatedMessages[updatedMessages.length - 1] = { | ||||
|         ...lastMessage, // Keep the existing role and other properties
 | ||||
|         content: newContent, // Update only the content
 | ||||
|       }; | ||||
|     } | ||||
|     return updatedMessages; // Return the updated array
 | ||||
|   }); | ||||
| }; | ||||
|     setMessages((prevMessages) => { | ||||
|       const updatedMessages = prevMessages.slice(); // Create a shallow copy of the current messages
 | ||||
|       if (updatedMessages.length > 0) { | ||||
|         const lastMessage = updatedMessages[updatedMessages.length - 1]; | ||||
|         updatedMessages[updatedMessages.length - 1] = { | ||||
|           ...lastMessage, // Keep the existing role and other properties
 | ||||
|           content: newContent, // Update only the content
 | ||||
|         }; | ||||
|       } | ||||
|       return updatedMessages; // Return the updated array
 | ||||
|     }); | ||||
|   }; | ||||
| 
 | ||||
| 
 | ||||
|   const addMessage = (role: string, content: string) => { | ||||
|     setMessages(previous => [...previous,{role,content}]) | ||||
|   }   | ||||
|   const handleSendClick = (inputValue: string) => { | ||||
|     setMessages(previous => [...previous, { role, content }]) | ||||
|   } | ||||
|   const handleSendClick = (inputValue: string, override: boolean) => { | ||||
|     if (inputValue != "") { | ||||
|       if (!inputDisabled) { | ||||
|       console.log(inputDisabled) | ||||
|       if (!inputDisabled || override) { | ||||
|         setInputDisabled(true) | ||||
|         if (postWorkerRef.current) { | ||||
|           addMessage("user", inputValue) | ||||
|           console.log("input:",inputValue); | ||||
|           postWorkerRef.current.postMessage({messages:[...messages, { role: "user", content: inputValue }], ai_model:"phi3.5", access_token:accessToken}) | ||||
|           console.log("input:", inputValue); | ||||
|           postWorkerRef.current.postMessage({ messages: [...messages, { role: "user", content: inputValue }], ai_model: "phi3.5", access_token: accessToken }) | ||||
|           startGetWorker() | ||||
|         } | ||||
|       } | ||||
|  | @ -133,18 +141,33 @@ const InputOutputBackend: React.FC = () => { | |||
|   } | ||||
| 
 | ||||
|   const handleResendClick = () => { | ||||
|     // do stuff
 | ||||
|     var temporary_message = messages[messages.length - 2]['content'] | ||||
|     const updatedMessages = messages.slice(0, -2) | ||||
|     setMessages(updatedMessages) | ||||
|     endGetWorker() | ||||
|     getNewToken() | ||||
|     setInputDisabled(false) | ||||
|     handleSendClick(temporary_message, true) | ||||
|   } | ||||
| 
 | ||||
|   const handleEditClick = () => { | ||||
|     // do stuff
 | ||||
|     setInputMessage(messages[messages.length - 2]['content']) | ||||
|     const updatedMessages = messages.slice(0, -2) | ||||
|     setMessages(updatedMessages) | ||||
|     endGetWorker() | ||||
|     getNewToken() | ||||
|     setInputDisabled(false) | ||||
|   } | ||||
| 
 | ||||
|   const handleCopyClick = () => { | ||||
|     // do stuff
 | ||||
|   const handleCopyClick = async () => { | ||||
|     try { | ||||
|       await navigator.clipboard.writeText(messages[messages.length - 1]['content']); | ||||
|     } catch (err) { | ||||
|       console.error('Failed to copy: ', err); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|     return ( | ||||
|   return ( | ||||
|     <div> | ||||
|       <ConversationFrontend | ||||
|         messages={messages} | ||||
|  | @ -153,13 +176,13 @@ const InputOutputBackend: React.FC = () => { | |||
|         onCopyClick={handleCopyClick} | ||||
|       /> | ||||
|       <InputFrontend | ||||
|         message="" | ||||
|         message={inputMessage} | ||||
|         onSendClick={handleSendClick} | ||||
|         onMicClick={handleMicClick} | ||||
|         inputDisabled={inputDisabled} | ||||
|       /> | ||||
|     </div> | ||||
|     ) | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| export default InputOutputBackend | ||||
|  | @ -168,4 +191,3 @@ export default InputOutputBackend | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|   | ||||
|  | @ -3,8 +3,8 @@ import axios from "axios"; | |||
| let accesstoken | ||||
| onmessage = (event) => { | ||||
|     const { action, access_token } = event.data | ||||
|     accesstoken=access_token | ||||
|      | ||||
|     accesstoken = access_token | ||||
| 
 | ||||
|     if (action === "start") { | ||||
|         fetchData() | ||||
|     } else if (action === "terminate") { | ||||
|  | @ -15,20 +15,20 @@ console.log('starting get loop'); | |||
| 
 | ||||
| const fetchData = () => { | ||||
|     console.log(accesstoken); | ||||
|      | ||||
|      | ||||
|     const apiURL = "http://localhost:5000/interstellar/api/ai_get?access_token="+accesstoken | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
|     const apiURL = "http://localhost:5000/interstellar_ai/api/ai_get?access_token=" + accesstoken | ||||
| 
 | ||||
|     axios.get(apiURL) | ||||
|         .then(response => { | ||||
|             const data = response.data | ||||
|             console.log(data); | ||||
|             postMessage(data) | ||||
|             setTimeout(fetchData,100) | ||||
|             setTimeout(fetchData, 100) | ||||
|         }) | ||||
|         .catch(error => { | ||||
|             console.log('Error fetching data:', error); | ||||
|             postMessage({error:"failed fetching data"}) | ||||
|             setTimeout(() => fetchData(),1000) | ||||
|     }) | ||||
|             postMessage({ error: "failed fetching data" }) | ||||
|             setTimeout(() => fetchData(), 1000) | ||||
|         }) | ||||
| } | ||||
|  | @ -7,23 +7,23 @@ onmessage = (e) => { | |||
|     const Message = { | ||||
|         messages: messages, | ||||
|         ai_model: "phi3.5", | ||||
|         model_type:"local", | ||||
|         access_token:access_token | ||||
|         model_type: "local", | ||||
|         access_token: access_token | ||||
|     } | ||||
| 
 | ||||
|     console.log(Message); | ||||
|      | ||||
| 
 | ||||
|     axios.post("http://localhost:5000/interstellar/api/ai_send",Message) | ||||
| 
 | ||||
|     axios.post("http://localhost:5000/interstellar_ai/api/ai_send", Message) | ||||
|         .then(response => { | ||||
|             const status = response.data.status | ||||
|             console.log(status); | ||||
|             postMessage({ status }) | ||||
|             console.log('message posted'); | ||||
|              | ||||
| 
 | ||||
|         }) | ||||
|         .catch(error => { | ||||
|             console.log("Error calling API:", error) | ||||
|             postMessage({status:500}) | ||||
|     }) | ||||
|             postMessage({ status: 500 }) | ||||
|         }) | ||||
| } | ||||
|  | @ -1,16 +1,19 @@ | |||
| import React, { useState, ForwardedRef } from 'react'; | ||||
| import React, { useState, ForwardedRef, useEffect } from 'react'; | ||||
| 
 | ||||
| interface InputProps { | ||||
|   message: string; | ||||
|   onSendClick: (message: string) => void; | ||||
|   onSendClick: (message: string, override: boolean) => void; | ||||
|   onMicClick: () => void; | ||||
|   inputDisabled:boolean | ||||
|   inputDisabled: boolean | ||||
| } | ||||
| 
 | ||||
| const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | ||||
|   ({ message, onSendClick, onMicClick, inputDisabled }, ref: ForwardedRef<HTMLDivElement>) => { | ||||
|     const [inputValue, setInputValue] = useState(''); | ||||
|      | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|       setInputValue(message); | ||||
|     }, [message]); | ||||
| 
 | ||||
|     const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||||
|       setInputValue(e.target.value); | ||||
|  | @ -19,7 +22,7 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | |||
|     const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { | ||||
|       if (!inputDisabled) { | ||||
|         if (event.key === 'Enter') { | ||||
|           onSendClick(inputValue); // Call the function passed via props
 | ||||
|           onSendClick(inputValue, false); // Call the function passed via props
 | ||||
|           setInputValue(''); // Optionally clear input after submission
 | ||||
|           event.preventDefault(); // Prevent default action (e.g., form submission)
 | ||||
|         } | ||||
|  | @ -36,7 +39,7 @@ const InputFrontend = React.forwardRef<HTMLDivElement, InputProps>( | |||
|           onChange={handleInputChange} | ||||
|           onKeyDown={handleKeyDown} | ||||
|         /> | ||||
|         <button type="button" onClick={() => onSendClick(inputValue)} disabled={inputDisabled?true:false}> | ||||
|         <button type="button" onClick={() => onSendClick(inputValue, false)} disabled={inputDisabled ? true : false}> | ||||
|           <img src="/img/send.svg" alt="send" /> | ||||
|         </button> | ||||
|         <button type="button" onClick={onMicClick}> | ||||
|  |  | |||
							
								
								
									
										12
									
								
								py/api.py
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								py/api.py
									
										
									
									
									
								
							|  | @ -1,4 +1,4 @@ | |||
|             from flask import Flask, request, jsonify | ||||
| from flask import Flask, request, jsonify | ||||
| from flask_cors import CORS | ||||
| import secrets | ||||
| import threading | ||||
|  | @ -26,11 +26,11 @@ class API: | |||
|         def create_ai(): | ||||
|             access_token = secrets.token_urlsafe(self.crypt_size) | ||||
| 
 | ||||
|             if access_token not in self.ai_response: | ||||
|                 self.ai_response[access_token] = "" | ||||
|                 return jsonify({'status': 200, 'access_token': access_token}) | ||||
|             while access_token in self.ai_response: | ||||
|                 access_token = secrets.token_urlsafe(self.crypt_size) | ||||
| 
 | ||||
|             return jsonify({'status': 401, 'error': 'An error occurred, please try again.'}) | ||||
|             self.ai_response[access_token] = "" | ||||
|             return jsonify({'status': 200, 'access_token': access_token}) | ||||
| 
 | ||||
|         @self.app.route('/interstellar_ai/api/ai_send', methods=['POST']) | ||||
|         def send_ai(): | ||||
|  | @ -96,7 +96,7 @@ class API: | |||
|             return jsonify({'status': 401, 'response': "Invalid action"}) | ||||
| 
 | ||||
|         @self.app.route('/interstellar_ai/api/voice_recognition', methods=['POST']) | ||||
|         def db_manipulate(): | ||||
|         def voice_recognition(): | ||||
|             recognition_type = request.args.get('type') | ||||
|             audio = request.args.get('audio_data') | ||||
|             option = request.args.get('option') | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue