Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/CogitoNTNU/jarvis
Browse files Browse the repository at this point in the history
  • Loading branch information
EldarAlvik committed Nov 7, 2024
2 parents 9d4a802 + 6d262fb commit a9c7327
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 100 deletions.
2 changes: 1 addition & 1 deletion core/graphAgent.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
18 changes: 10 additions & 8 deletions core/noder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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.
Expand Down
143 changes: 79 additions & 64 deletions core/static/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 */ `
<div id="spinner" class="dot-spinner">
<div></div>
<div></div>
<div></div>
<div></div>
</div>`
}else{
try{
document.getElementById("spinner").remove()
}catch(e){
</div>`;
} 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*/ `
<li class = "chat_element">
<img class="profile_picture" src="./static/rickroll-roll.gif">
<div class="chat_message_container">
<div id=${uuid} class="chat_message"> ${message} </div>
</li>`;
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*/ `
<div class="process_element">
<img class="process_icon" src="./static/tool_icon.png" alt="Tool Icon">
<div class="process_message">${toolResponse}</div>
</div>`;
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*/ `
<li class = "chat_element">
<img class="profile_picture" src="https://media1.tenor.com/m/pMhSj9NfCXsAAAAd/saul-goodman-better-call-saul.gif">
<div class="chat_message_container">
<div class="chat_message">${message}</div>
</li>`
document.getElementById('chat_history').innerHTML += html;
}
</li>`;
document.getElementById("chat_history").innerHTML += html;
};

initialLoadMessages = () => {
const chat_box = document.getElementById('chat_history')
allChats = []
chat_box.value = messageLog.join('\n')
}
const chat_box = document.getElementById("chat_history");
allChats = [];
chat_box.value = messageLog.join("\n");
};
54 changes: 27 additions & 27 deletions core/static/socketEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -54,4 +54,4 @@ socket.on("tool_response", async (tool_response) => {
chat_history.scrollTop = chat_history.scrollHeight;
*/

console.log('socketEvents.js loaded...')
console.log("socketEvents.js loaded...");

0 comments on commit a9c7327

Please sign in to comment.