Skip to content

Commit

Permalink
sending whole history to backend
Browse files Browse the repository at this point in the history
  • Loading branch information
yachty66 committed Jul 2, 2024
1 parent 8da318d commit ec33c70
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 13 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,12 @@ if we build this from scratch than i dont even need supabase

## backlog

- [ ] add cyberpunk mode to map - if the user clicks one of the major cities here futuristic gen ai images of the city are displayed
- [ ] add cyberpunk mode to map - if the user clicks one of the major cities here futuristic gen ai images of the city are displayed
- [ ] make all the spots which have a name in the map already like golden gate park
- [ ] make everything clickable
- [ ] show current location
- [ ] add star on github button
- [ ] add more agentic functions
- [ ] go to X

returning functions to call from the chatinterface would be the best
69 changes: 64 additions & 5 deletions api/index.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from fastapi import FastAPI, HTTPException
from fastapi import FastAPI, HTTPException, WebSocket, WebSocketDisconnect
from typing import List
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from supabase import create_client, Client
from openai import AsyncOpenAI
from openai import AsyncOpenAI, OpenAI
import os
import logging
import json
from pydantic import BaseModel

# Set up logging
logging.basicConfig(level=logging.INFO)
Expand Down Expand Up @@ -40,7 +43,6 @@ async def get_events():
if not supabase:
logger.error("Supabase client not initialized")
raise HTTPException(status_code=500, detail="Supabase client not initialized")

try:
response = supabase.table("resident_advisor").select("*").order('created_at', desc=True).limit(1).execute()
logger.info(f"Supabase response: {response}")
Expand All @@ -57,19 +59,76 @@ async def get_events():
logger.error(f"Exception occurred: {e}")
raise HTTPException(status_code=500, detail=str(e))

tools = [
{
"type": "function",
"function": {
"name": "go_to_place_in_map",
"description": "Go to a place in the map",
"parameters": {
"type": "object",
"properties": {
"place": {
"type": "string",
"description": "The name of the place to navigate to.",
}
},
"required": ["place"],
},
},
}
]

#how to build a good agent system with tools - thinking of just using openai function calling
def check_for_function_call():
system=f"""
You are a chatbot on top of a map. Your job is to help the user navigate the map. You can use the available functions to help you with this task.
"""
#todo this needs to be messages from the frontend
user_query="Go to berlin."
user_content=f"""
You are giving a chat conversation and based on this conversation you need to decide if an function from the available functions needs to be called. the available functions are:
---
{tools}
---
in the case a function can be called return the function name and the arguments that need to be passed to the function in JSON. Its important that the name of the key for the function name is `function_name` and the name of the key for the arguments is `arguments`. In the case a function cannot be called return an empty JSON object.
Following the chat conversation:
---
{user_query}
---
"""
completion = client.chat.completions.create(
model="gpt-3.5-turbo",
response_format={ "type": "json_object" },
temperature=0.0,
messages=[
{"role": "system", "content": system},
{"role": "user", "content": user_content}
]
)
response_content = completion.choices[0].message.content
return response_content

def final_response():

pass


#how to build a good agent system with tools - thinking of just using openai function calling
@app.post("/api/ask")
async def ask(req: dict):
print("req: ", req)
#check_for_function_call()
logger.info("Received request for /api/ask with data: %s", req)
try:
stream = await client.chat.completions.create(
messages=req["messages"],
model="gpt-3.5-turbo",
stream=True,
)

async def generator():
async for chunk in stream:
yield chunk.choices[0].delta.content or ""
Expand Down
Empty file added api/tools.py
Empty file.
52 changes: 51 additions & 1 deletion public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,53 @@ function initializeMap() {
});
}

function initializeWebSocket() {
const socket = new WebSocket("ws://localhost:8000/ws");

socket.onopen = function(event) {
console.log("WebSocket is open now.");
};

socket.onmessage = function(event) {
console.log("WebSocket message received:", event.data);
test(event.data); // Call the test function with the received message
};

socket.onclose = function(event) {
console.log("WebSocket is closed now.");
};

socket.onerror = function(error) {
console.error("WebSocket error observed:", error);
};
}

async function go_to_place(placeName = 'Berlin') {
//all what needs to happen is that this endpoint is getting called
const geocodingUrl = `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(placeName)}.json?access_token=${mapboxgl.accessToken}`;

try {
const response = await fetch(geocodingUrl);
const data = await response.json();

if (data.features && data.features.length > 0) {
const coordinates = data.features[0].center;

map.flyTo({
center: coordinates,
zoom: 10, // Adjust this value to set the desired zoom level
essential: true // This animation is considered essential with respect to prefers-reduced-motion
});
} else {
console.error('Location not found');
}
} catch (error) {
console.error('Error fetching location:', error);
}
}



function loadEvents() {
fetch('/api/events')
.then(response => response.json())
Expand Down Expand Up @@ -47,4 +94,7 @@ function displayEvents(events) {
}

// Call initializeMap when the window loads
window.onload = initializeMap;
window.onload = function() {
initializeMap();
initializeWebSocket();
};
13 changes: 7 additions & 6 deletions public/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ document.addEventListener("DOMContentLoaded", function() {
const chatInput = document.getElementById("chatInput");
const chatMessages = document.getElementById("chatMessages");
let isStreaming = false; // Flag to track if a response is being streamed

//const baseURL = window.location.hostname === "localhost" ? "http://localhost:8000" : "https://www.pantheon.so";
let chatHistory = []; // Array to store the chat history

function sendMessage() {
if (isStreaming) {
Expand All @@ -18,6 +17,9 @@ document.addEventListener("DOMContentLoaded", function() {
return;
}

// Add user message to chat history
chatHistory.push({"role": "user", "content": message});

// Append user message to chat
appendMessage("user", message);

Expand All @@ -32,9 +34,7 @@ document.addEventListener("DOMContentLoaded", function() {
"Content-Type": "application/json"
},
body: JSON.stringify({
messages: [
{"role": "user", "content": message}
]
messages: chatHistory // Send the entire chat history
})
})
.then(response => {
Expand Down Expand Up @@ -62,6 +62,8 @@ document.addEventListener("DOMContentLoaded", function() {
reader.read().then(({ done, value }) => {
if (done) {
console.log("Final result:", result);
// Add assistant's response to chat history
chatHistory.push({"role": "assistant", "content": result});
isStreaming = false; // Set the flag to false when streaming is complete
return;
}
Expand All @@ -76,7 +78,6 @@ document.addEventListener("DOMContentLoaded", function() {
isStreaming = false; // Set the flag to false if an error occurs
});
}

read();
})
.catch(error => {
Expand Down

0 comments on commit ec33c70

Please sign in to comment.