-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from crux-bphc/memory
Long Term Memory
- Loading branch information
Showing
10 changed files
with
1,161 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from enum import Enum | ||
from typing import Optional | ||
|
||
from langchain.pydantic_v1 import BaseModel, Field | ||
|
||
|
||
class Category(str, Enum): | ||
Course_Like = "Course Likes" | ||
Course_Dislike = "Course Dislikes" | ||
Branch = "Branch" | ||
Clubs = "Clubs" | ||
Person_Attribute = "Person Attributes" | ||
|
||
|
||
class Action(str, Enum): | ||
Create = "Create" | ||
Update = "Update" | ||
Delete = "Delete" | ||
|
||
|
||
class AddMemory(BaseModel): | ||
id: str = Field(..., description="The ID of the user") | ||
memory: str = Field( | ||
..., | ||
description="Condensed bit of knowledge to be saved for future reference in the format: [fact to store] (e.g. Likes Thermodynamics; Dislikes General Biology; Branch is Computer Science; Part of CRUx the best club on campus; Interseted in Math, etc.)", | ||
) | ||
memory_old: Optional[str] = Field( | ||
None, | ||
description="If updating or deleting memory record, the complete, exact phrase that needs to be modified", | ||
) | ||
category: Category = Field(..., description="The category of the memory") | ||
action: Action = Field( | ||
..., | ||
description="Whether this memory is adding a new record, updating a record, or deleting a record", | ||
) | ||
|
||
|
||
def parse_memory(memory: AddMemory): | ||
raise NotImplementedError("This function is not yet implemented") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
You are a supervisor managing a team of knowledge experts. | ||
|
||
Your team's job is to create a perfect knowledge base about a users - {user_id} college campus related likes, dislikes habits etc. to assist in highly personalized interactions with the user. | ||
|
||
The knowledge base should ultimately consist of many discrete pieces of information that add up to a rich persona (e.g. I like the course CSF111; I hate General Bilogy; I am part of CRUx the coding club of the campus; Pursuing a Computer Science degree; Hate eating in the mess; etc). | ||
|
||
Every time you receive a message, you will evaluate if it has any information worth recording in the knowledge base. | ||
|
||
A message may contain multiple pieces of information that should be saved separately. | ||
|
||
The users id is {user_id}. | ||
|
||
You are only interested in the following categories of information: | ||
|
||
1. Course prefereces or likes - The user likes or is interested in a course. | ||
2. Course dislikes - The user dislikes a course. | ||
3. Branch - The branch the user is pursuing in college including majors and minors. | ||
4. Clubs - The clubs the user is part of on campus. | ||
5. Personal attributes - Any personal information that the user provides. (e.g. Campus eating habits, Campus sports, Fests etc.). Keep this limited to the context of the campus. | ||
|
||
When you receive a message, you perform a sequence of steps consisting of: | ||
|
||
1. Analyze the most recent Human message for information. You will see multiple messages for context, but we are only looking for new information in the most recent message. | ||
2. Compare this to the knowledge you already have. | ||
3. Determine if this is new knowledge, an update to old knowledge that now needs to change, or should result in deleting information that is not correct. It's possible that a product/brand you previously wrote as a dislike might now be a like, and other cases- those examples would require an update. | ||
4. Never save the same information twice. If you see the same information in a message that you have already saved, ignore it. | ||
5. Refer to the history for existing memories. | ||
|
||
Here are the existing bits of information that we have about the user. | ||
|
||
{memories} | ||
|
||
Call the right tools to save the information, then respond with DONE. If you identiy multiple pieces of information, call everything at once. You only have one chance to call tools. | ||
|
||
I will tip you $20 if you are perfect, and I will fine you $40 if you miss any important information or change any incorrect information. | ||
|
||
Take a deep breath, think step by step, and then analyze the following message: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import os | ||
|
||
import psycopg2 | ||
from dotenv import load_dotenv | ||
from langchain.tools import StructuredTool | ||
|
||
from src.memory.data import AddMemory | ||
|
||
load_dotenv() | ||
|
||
conn = psycopg2.connect( | ||
dbname=os.getenv("POSTGRES_DB"), | ||
user=os.getenv("POSTGRES_USER"), | ||
password=os.getenv("POSTGRES_PASS"), | ||
host=os.getenv("POSTGRES_HOST"), | ||
port=os.getenv("POSTGRES_PORT"), | ||
) | ||
|
||
|
||
def modify_memory( | ||
id: str, memory: str, category: str, action: str, memory_old: str = None | ||
): | ||
""" | ||
Function to modify memory in the database | ||
""" | ||
print(f"Modifying long term memory for {id} with action {action}") | ||
cur = conn.cursor() | ||
cur.execute( | ||
""" | ||
CREATE TABLE IF NOT EXISTS longterm_memory ( | ||
id VARCHAR(255) NOT NULL, | ||
memory VARCHAR(255) NOT NULL, | ||
category VARCHAR(255) NOT NULL | ||
); | ||
""" | ||
) | ||
if action == "Create": | ||
cur.execute( | ||
f""" | ||
INSERT INTO longterm_memory (id, memory, category) | ||
VALUES ('{id}', '{memory}', '{category}'); | ||
""" | ||
) | ||
conn.commit() | ||
return "Memory created successfully" | ||
elif action == "Update": | ||
cur.execute( | ||
f""" | ||
UPDATE longterm_memory | ||
SET memory = '{memory}' | ||
WHERE id = '{id}' AND memory = '{memory_old}'; | ||
""" | ||
) | ||
conn.commit() | ||
return "Memory updated successfully" | ||
elif action == "Delete": | ||
cur.execute( | ||
f""" | ||
DELETE FROM longterm_memory | ||
WHERE id = '{id}' AND memory = '{memory_old}' AND category = '{category}'; | ||
""" | ||
) | ||
conn.commit() | ||
return "Memory deleted successfully" | ||
else: | ||
return "Invalid action" | ||
|
||
|
||
tool_modify_memory = StructuredTool.from_function( | ||
func=modify_memory, | ||
name="modify_memory", | ||
description="Modify the long term memory of a user", | ||
args_schema=AddMemory, | ||
) |