main #116
5 changed files with 131 additions and 55 deletions
|
@ -1,30 +1,28 @@
|
|||
|
||||
type Message = {
|
||||
role: string;
|
||||
content:string
|
||||
}
|
||||
// type Message = {
|
||||
// role: string;
|
||||
// content:string
|
||||
// }
|
||||
|
||||
type Chat = {
|
||||
name: string;
|
||||
messages: Message[];
|
||||
timestamp: number;
|
||||
};
|
||||
// type Chat = {
|
||||
// name: string;
|
||||
// messages: Message[];
|
||||
// timestamp: number;
|
||||
// };
|
||||
|
||||
export let chatHistory: Chat[] = [];
|
||||
// export function addMessageToHistory(index: number, chat: Chat): void {
|
||||
// if (index >= 0 && index < chatHistory.length) {
|
||||
// chatHistory[index] = chat;
|
||||
// chatHistory.sort((a, b) => b.timestamp - a.timestamp)
|
||||
// }
|
||||
// }
|
||||
|
||||
export function addMessageToHistory(index: number, chat: Chat): void {
|
||||
if (index >= 0 && index < chatHistory.length) {
|
||||
chatHistory[index] = chat;
|
||||
chatHistory.sort((a, b) => b.timestamp - a.timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
export function removeMessageFromHistory(timestamp: number): void {
|
||||
const index = chatHistory.findIndex((msg) => msg.timestamp === timestamp);
|
||||
if (index > -1) {
|
||||
chatHistory.splice(index, 1);
|
||||
console.log(`Removed message with timestamp: ${timestamp}`);
|
||||
} else {
|
||||
console.log(`Message not found with timestamp: ${timestamp}`);
|
||||
}
|
||||
}
|
||||
// export function removeMessageFromHistory(timestamp: number): void {
|
||||
// const index = chatHistory.findIndex((msg) => msg.timestamp === timestamp);
|
||||
// if (index > -1) {
|
||||
// chatHistory.splice(index, 1);
|
||||
// console.log(`Removed message with timestamp: ${timestamp}`);
|
||||
// } else {
|
||||
// console.log(`Message not found with timestamp: ${timestamp}`);
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -5,34 +5,26 @@ import InputFrontend from "../components/InputFrontend";
|
|||
import { sendToVoiceRecognition } from "./voice_backend"
|
||||
import axios from "axios";
|
||||
import { changeHistory, checkCredentials, getHistory } from './database';
|
||||
import { addMessageToHistory, removeMessageFromHistory } from "./ChatHistory";
|
||||
import { useChatHistory } from '../hooks/useChatHistory';
|
||||
|
||||
interface InputOutputHandlerProps {
|
||||
selectedIndex: number;
|
||||
}
|
||||
|
||||
const InputOutputBackend: React.FC<InputOutputHandlerProps> = ({selectedIndex}) => {
|
||||
const InputOutputBackend: React.FC = () => {
|
||||
// # variables
|
||||
type Message = {
|
||||
role: string
|
||||
content: string
|
||||
}
|
||||
|
||||
type Chat = {
|
||||
name?: string
|
||||
messages: Message[]
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
// Define state variables for user preferences and messages
|
||||
const [chatHistory, setChatHistory, setSelectedIndex] = useChatHistory()
|
||||
const [preferredCurrency, setPreferredCurrency] = useState<string>("USD");
|
||||
const [preferredLanguage, setPreferredLanguage] = useState<string>("english");
|
||||
const [timeFormat, setTimeFormat] = useState<string>("24-hour");
|
||||
const [preferredMeasurement, setPreferredMeasurement] = useState<string>("metric");
|
||||
const [timeZone, setTimeZone] = useState<string>("GMT");
|
||||
const [dateFormat, setDateFormat] = useState<string>("DD-MM-YYYY");
|
||||
const [messages, setMessages] = useState<Message[]>([]);
|
||||
const [messages, setMessages] = useState<Message[]>(chatHistory.chats[chatHistory.selectedIndex]?.messages || []);
|
||||
const [myBoolean, setMyBoolean] = useState<boolean>(false);
|
||||
const [systemMessage, setSystemMessage] = useState<string>("You are a helpful assistant")
|
||||
const apiURL = new URL("http://localhost:5000/interstellar_ai/api/ai_create")
|
||||
if (typeof window !== 'undefined') {
|
||||
apiURL.hostname = window.location.hostname;
|
||||
|
@ -40,6 +32,23 @@ const InputOutputBackend: React.FC<InputOutputHandlerProps> = ({selectedIndex})
|
|||
apiURL.hostname = "localhost"
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
console.log("History", chatHistory);
|
||||
console.log("Messages", messages);
|
||||
|
||||
// Get the current chat's messages
|
||||
const currentMessages = chatHistory.chats[chatHistory.selectedIndex]?.messages || [];
|
||||
|
||||
// If currentMessages is not empty, update messages only if it's not the same
|
||||
if (currentMessages.length > 0 && JSON.stringify(currentMessages) !== JSON.stringify(messages)) {
|
||||
setMessages(currentMessages);
|
||||
} else if (messages.length === 0) {
|
||||
setMessages([{ role: "system", content: systemMessage }, { role: "assistant", content: "Hello! How can I help you?" }]);
|
||||
}
|
||||
}, [chatHistory, setSelectedIndex]);
|
||||
|
||||
// Update messages when any of the settings change
|
||||
useEffect(() => {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
|
@ -51,11 +60,14 @@ const InputOutputBackend: React.FC<InputOutputHandlerProps> = ({selectedIndex})
|
|||
setDateFormat(localStorage.getItem("dateFormat") || "DD-MM-YYYY");
|
||||
setMyBoolean(localStorage.getItem('myBoolean') === 'true');
|
||||
}
|
||||
},[])
|
||||
|
||||
useEffect(() => {
|
||||
const measurementString = (preferredMeasurement == "Metric")
|
||||
? "All measurements follow the metric system. Refuse to use any other measurement system."
|
||||
: "All measurements follow the imperial system. Refuse to use any other measurement system.";
|
||||
|
||||
const systemMessage = myBoolean
|
||||
const newSystemMessage = myBoolean
|
||||
? `You are operating in the timezone: ${timeZone}. Use the ${timeFormat} time format and ${dateFormat} for dates.
|
||||
${measurementString}
|
||||
The currency is ${preferredCurrency}.
|
||||
|
@ -63,12 +75,20 @@ const InputOutputBackend: React.FC<InputOutputHandlerProps> = ({selectedIndex})
|
|||
You are only able to change language if the user specifically states you must.
|
||||
Do not answer in multiple languages or multiple measurement systems under any circumstances other than the user requesting it.`
|
||||
: `You are a helpful assistant`;
|
||||
setMessages([
|
||||
{ role: "system", content: systemMessage },
|
||||
{ role: "assistant", content: "Hello! How may I help you?" },
|
||||
]);
|
||||
|
||||
setSystemMessage(newSystemMessage)
|
||||
}, [preferredCurrency, preferredLanguage, timeFormat, preferredMeasurement, timeZone, dateFormat, myBoolean]);
|
||||
|
||||
useEffect(() => {
|
||||
const updateSystemprompt = (prompt: string) => {
|
||||
setMessages(prevMessages => {
|
||||
const newMessage = { role: "system", content: prompt }
|
||||
return [newMessage, ...prevMessages]
|
||||
})
|
||||
}
|
||||
updateSystemprompt
|
||||
},[systemMessage])
|
||||
|
||||
|
||||
const conversationRef = useRef<HTMLDivElement>(null)
|
||||
const [copyClicked, setCopyClicked] = useState(false)
|
||||
|
@ -180,7 +200,11 @@ const InputOutputBackend: React.FC<InputOutputHandlerProps> = ({selectedIndex})
|
|||
};
|
||||
|
||||
const addMessage = (role: string, content: string) => {
|
||||
setMessages(previous => [...previous, { role, content }])
|
||||
const newMessage: Message = { role: role, content: content }
|
||||
setMessages((prevMessages) => [...prevMessages, newMessage])
|
||||
const updatedChats = [...chatHistory.chats]
|
||||
updatedChats[chatHistory.selectedIndex].messages.push(newMessage)
|
||||
setChatHistory({...chatHistory, chats:updatedChats})
|
||||
}
|
||||
const handleSendClick = (inputValue: string, override: boolean) => {
|
||||
if (inputValue != "") {
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { ForwardedRef, useState, useEffect, useRef } from 'react';
|
|||
import Markdown from 'react-markdown'
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { useChatHistory } from '../hooks/useChatHistory';
|
||||
|
||||
type Message = {
|
||||
role: string
|
||||
|
@ -21,6 +22,7 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
|
|||
({ messages, onStopClick, onResendClick, onEditClick, onCopyClick, isClicked }, ref: ForwardedRef<HTMLDivElement>) => {
|
||||
const [isScrolling, setIsScrolling] = useState(true);
|
||||
const messagesEndRef = useRef<HTMLDivElement | null>(null);
|
||||
const [chatHistory, setChatHistory, setSelectedIndex] = useChatHistory()
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
|
@ -61,7 +63,7 @@ const ConversationFrontend = React.forwardRef<HTMLDivElement, ConversationProps>
|
|||
return (
|
||||
<div className="output" ref={ref}>
|
||||
<div className="conversation resize" id="conversation">
|
||||
{messages.map((message, index) => {
|
||||
{chatHistory.chats[chatHistory.selectedIndex].messages.map((message, index) => {
|
||||
if (index >= 1) {
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useChatHistory } from '../hooks/useChatHistory';
|
||||
|
||||
interface HistoryProps{
|
||||
selectedIndex: number;
|
||||
setSelectedIndex: (index: number) => void;
|
||||
}
|
||||
|
||||
const History: React.FC<HistoryProps> = ({selectedIndex, setSelectedIndex}) => {
|
||||
const History: React.FC = () => {
|
||||
const [chatHistory, setChatHistory, setSelectedIndex] = useChatHistory()
|
||||
|
||||
const handleHistoryClick = (index: number) => {
|
||||
setSelectedIndex(index)
|
||||
|
@ -16,9 +13,9 @@ const History: React.FC<HistoryProps> = ({selectedIndex, setSelectedIndex}) => {
|
|||
<div className="history">
|
||||
<ul>
|
||||
{/* Populate with history items */}
|
||||
{Array.from({ length: 20 }, (_, index) => (
|
||||
{chatHistory.chats.map((chats, index) => (
|
||||
<li key={index}>
|
||||
<a href="#" onClick={()=>handleHistoryClick(index)}>history{index + 1}</a>
|
||||
<a href="#" onClick={() => handleHistoryClick(index)}>{chatHistory.chats[index].name}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
55
app/hooks/useChatHistory.tsx
Normal file
55
app/hooks/useChatHistory.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { useEffect, useState } from "react"
|
||||
|
||||
interface Message {
|
||||
role: string
|
||||
content:string
|
||||
}
|
||||
|
||||
interface ChatMessages {
|
||||
name: string
|
||||
messages: Message[]
|
||||
timestamp: number
|
||||
|
||||
}
|
||||
|
||||
interface GlobalChatHistory {
|
||||
chats: ChatMessages[]
|
||||
selectedIndex: number
|
||||
}
|
||||
|
||||
let globalChatHistory: GlobalChatHistory = {
|
||||
chats: [
|
||||
{ name: "Chat 1", messages: [], timestamp: 4 }
|
||||
],
|
||||
selectedIndex:0
|
||||
}
|
||||
let listeners: ((state: GlobalChatHistory) => void)[] = []
|
||||
|
||||
const setGlobalState = (newState: GlobalChatHistory): void => {
|
||||
globalChatHistory = newState;
|
||||
listeners.forEach((listener) => listener(globalChatHistory))
|
||||
}
|
||||
|
||||
export const useChatHistory = (): [GlobalChatHistory, (newState:GlobalChatHistory) => void, (index:number)=>void] => {
|
||||
const [state, setState] = useState<GlobalChatHistory>(globalChatHistory)
|
||||
|
||||
useEffect(() => {
|
||||
console.log("help", globalChatHistory);
|
||||
|
||||
const listener = (newState: GlobalChatHistory) => {
|
||||
setState(newState)
|
||||
}
|
||||
|
||||
listeners.push(listener)
|
||||
|
||||
return () => {
|
||||
listeners = listeners.filter((l) => l!== listener)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setSelectedIndex = (index: number) => {
|
||||
setGlobalState({...state,selectedIndex:index})
|
||||
}
|
||||
|
||||
return [state, setGlobalState, setSelectedIndex]
|
||||
}
|
Loading…
Reference in a new issue