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

falkor-integration #2

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
41eeccd
falkor-integration
Sep 10, 2024
3bd49b5
Feature: milvus db integration (#1821)
ketangangal Sep 10, 2024
e3aca70
chore: version -> `0.1.12` (#1846)
Dev-Khant Sep 10, 2024
db835cd
Update README.md (#1847)
deshraj Sep 10, 2024
5eeeb4e
Fixing memory adding errors (#1848)
PranavPuranik Sep 10, 2024
ac7b7aa
Added custom prompt support (#1849)
prateekchhikara Sep 10, 2024
6c3d44b
fix-example
Sep 11, 2024
ca95bed
database-config-val
Sep 11, 2024
f40a2e7
Add CONTRIBUTING.md (#1836)
techcontributor Sep 11, 2024
47a8e67
Fixed environment variables priority in OpenAILLM (#1851)
FoliageOwO Sep 12, 2024
f9634b4
add test cases for embeddings (#1829)
reachAnushaKondam Sep 13, 2024
959f4bb
Add Support for Vertex AI Embeddings (#1840)
Divyanshu9822 Sep 13, 2024
d66654b
Add API-Reference docs for Organization/Project (#1858)
Dev-Khant Sep 14, 2024
dc5a26f
Update docs for exisiting APIs to support organization/project (#1859)
Dev-Khant Sep 14, 2024
8e2f7f2
Shows all responses in api-reference (#1865)
Dev-Khant Sep 14, 2024
5b9be67
Migrate session_id -> run_id (#1864)
Dev-Khant Sep 16, 2024
30edf49
chore: version -> 0.1.14 (#1869)
Dev-Khant Sep 16, 2024
3502344
Remove auto install library for chromadb (#1870)
Dev-Khant Sep 16, 2024
0a78cb9
added vector store test cases (#1868)
reachAnushaKondam Sep 16, 2024
55c54be
[Misc] Lint code and fix code smells (#1871)
deshraj Sep 17, 2024
495a66d
gen-graph-use
Sep 17, 2024
19db2cc
def-databasename
Sep 17, 2024
7f3b23d
update-docs
Sep 17, 2024
8c3c9e1
Docs update (#1875)
prateekchhikara Sep 17, 2024
fc88cae
update milvus docs (#1876)
Dev-Khant Sep 17, 2024
07de1c4
update-graph-use
Sep 18, 2024
12da12d
local-pas
Sep 18, 2024
852220a
Merge branch 'main' into falkor-int
galshubeli Sep 18, 2024
9a49aa8
comment-graph-query
Oct 10, 2024
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
34 changes: 34 additions & 0 deletions cookbooks/mem0_graph_memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
import sys
from dotenv import load_dotenv
sys.path.append(os.getcwd())
from mem0 import Memory
load_dotenv()

config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4o-mini",
"temperature": 0
}
},
"graph_store": {
"provider": "falkordb",
"config": {
"database": "falkordb",
"host": os.environ['HOST'],
"username": os.environ['USERNAME'],
"password": os.environ['PASSWORD'],
"port": os.environ['PORT']
}
},
"version": "v1.1"
}

m = Memory.from_config(config_dict=config)

user_id = "alice123"
m.add("I like painting", user_id=user_id)
m.add("I hate playing badminton", user_id=user_id)
m.add("My friend name is john and john has a dog named tommy", user_id='gal')
10 changes: 6 additions & 4 deletions docs/open-source/graph_memory/features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ from mem0 import Memory

config = {
"graph_store": {
"provider": "neo4j",
"provider": "falkordb",
"config": {
"url": "neo4j+s://xxx",
"username": "neo4j",
"password": "xxx"
"Database": "falkordb",
"host": "---"
"username": "---",
"password": "---",
"port": "---"
},
"custom_prompt": "Please only extract entities containing sports related relationships and nothing else.",
},
Expand Down
22 changes: 13 additions & 9 deletions docs/open-source/graph_memory/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ allowfullscreen
## Initialize Graph Memory

To initialize Graph Memory you'll need to set up your configuration with graph store providers.
Currently, we support Neo4j as a graph store provider. You can setup [Neo4j](https://neo4j.com/) locally or use the hosted [Neo4j AuraDB](https://neo4j.com/product/auradb/).
Currently, we support FalkorDB and Neo4j as a graph store providers. You can setup [FalkorDB](https://www.falkordb.com/) or [Neo4j](https://neo4j.com/) locally or use the hosted [FalkorDB Cloud](https://app.falkordb.cloud/) or [Neo4j AuraDB](https://neo4j.com/product/auradb/).
Moreover, you also need to set the version to `v1.1` (*prior versions are not supported*).

User can also customize the LLM for Graph Memory from the [Supported LLM list](https://docs.mem0.ai/components/llms/overview) with three levels of configuration:
Expand All @@ -44,11 +44,13 @@ from mem0 import Memory

config = {
"graph_store": {
"provider": "neo4j",
"provider": "falkordb",
"config": {
"url": "neo4j+s://xxx",
"username": "neo4j",
"password": "xxx"
"Database": "falkordb",
"host": "---"
"username": "---",
"password": "---",
"port": "---"
}
},
"version": "v1.1"
Expand All @@ -70,11 +72,13 @@ config = {
}
},
"graph_store": {
"provider": "neo4j",
"provider": "falkordb",
"config": {
"url": "neo4j+s://xxx",
"username": "neo4j",
"password": "xxx"
"Database": "falkordb",
"host": "---"
"username": "---",
"password": "---",
"port": "---"
},
"llm" : {
"provider": "openai",
Expand Down
10 changes: 6 additions & 4 deletions docs/open-source/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,13 @@ from mem0 import Memory

config = {
"graph_store": {
"provider": "neo4j",
"provider": "falkordb",
"config": {
"url": "neo4j+s://---",
"username": "neo4j",
"password": "---"
"Database": "falkordb",
"host": "---"
"username": "---",
"password": "---",
"port": "---"
}
},
"version": "v1.1"
Expand Down
30 changes: 27 additions & 3 deletions mem0/graphs/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,36 @@ def check_host_port_or_path(cls, values):
"Please provide 'url', 'username' and 'password'."
)
return values

class FalkorDBConfig(BaseModel):
database: Optional[str] = Field(None, description="Database name for the graph database")
host: Optional[str] = Field(None, description="Host address for the graph database")
username: Optional[str] = Field(None, description="Username for the graph database")
password: Optional[str] = Field(None, description="Password for the graph database")
port: Optional[int] = Field(None, description="Port for the graph database")

@model_validator(mode="before")
def check_host_port_or_path(cls, values):
database, host, username, password, port = (
values.get("database"),
values.get("host"),
values.get("username"),
values.get("password"),
galshubeli marked this conversation as resolved.
Show resolved Hide resolved
values.get("port"),
)
if not database or not host or not username or not password or not port:
raise ValueError(
"Please provide 'host', 'username', 'password' and 'port'."
)
return values


class GraphStoreConfig(BaseModel):
provider: str = Field(
description="Provider of the data store (e.g., 'neo4j')",
default="neo4j"
description="Provider of the data store (e.g., 'falkordb', 'neo4j')",
default="falkordb"
)
config: Neo4jConfig = Field(
config: FalkorDBConfig = Field(
description="Configuration for the specific data store",
default=None
)
Expand All @@ -47,6 +69,8 @@ def validate_config(cls, v, values):
provider = values.data.get("provider")
if provider == "neo4j":
return Neo4jConfig(**v.model_dump())
elif provider == "falkordb":
return FalkorDBConfig(**v.model_dump())
else:
raise ValueError(f"Unsupported graph store provider: {provider}")

38 changes: 28 additions & 10 deletions mem0/memory/graph_memory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging

from langchain_community.graphs import Neo4jGraph
from rank_bm25 import BM25Okapi

from mem0.graphs.tools import (
Expand All @@ -16,14 +15,16 @@
SEARCH_STRUCT_TOOL
)
from mem0.graphs.utils import EXTRACT_ENTITIES_PROMPT, get_update_memory_messages
from mem0.utils.factory import EmbedderFactory, LlmFactory
from mem0.utils.factory import EmbedderFactory, LlmFactory, GraphFactory

logger = logging.getLogger(__name__)

class MemoryGraph:
def __init__(self, config):
self.config = config
self.graph = Neo4jGraph(self.config.graph_store.config.url, self.config.graph_store.config.username, self.config.graph_store.config.password)
self.graph = GraphFactory.create(
self.config.graph_store.provider, self.config.graph_store.config
)
self.embedding_model = EmbedderFactory.create(
self.config.embedder.provider, self.config.embedder.config
)
Expand Down Expand Up @@ -138,7 +139,7 @@ def add(self, data, filters):
"user_id": filters["user_id"]
}

_ = self.graph.query(cypher, params=params)
_ = self.graph_query(cypher, params=params)

logger.info(f"Added {len(to_be_added)} new memories to the graph")

Expand Down Expand Up @@ -202,7 +203,7 @@ def _search(self, query, filters):
ORDER BY similarity DESC
"""
params = {"n_embedding": n_embedding, "threshold": self.threshold, "user_id": filters["user_id"]}
ans = self.graph.query(cypher_query, params=params)
ans = self.graph_query(cypher_query, params=params)
result_relations.extend(ans)

return result_relations
Expand Down Expand Up @@ -252,7 +253,7 @@ def delete_all(self, filters):
DETACH DELETE n
"""
params = {"user_id": filters["user_id"]}
self.graph.query(cypher, params=params)
self.graph_query(cypher, params=params)


def get_all(self, filters):
Expand All @@ -272,7 +273,7 @@ def get_all(self, filters):
MATCH (n {user_id: $user_id})-[r]->(m {user_id: $user_id})
RETURN n.name AS source, type(r) AS relationship, m.name AS target
"""
results = self.graph.query(query, params={"user_id": filters["user_id"]})
results = self.graph_query(query, params={"user_id": filters["user_id"]})

final_results = []
for result in results:
Expand Down Expand Up @@ -309,22 +310,39 @@ def _update_relationship(self, source, target, relationship, filters):
MERGE (n1 {name: $source, user_id: $user_id})
MERGE (n2 {name: $target, user_id: $user_id})
"""
self.graph.query(check_and_create_query, params={"source": source, "target": target, "user_id": filters["user_id"]})
self.graph_query(check_and_create_query, params={"source": source, "target": target, "user_id": filters["user_id"]})

# Delete any existing relationship between the nodes
delete_query = """
MATCH (n1 {name: $source, user_id: $user_id})-[r]->(n2 {name: $target, user_id: $user_id})
DELETE r
"""
self.graph.query(delete_query, params={"source": source, "target": target, "user_id": filters["user_id"]})
self.graph_query(delete_query, params={"source": source, "target": target, "user_id": filters["user_id"]})

# Create the new relationship
create_query = f"""
MATCH (n1 {{name: $source, user_id: $user_id}}), (n2 {{name: $target, user_id: $user_id}})
CREATE (n1)-[r:{relationship}]->(n2)
RETURN n1, r, n2
"""
result = self.graph.query(create_query, params={"source": source, "target": target, "user_id": filters["user_id"]})
result = self.graph_query(create_query, params={"source": source, "target": target, "user_id": filters["user_id"]})

if not result:
raise Exception(f"Failed to update or create relationship between {source} and {target}")

def graph_query(self, query, params):
"""
Execute a Cypher query on the graph database.
For FalkorDB, the graph is switched based on the user_id.

Args:
query (str): The Cypher query to execute.
params (dict): A dictionary containing params to be applied during the query.

Returns:
list: A list of dictionaries containing the results of the query.
"""
if self.config.graph_store.provider == "falkordb":
self.graph.switch_graph(params["user_id"])

return self.graph.query(query, params=params)
17 changes: 17 additions & 0 deletions mem0/utils/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,20 @@ def create(cls, provider_name, config):
return vector_store_instance(**config)
else:
raise ValueError(f"Unsupported VectorStore provider: {provider_name}")

class GraphFactory:
provider_to_class = {
"falkordb": "langchain_community.graphs.FalkorDBGraph",
"neo4j": "langchain_community.graphs.Neo4jGraph",
}

@classmethod
def create(cls, provider_name, config):
class_type = cls.provider_to_class.get(provider_name)
if class_type:
if not isinstance(config, dict):
config = config.model_dump()
graph_instance = load_class(class_type)
return graph_instance(**config)
else:
raise ValueError(f"Unsupported graph provider: {provider_name}")
35 changes: 33 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sqlalchemy = "^2.0.31"
langchain-community = "^0.2.12"
neo4j = "^5.23.1"
rank-bm25 = "^0.2.2"
falkordb = "^1.0.8"

[tool.poetry.group.test.dependencies]
pytest = "^8.2.2"
Expand Down