Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add serverside function for app #2

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
qdrant:
image: qdrant/qdrant:v1.2.0
ports:
- "6333:6333"
volumes:
- qdrant_storage:/qdrant/storage
environment:
QDRANT__LOG_LEVEL: "INFO"

volumes:
qdrant_storage:
98 changes: 98 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
annotated-types==0.7.0
anyio==4.4.0
asttokens==2.4.1
attrs==23.2.0
backcall==0.2.0
backoff==2.2.1
beautifulsoup4==4.12.3
bleach==6.1.0
certifi==2024.7.4
charset-normalizer==3.3.2
click==8.1.7
decorator==5.1.1
defusedxml==0.7.1
distro==1.9.0
dnspython==2.6.1
docopt==0.6.2
email_validator==2.2.0
executing==2.0.1
fastapi==0.111.1
fastapi-cli==0.0.4
fastjsonschema==2.20.0
grpcio==1.65.1
grpcio-tools==1.65.1
h11==0.14.0
h2==4.1.0
hpack==4.0.0
httpcore==1.0.5
httptools==0.6.1
httpx==0.27.0
hyperframe==6.0.1
idna==3.7
ipython==8.12.3
jedi==0.19.1
Jinja2==3.1.4
jsonschema==4.23.0
jsonschema-specifications==2023.12.1
jupyter_client==8.6.2
jupyter_core==5.7.2
jupyterlab_pygments==0.3.0
markdown-it-py==3.0.0
MarkupSafe==2.1.5
matplotlib-inline==0.1.7
mdurl==0.1.2
mem0ai==0.0.9
mistune==3.0.2
monotonic==1.6
nbclient==0.10.0
nbconvert==7.16.4
nbformat==5.10.4
numpy==2.0.1
openai==1.37.0
packaging==24.1
pandocfilters==1.5.1
parso==0.8.4
pexpect==4.9.0
pickleshare==0.7.5
pipreqs==0.5.0
platformdirs==4.2.2
portalocker==2.10.1
posthog==3.5.0
prompt_toolkit==3.0.47
protobuf==5.27.2
ptyprocess==0.7.0
pure_eval==0.2.3
pydantic==2.8.2
pydantic_core==2.20.1
Pygments==2.18.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-multipart==0.0.9
PyYAML==6.0.1
pyzmq==26.0.3
qdrant-client==1.10.1
referencing==0.35.1
requests==2.32.3
rich==13.7.1
rpds-py==0.19.1
setuptools==71.1.0
shellingham==1.5.4
six==1.16.0
sniffio==1.3.1
soupsieve==2.5
stack-data==0.6.3
starlette==0.37.2
tinycss2==1.3.0
tornado==6.4.1
tqdm==4.66.4
traitlets==5.14.3
typer==0.12.3
typing_extensions==4.12.2
urllib3==2.2.2
uvicorn==0.30.3
uvloop==0.19.0
watchfiles==0.22.0
wcwidth==0.2.13
webencodings==0.5.1
websockets==12.0
yarg==0.1.9
10 changes: 10 additions & 0 deletions script/export_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

# Check if .env file exists in the parent directory
if [ ! -f ../.env ]; then
echo "../.env file not found!"
exit 1
fi

# Export each variable from ../.env file
export $(grep -v '^#' ../.env | xargs)
Empty file added server/__init__.py
Empty file.
2 changes: 2 additions & 0 deletions server/api_test/test_main.http
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ GET http://127.0.0.1:8000/hello/User
Accept: application/json

###
GET http://127.0.0.1:8000/ask/hello
Accept: application/json
Empty file added server/domain/__init__.py
Empty file.
Empty file added server/domain/model/__init__.py
Empty file.
Empty file.
68 changes: 68 additions & 0 deletions server/domain/service/RememberService.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import os
from openai import OpenAI
from mem0 import Memory
from dotenv import load_dotenv

# dotenv_path = os.path.join(os.path.dirname(__file__), '../.env')
load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')

# Initialize the OpenAI client
client = OpenAI()


class RememberService:
def __init__(self):
"""
Initialize the PersonalAITutor with memory configuration and OpenAI client.
"""
# in case we want to change to qdrant
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": os.getenv('QDRANT_HOST'),
"port": os.getenv('QDRANT_PORT'),
"api_key": os.getenv('QDRANT_API_KEY')
}
},
}
self.memory = Memory.from_config(config)
self.client = client
self.app_id = "app-1"
self.messages = [{"role": "system",
"content": """
Kamu adalah asisten personal bernama bear.
kamu akan membantu user meningat setiap peristiwa dan hal-hal yang diceritakan
"""}]

async def ask(self, question, user_id=1):
# Fetch previous related memories
previous_memories = self.get_memories(user_id=user_id)
prompt = question
if previous_memories:
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
self.messages.append({"role": "user", "content": prompt})

# Generate response using GPT-4o
response = self.client.chat.completions.create(
model="gpt-3.5-turbo",
messages=self.messages
)
answer = response.choices[0].message.content
self.messages.append({"role": "assistant", "content": answer})

# Store the question in memory
self.memory.add(question, user_id=user_id)
return dict({
"message": answer
})

def get_memories(self, user_id):
memories = self.memory.get_all(user_id=user_id)
return [m['text'] for m in memories]

def search_memories(self, query, user_id):
memories = self.memory.search(query, user_id=user_id)
return [m['text'] for m in memories]
2 changes: 2 additions & 0 deletions server/domain/service/TriggerService.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class TriggerService:
pass
Empty file.
25 changes: 25 additions & 0 deletions server/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from server.domain.service.RememberService import RememberService
import backoff
import httpx

app = FastAPI()

origins = [
"http://localhost",
"http://localhost:3000", # Adjust based on your frontend's URL and port
"http://127.0.0.1:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)


@app.get("/")
async def root():
Expand All @@ -11,3 +28,11 @@ async def root():
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello {name}"}


@backoff.on_exception(backoff.expo, httpx.RequestError, max_time=60)
@app.get("/ask/{prompt}")
async def ask(prompt: str):
ai = RememberService()
response = await ai.ask(prompt)
return response
15 changes: 15 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": 2,
"builds": [
{
"src": "./server/main.py",
"use": "@vercel/python"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "/server/main.py"
}
]
}
3 changes: 2 additions & 1 deletion web/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
CAPACITOR_ANDROID_STUDIO_PATH=
CAPACITOR_ANDROID_STUDIO_PATH=
NEXT_PUBLIC_SERVER_URL=
17 changes: 16 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,32 @@
},
"dependencies": {
"@capacitor/android": "^6.1.1",
"@capacitor/camera": "^6.0.1",
"@capacitor/core": "^6.1.1",
"@capacitor/keyboard": "^6.0.1",
"@capacitor/local-notifications": "^6.0.0",
"@capacitor/network": "^6.0.1",
"@capacitor/push-notifications": "^6.0.1",
"@hookform/resolvers": "^3.9.0",
"@next-auth/firebase-adapter": "0.0.2-canary.207",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@vercel/analytics": "^1.3.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"firebase": "^10.12.4",
"lucide-react": "^0.414.0",
"next": "14.2.5",
"next-auth": "^4.24.7",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.52.1",
"react-icons": "^5.2.1",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@capacitor/cli": "^6.1.1",
Expand Down
15 changes: 11 additions & 4 deletions web/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type {Metadata} from "next";
import {Inter} from "next/font/google";
import "./globals.css";
import {Analytics} from "@vercel/analytics/react"
import React, {StrictMode} from "react";
import {Navbar} from "@/components/navbar";

const inter = Inter({subsets: ["latin"]});

Expand All @@ -17,10 +19,15 @@ export default function RootLayout({
}>) {
return (
<>
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
<Analytics/>
<StrictMode>
<html lang="en">
<body className={inter.className}>
<Navbar/>
{children}
</body>
</html>
<Analytics/>
</StrictMode>
</>
);
}
28 changes: 28 additions & 0 deletions web/src/app/login/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type {Metadata} from "next";
import {Inter} from "next/font/google";
import {Analytics} from "@vercel/analytics/react"
import React from "react";

const inter = Inter({subsets: ["latin"]});

export const metadata: Metadata = {
title: "Remembear",
description: "An app for short term memory",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<>
<html lang="en">
<body className={inter.className}>
{children}
</body>
</html>
<Analytics/>
</>
);
}
21 changes: 21 additions & 0 deletions web/src/app/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Image from "next/image";
import Link from "next/link";
import {Button, buttonVariants} from "@/components/ui/button";
import {Textarea} from "@/components/ui/textarea";

export default function Login() {
return (
<form>
<main className="flex min-h-screen flex-col items-center p-2">
<h1>
Login
</h1>
<Link
href={"/"}
className={buttonVariants({variant: "default"})}>
Login with google
</Link>
</main>
</form>
);
}
Loading