diff --git a/core/graphAgent.py b/core/graphAgent.py index f5f62ff..c6605e5 100644 --- a/core/graphAgent.py +++ b/core/graphAgent.py @@ -29,7 +29,7 @@ def __init__(self): self.workflow.add_node("perplexity_agent", perplexity_agent) self.workflow.add_node("calendar_tool", ToolNode(get_tools())) self.workflow.add_node("use_calendar_tool", calendar_tool_decider) - self.workflow.add_node("calendar_decider", calendar_desicion_agent) + self.workflow.add_node("calendar_decider", calendar_decision_agent) self.workflow.add_node("other_agent", other_agent) self.workflow.add_edge(START, "jarvis_agent") diff --git a/core/noder.py b/core/noder.py index 35c83b7..d3d8d5b 100644 --- a/core/noder.py +++ b/core/noder.py @@ -12,7 +12,7 @@ def jarvis_agent(state: GraphState): template= """ Your job is to determine if you need tools to answer the users question and answer with only the name of the option - choose. + chosen. Here are previous messages: @@ -52,8 +52,8 @@ def tool_agent_decider(state: GraphState): Data: {data} Your options for agents are the following: - - "perplexity": This agent has access to tools that use the perplexity API. - These tools are the following: {perplexity_tools} + - "perplexity": This agent has access to tools that use the perplexity API and tools + for doing a RAG-search. These tools are the following: {perplexity_tools} - "calendar": This agent has access to calendar tools These tools are the following: {calendar_tools} - "other": Other tools available: {other_tools} @@ -89,6 +89,8 @@ def response_generator(state: GraphState): prompt = PromptTemplate( template= """ You are a personal assistant and your job is to generate a response to the user. + You should format the response so that it is easy for an text-to-speech model + to communicate to the user Here are the previous messages: @@ -98,7 +100,7 @@ def response_generator(state: GraphState): Data: {data} - Formulate a response that answer the users question + Formulate a response that answer the users question and is formatted correctly """, ) chain = prompt | SimpleAgent.llm @@ -110,8 +112,8 @@ def perplexity_agent(state: GraphState): """Agent that handles tools using the perplexity api""" prompt = PromptTemplate( template= """ - Your job is to create tool_calls to tools using the perplexity API. - The tool or tools you decide + Your job is to create tool_calls to tools using the perplexity API or + to tools that do a RAG-search. The tool or tools you decide to call should help answer the users question. Here are previous messages: @@ -132,11 +134,11 @@ def perplexity_agent(state: GraphState): return {"messages": [response]} -def calendar_desicion_agent(state: GraphState): +def calendar_decision_agent(state: GraphState): """Agent that decides what to do with the calendar""" prompt = PromptTemplate( template= """ - Your job is to determine if you wich calendar related tools you need to answer the + Your job is to determine if you which calendar related tools you need to answer the jarvis agents question and answer with only the name of the option choose. diff --git a/core/static/index.js b/core/static/index.js index 4b78eb5..e2fe57a 100644 --- a/core/static/index.js +++ b/core/static/index.js @@ -5,105 +5,120 @@ Main js file for loading the dynamic UI elements. */ // Runs on inital startup, after window (html) has finished loading - init = () => { - document.getElementById('send_button').addEventListener('click', sendMessage) - document.getElementById('clear_log').addEventListener('click', clear_log) - - document.querySelector(".chatHistory").innerHTML += chatHistoryList() - - // To hide settings page when clicking somewhere else after it's opened. - document.addEventListener('click', function(event){ - const settings = document.getElementById("settingsPage"); - const settingsButton = document.getElementById("settingsButton"); - if(!settings.contains(event.target) && !settingsButton.contains(event.target) && settings.style.display=="block") { - settingsPage() - } - }); -} +init = () => { + document.getElementById("send_button").addEventListener("click", sendMessage); + document.getElementById("clear_log").addEventListener("click", clear_log); + + document.querySelector(".chatHistory").innerHTML += chatHistoryList(); + + // To hide settings page when clicking somewhere else after it's opened. + document.addEventListener("click", function (event) { + const settings = document.getElementById("settingsPage"); + const settingsButton = document.getElementById("settingsButton"); + if ( + !settings.contains(event.target) && + !settingsButton.contains(event.target) && + settings.style.display == "block" + ) { + settingsPage(); + } + }); +}; window.onload = init; // global state of the UI state = { - activeConversationId: 0, // The active conversation ID, so the UI knows what conversation to display and load. - userId: 0, // The user ID using the interface. probably not going to be used for a while. - totalTokensUsed: 0, // Track of total tokens and $$$ used - aiMessageId: 0 // The message id. Set when a response is received from the AI in chat.js -} + activeConversationId: 0, // The active conversation ID, so the UI knows what conversation to display and load. + userId: 0, // The user ID using the interface. probably not going to be used for a while. + totalTokensUsed: 0, // Track of total tokens and $$$ used + aiMessageId: 0, // The message id. Set when a response is received from the AI in chat.js +}; // Changes the loading icon -let loading = false +let loading = false; let setLoading = (newLoadingVal) => { - if(newLoadingVal){ - document.getElementById("chat_history").innerHTML += /* html */` + if (newLoadingVal) { + document.getElementById("chat_history").innerHTML += /* html */ `
-
` - }else{ - try{ - document.getElementById("spinner").remove() - }catch(e){ + `; + } else { + try { + document.getElementById("spinner").remove(); + } catch (e) {} + } - } - } - - loading = newLoadingVal -} + loading = newLoadingVal; +}; // For seeing formatted HTML in javascript files, this extension for VSCode is recommended: // https://marketplace.visualstudio.com/items?itemName=pushqrdx.inline-html async function addMessage(message, uuid) { -let html = /*html*/` + let html = /*html*/ `
  • ${message}
  • `; - document.getElementById('chat_history').innerHTML += html; - const messages = getAllChatMessages(); - console.log(messages); + document.getElementById("chat_history").innerHTML += html; + const messages = getAllChatMessages(); + console.log(messages); } async function getAllChatMessages() { - const chatMessages = document.querySelectorAll('.chat_message'); - const messagesList = []; - chatMessages.forEach((element) => { - messagesList.push(element.textContent.trim()); - }); - return messagesList; + const chatMessages = document.querySelectorAll(".chat_message"); + const messagesList = []; + chatMessages.forEach((element) => { + messagesList.push(element.textContent.trim()); + }); + return messagesList; } async function addStreamedMessage(uuid, messagePart) { - let element = document.getElementById(uuid); - - if (element == null) { - await addMessage(messagePart, uuid); - element = document.getElementById(uuid); - } else { - // Concat ChatPart on message with uuid - element.innerHTML += messagePart; - } - - // Add auto-scroll - let chat_history = document.getElementById("chat_history") - chat_history.scrollTop = chat_history.scrollHeight; + let element = document.getElementById(uuid); + + if (element == null) { + await addMessage(messagePart, uuid); + element = document.getElementById(uuid); + } else { + // Concat ChatPart on message with uuid + element.innerHTML += messagePart; + } + + // Add auto-scroll + let chat_history = document.getElementById("chat_history"); + chat_history.scrollTop = chat_history.scrollHeight; +} + +async function addToolResponseToProcessContainer(toolResponse) { + let html = /*html*/ ` +
    + Tool Icon +
    ${toolResponse}
    +
    `; + document.querySelector(".processesContainer").innerHTML += html; + + // Auto-scroll to the latest process + let processesContainer = document.querySelector(".processesContainer"); + processesContainer.scrollTop = processesContainer.scrollHeight; } addUserMessage = (message) => { - let html = /*html*/` + let html = /*html*/ `
  • ${message}
    -
  • ` - document.getElementById('chat_history').innerHTML += html; -} + `; + document.getElementById("chat_history").innerHTML += html; +}; initialLoadMessages = () => { - const chat_box = document.getElementById('chat_history') - allChats = [] - chat_box.value = messageLog.join('\n') -} \ No newline at end of file + const chat_box = document.getElementById("chat_history"); + allChats = []; + chat_box.value = messageLog.join("\n"); +}; diff --git a/core/static/socketEvents.js b/core/static/socketEvents.js index d7522c1..d0d9da2 100644 --- a/core/static/socketEvents.js +++ b/core/static/socketEvents.js @@ -3,43 +3,43 @@ // TODO: add this port to .env later var socket = io("ws://localhost:3000"); // websocket querying port 3001, where Flask is running. -socket.on('connect', () => { - socket.emit('message', {data: 'I\'m connected!'}); +socket.on("connect", () => { + socket.emit("message", { data: "I'm connected!" }); }); -let tokenCounter = 0 -let uuid = 0 +let tokenCounter = 0; +let uuid = 0; // prints chunks that are streamed to the console and adds them to the chat -socket.on("chunk", async (chunk)=>{ - if(!state.activeAIMessage){ - console.log("STARTED MESSAGE") - uuid = generateUUID(); - await addStreamedMessage(uuid, ""); - ai_message = document.getElementById(uuid) - state.activeAIMessage = ai_message - } - await addStreamedMessage(uuid, chunk); -}) +socket.on("chunk", async (chunk) => { + if (!state.activeAIMessage) { + console.log("STARTED MESSAGE"); + uuid = generateUUID(); + await addStreamedMessage(uuid, ""); + ai_message = document.getElementById(uuid); + state.activeAIMessage = ai_message; + } + await addStreamedMessage(uuid, chunk); +}); socket.on("tokens", async (tokens) => { - state.totalTokensUsed += tokens - console.log("Total tokens so far:", state.totalTokensUsed) - endStreamedAIMessage() -}) - -socket.on("start_message", async () => { + state.totalTokensUsed += tokens; + console.log("Total tokens so far:", state.totalTokensUsed); + endStreamedAIMessage(); +}); -}) +socket.on("start_message", async () => {}); socket.on("tool_call", async (tool_call) => { - console.log("Tool called: ", tool_call); -}) + console.log("Tool called: ", tool_call); +}); socket.on("tool_response", async (tool_response) => { - console.log("Response from tool: ", tool_response); - -}) + console.log("Response from tool: ", tool_response); + + // Add the tool response to the chat + await addToolResponseToProcessContainer(tool_response); +}); // Remember to parse the streamed response @@ -54,4 +54,4 @@ socket.on("tool_response", async (tool_response) => { chat_history.scrollTop = chat_history.scrollHeight; */ -console.log('socketEvents.js loaded...') \ No newline at end of file +console.log("socketEvents.js loaded...");