From 042b916fe4045a1e314e457c767021467d433987 Mon Sep 17 00:00:00 2001 From: Deshraj Yadav Date: Thu, 25 Jul 2024 15:01:36 -0700 Subject: [PATCH] [Examples] Add mem0 example --- plugins/mem0/main.py | 58 +++++++++++++++++++++++++++++++++++ plugins/mem0/models.py | 56 +++++++++++++++++++++++++++++++++ plugins/mem0/requirements.txt | 7 +++++ 3 files changed, 121 insertions(+) create mode 100644 plugins/mem0/main.py create mode 100644 plugins/mem0/models.py create mode 100644 plugins/mem0/requirements.txt diff --git a/plugins/mem0/main.py b/plugins/mem0/main.py new file mode 100644 index 0000000000..64e3bc9648 --- /dev/null +++ b/plugins/mem0/main.py @@ -0,0 +1,58 @@ +import os + +from fastapi import FastAPI +from fastapi.templating import Jinja2Templates +from modal import Image, App, Secret, asgi_app, mount + +from models import Memory +from mem0 import MemoryClient + +app = FastAPI() + +modal_app = App( + name="plugins_examples", + secrets=[Secret.from_dotenv(".env")], + mounts=[ + mount.Mount.from_local_dir("templates/", remote_path="templates/"), + ], +) + +mem0 = MemoryClient(api_key=os.getenv("MEM0_API_KEY", "123")) + + +@modal_app.function( + image=Image.debian_slim().pip_install_from_requirements("requirements.txt"), + keep_warm=1, # need 7 for 1rps + memory=(1024, 2048), + cpu=4, + allow_concurrent_inputs=10, +) +@asgi_app() +def plugins_app(): + return app + + +# ************************************************** +# ************ On Memory Created Plugin ************ +# ************************************************** + + +@app.post("/mem0") +def mem0_add(memory: Memory, uid: str): + transcript_segments = memory.transcriptSegments + messages = [] + for segment in transcript_segments: + messages.append( + { + "role": "user" if segment.is_user else "assistant", + "content": segment.text, + } + ) + if not messages: + return {"message": "No messages found"} + + mem0.add(messages, user_id=uid) + memories = mem0.search(messages, user_id=uid) + response = [row["memory"] for row in memories] + response_str = "\n".join(response) + return {"message": f"User memories: {response_str}"} diff --git a/plugins/mem0/models.py b/plugins/mem0/models.py new file mode 100644 index 0000000000..7c8c86f5a8 --- /dev/null +++ b/plugins/mem0/models.py @@ -0,0 +1,56 @@ +from datetime import datetime +from typing import List, Optional + +from pydantic import BaseModel + + +class Structured(BaseModel): + title: str + overview: str + emoji: str = "" + category: str = "other" + + +class ActionItem(BaseModel): + description: str + + +class Event(BaseModel): + title: str + startsAt: datetime + duration: int + description: Optional[str] = "" + created: bool = False + + +class MemoryPhoto(BaseModel): + base64: str + description: str + + +class PluginResponse(BaseModel): + pluginId: Optional[str] = None + content: str + + +class TranscriptSegment(BaseModel): + text: str + speaker: str + speaker_id: int + is_user: bool + start: float + end: float + + +class Memory(BaseModel): + createdAt: datetime + startedAt: Optional[datetime] = None + finishedAt: Optional[datetime] = None + transcript: str = "" + transcriptSegments: List[TranscriptSegment] = [] + photos: Optional[List[MemoryPhoto]] = [] + recordingFilePath: Optional[str] = None + recordingFileBase64: Optional[str] = None + structured: Structured + pluginsResponse: List[PluginResponse] = [] + discarded: bool diff --git a/plugins/mem0/requirements.txt b/plugins/mem0/requirements.txt new file mode 100644 index 0000000000..8eb07e7b6f --- /dev/null +++ b/plugins/mem0/requirements.txt @@ -0,0 +1,7 @@ +mem0ai>=0.0.9 +modal==0.63.75 +fastapi==0.111.0 +fastapi-cli==0.0.4 +modal==0.63.75 +openai==1.35.14 +requests==2.31.0 \ No newline at end of file