format and linting (#18)

* Makefile and format

* fix podcast stuff

* refactor: update import statement for transcript_parser in podcast_runner.py

* format and linting

* chore: Update import statements and remove unused code in maintenance module
This commit is contained in:
Daniel Chalef 2024-08-22 12:26:13 -07:00 committed by GitHub
parent 63b9790026
commit 50da9d0f31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 282 additions and 239 deletions

30
Makefile Normal file
View File

@ -0,0 +1,30 @@
.PHONY: install format lint test all check
# Define variables
PYTHON = python3
POETRY = poetry
PYTEST = $(POETRY) run pytest
RUFF = $(POETRY) run ruff
# Default target
all: format lint test
# Install dependencies
install:
$(POETRY) install --with dev
# Format code
format:
$(POETRY) run ruff check --select I --fix
$(POETRY) run ruff format
# Lint code
lint:
$(POETRY) run ruff check
# Run tests
test:
$(POETRY) run pytest
# Run format, lint, and test
check: format lint test

View File

@ -47,4 +47,4 @@ graphiti.close()
## License
(Add license information)
(Add license information)

View File

@ -6,8 +6,8 @@ Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 0.x | :white_check_mark: |
|---------|--------------------|
| 0.x | :white_check_mark: |
## Reporting a Vulnerability

View File

@ -1,5 +1,5 @@
import sys
import os
import sys
# This code adds the project root directory to the Python path, allowing imports to work correctly when running tests.
# Without this file, you might encounter ModuleNotFoundError when trying to import modules from your project, especially when running tests.

View File

@ -1,10 +1,11 @@
import logging
from abc import ABC, abstractmethod
from pydantic import BaseModel, Field
from datetime import datetime
from time import time
from neo4j import AsyncDriver
from uuid import uuid4
import logging
from neo4j import AsyncDriver
from pydantic import BaseModel, Field
from core.llm_client.config import EMBEDDING_DIM
from core.nodes import Node

View File

@ -1,29 +1,34 @@
import asyncio
from datetime import datetime
import logging
from typing import Callable
from neo4j import AsyncGraphDatabase
from dotenv import load_dotenv
from time import time
import os
from datetime import datetime
from time import time
from typing import Callable
from dotenv import load_dotenv
from neo4j import AsyncGraphDatabase
from core.nodes import EntityNode, EpisodicNode
from core.edges import EntityEdge, EpisodicEdge
from core.llm_client import LLMClient, LLMConfig, OpenAIClient
from core.nodes import EntityNode, EpisodicNode
from core.search.search import SearchConfig, hybrid_search
from core.search.search_utils import (
get_relevant_edges,
get_relevant_nodes,
)
from core.utils import (
build_episodic_edges,
retrieve_episodes,
)
from core.llm_client import LLMClient, OpenAIClient, LLMConfig
from core.utils.bulk_utils import (
BulkEpisode,
extract_nodes_and_edges_bulk,
retrieve_previous_episodes_bulk,
dedupe_nodes_bulk,
resolve_edge_pointers,
dedupe_edges_bulk,
dedupe_nodes_bulk,
extract_nodes_and_edges_bulk,
resolve_edge_pointers,
retrieve_previous_episodes_bulk,
)
from core.utils.maintenance.edge_operations import extract_edges, dedupe_extracted_edges
from core.utils.maintenance.edge_operations import dedupe_extracted_edges, extract_edges
from core.utils.maintenance.graph_data_operations import (
EPISODE_WINDOW_LEN,
build_indices_and_constraints,
@ -33,10 +38,6 @@ from core.utils.maintenance.temporal_operations import (
invalidate_edges,
prepare_edges_for_invalidation,
)
from core.search.search_utils import (
get_relevant_nodes,
get_relevant_edges,
)
logger = logging.getLogger(__name__)
@ -90,8 +91,8 @@ class Graphiti:
name: str,
episode_body: str,
source_description: str,
reference_time: datetime,
episode_type="string",
reference_time: datetime | None = None,
episode_type: str | None = "string", # TODO: this field isn't used yet?
success_callback: Callable | None = None,
error_callback: Callable | None = None,
):
@ -249,9 +250,11 @@ class Graphiti:
episode_pairs = await retrieve_previous_episodes_bulk(self.driver, episodes)
# Extract all nodes and edges
extracted_nodes, extracted_edges, episodic_edges = (
await extract_nodes_and_edges_bulk(self.llm_client, episode_pairs)
)
(
extracted_nodes,
extracted_edges,
episodic_edges,
) = await extract_nodes_and_edges_bulk(self.llm_client, episode_pairs)
# Generate embeddings
await asyncio.gather(

View File

@ -1,5 +1,5 @@
from .client import LLMClient
from .openai_client import OpenAIClient
from .config import LLMConfig
from .openai_client import OpenAIClient
__all__ = ["LLMClient", "OpenAIClient", "LLMConfig"]

View File

@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
from .config import LLMConfig

View File

@ -1,10 +1,11 @@
import json
import logging
from openai import AsyncOpenAI
from .client import LLMClient
from .config import LLMConfig
import logging
logger = logging.getLogger(__name__)

View File

@ -1,12 +1,12 @@
import logging
from abc import ABC, abstractmethod
from time import time
from datetime import datetime
from time import time
from uuid import uuid4
from neo4j import AsyncDriver
from openai import OpenAI
from pydantic import BaseModel, Field
from neo4j import AsyncDriver
import logging
from core.llm_client.config import EMBEDDING_DIM

View File

@ -1,7 +1,7 @@
import json
from typing import TypedDict, Protocol
from typing import Protocol, TypedDict
from .models import Message, PromptVersion, PromptFunction
from .models import Message, PromptFunction, PromptVersion
class Prompt(Protocol):

View File

@ -1,7 +1,7 @@
import json
from typing import TypedDict, Protocol
from typing import Protocol, TypedDict
from .models import Message, PromptVersion, PromptFunction
from .models import Message, PromptFunction, PromptVersion
class Prompt(Protocol):

View File

@ -1,7 +1,7 @@
import json
from typing import TypedDict, Protocol
from typing import Protocol, TypedDict
from .models import Message, PromptVersion, PromptFunction
from .models import Message, PromptFunction, PromptVersion
class Prompt(Protocol):
@ -14,62 +14,6 @@ class Versions(TypedDict):
v2: PromptFunction
def v1(context: dict[str, any]) -> list[Message]:
return [
Message(
role="system",
content="You are a helpful assistant that extracts graph edges from provided context.",
),
Message(
role="user",
content=f"""
Given the following context, extract new semantic edges (relationships) that need to be added to the knowledge graph:
Current Graph Structure:
{context['relevant_schema']}
New Nodes:
{json.dumps(context['new_nodes'], indent=2)}
New Episode:
Content: {context['episode_content']}
Timestamp: {context['episode_timestamp']}
Previous Episodes:
{json.dumps([ep['content'] for ep in context['previous_episodes']], indent=2)}
Extract new semantic edges based on the content of the current episode, considering the existing graph structure, new nodes, and context from previous episodes.
Guidelines:
1. Create edges only between semantic nodes (not episodic nodes like messages).
2. Each edge should represent a clear relationship between two semantic nodes.
3. The relation_type should be a concise, all-caps description of the relationship (e.g., LOVES, IS_FRIENDS_WITH, WORKS_FOR).
4. Provide a more detailed fact describing the relationship.
5. If a relationship seems to update an existing one, create a new edge with the updated information.
6. Consider temporal aspects of relationships when relevant.
7. Do not create edges involving episodic nodes (like Message 1 or Message 2).
8. Use existing nodes from the current graph structure when appropriate.
Respond with a JSON object in the following format:
{{
"new_edges": [
{{
"relation_type": "RELATION_TYPE_IN_CAPS",
"source_node": "Name of the source semantic node",
"target_node": "Name of the target semantic node",
"fact": "Detailed description of the relationship",
"valid_at": "YYYY-MM-DDTHH:MM:SSZ or null if not explicitly mentioned",
"invalid_at": "YYYY-MM-DDTHH:MM:SSZ or null if ongoing or not explicitly mentioned"
}}
]
}}
If no new edges need to be added, return an empty list for "new_edges".
""",
),
]
def v1(context: dict[str, any]) -> list[Message]:
return [
Message(

View File

@ -1,7 +1,7 @@
import json
from typing import TypedDict, Protocol
from typing import Protocol, TypedDict
from .models import Message, PromptVersion, PromptFunction
from .models import Message, PromptFunction, PromptVersion
class Prompt(Protocol):

View File

@ -1,5 +1,6 @@
from typing import Protocol, TypedDict
from .models import Message, PromptVersion, PromptFunction
from .models import Message, PromptFunction, PromptVersion
class Prompt(Protocol):

View File

@ -1,36 +1,51 @@
from typing import TypedDict, Protocol
from .models import Message, PromptFunction
from typing import TypedDict, Protocol
from .models import Message, PromptFunction
from .extract_nodes import (
Prompt as ExtractNodesPrompt,
Versions as ExtractNodesVersions,
versions as extract_nodes_versions,
)
from .dedupe_nodes import (
Prompt as DedupeNodesPrompt,
Versions as DedupeNodesVersions,
versions as dedupe_nodes_versions,
)
from .extract_edges import (
Prompt as ExtractEdgesPrompt,
Versions as ExtractEdgesVersions,
versions as extract_edges_versions,
)
from typing import Protocol, TypedDict
from .dedupe_edges import (
Prompt as DedupeEdgesPrompt,
)
from .dedupe_edges import (
Versions as DedupeEdgesVersions,
)
from .dedupe_edges import (
versions as dedupe_edges_versions,
)
from .dedupe_nodes import (
Prompt as DedupeNodesPrompt,
)
from .dedupe_nodes import (
Versions as DedupeNodesVersions,
)
from .dedupe_nodes import (
versions as dedupe_nodes_versions,
)
from .extract_edges import (
Prompt as ExtractEdgesPrompt,
)
from .extract_edges import (
Versions as ExtractEdgesVersions,
)
from .extract_edges import (
versions as extract_edges_versions,
)
from .extract_nodes import (
Prompt as ExtractNodesPrompt,
)
from .extract_nodes import (
Versions as ExtractNodesVersions,
)
from .extract_nodes import (
versions as extract_nodes_versions,
)
from .invalidate_edges import (
Prompt as InvalidateEdgesPrompt,
)
from .invalidate_edges import (
Versions as InvalidateEdgesVersions,
)
from .invalidate_edges import (
versions as invalidate_edges_versions,
)
from .models import Message, PromptFunction
class PromptLibrary(Protocol):

View File

@ -1,4 +1,3 @@
import asyncio
import logging
from datetime import datetime
from time import time
@ -6,12 +5,12 @@ from time import time
from neo4j import AsyncDriver
from pydantic import BaseModel
from core.edges import EntityEdge, Edge
from core.edges import Edge
from core.llm_client.config import EMBEDDING_DIM
from core.nodes import Node
from core.search.search_utils import (
edge_similarity_search,
edge_fulltext_search,
edge_similarity_search,
get_mentioned_nodes,
rrf,
)

View File

@ -73,7 +73,7 @@ async def bfs(node_ids: list[str], driver: AsyncDriver):
for record in records:
n_uuid = record["source_node_uuid"]
if n_uuid in context.keys():
if n_uuid in context:
context[n_uuid]["facts"].append(record["fact"])
else:
context[n_uuid] = {

View File

@ -1,8 +1,8 @@
from .maintenance import (
extract_new_edges,
build_episodic_edges,
extract_new_nodes,
clear_data,
extract_new_edges,
extract_new_nodes,
retrieve_episodes,
)

View File

@ -4,23 +4,23 @@ from datetime import datetime
from neo4j import AsyncDriver
from pydantic import BaseModel
from core.edges import EpisodicEdge, EntityEdge, Edge
from core.edges import Edge, EntityEdge, EpisodicEdge
from core.llm_client import LLMClient
from core.nodes import EpisodicNode, EntityNode
from core.nodes import EntityNode, EpisodicNode
from core.search.search_utils import get_relevant_edges, get_relevant_nodes
from core.utils import retrieve_episodes
from core.utils.maintenance.edge_operations import (
extract_edges,
build_episodic_edges,
dedupe_edge_list,
dedupe_extracted_edges,
extract_edges,
)
from core.utils.maintenance.graph_data_operations import EPISODE_WINDOW_LEN
from core.utils.maintenance.node_operations import (
extract_nodes,
dedupe_node_list,
dedupe_extracted_nodes,
dedupe_node_list,
extract_nodes,
)
from core.search.search_utils import get_relevant_nodes, get_relevant_edges
CHUNK_SIZE = 10
@ -59,9 +59,10 @@ async def extract_nodes_and_edges_bulk(
]
)
episodes, previous_episodes_list = [episode[0] for episode in episode_tuples], [
episode[1] for episode in episode_tuples
]
episodes, previous_episodes_list = (
[episode[0] for episode in episode_tuples],
[episode[1] for episode in episode_tuples],
)
extracted_edges_bulk = await asyncio.gather(
*[

View File

@ -1,9 +1,10 @@
from .edge_operations import extract_new_edges, build_episodic_edges
from .node_operations import extract_new_nodes
from .edge_operations import build_episodic_edges, extract_new_edges
from .graph_data_operations import (
clear_data,
retrieve_episodes,
)
from .node_operations import extract_new_nodes
from .temporal_operations import invalidate_edges
__all__ = [
"extract_new_edges",

View File

@ -1,16 +1,13 @@
import json
from typing import List
import logging
from datetime import datetime
from time import time
from typing import List
from pydantic import BaseModel
from core.nodes import EntityNode, EpisodicNode
from core.edges import EpisodicEdge, EntityEdge
import logging
from core.prompts import prompt_library
from core.edges import EntityEdge, EpisodicEdge
from core.llm_client import LLMClient
from core.nodes import EntityNode, EpisodicNode
from core.prompts import prompt_library
logger = logging.getLogger(__name__)
@ -206,7 +203,7 @@ async def dedupe_extracted_edges(
for edge in existing_edges:
edge_map[edge.fact] = edge
for edge in extracted_edges:
if edge.fact in edge_map.keys():
if edge.fact in edge_map:
continue
edge_map[edge.fact] = edge

View File

@ -1,10 +1,11 @@
import asyncio
import logging
from datetime import datetime, timezone
from typing import LiteralString
from core.nodes import EpisodicNode
from neo4j import AsyncDriver
import logging
from core.nodes import EpisodicNode
EPISODE_WINDOW_LEN = 3

View File

@ -1,10 +1,9 @@
import logging
from datetime import datetime
from time import time
from core.nodes import EntityNode, EpisodicNode
import logging
from core.llm_client import LLMClient
from core.nodes import EntityNode, EpisodicNode
from core.prompts import prompt_library
logger = logging.getLogger(__name__)

View File

@ -1,10 +1,11 @@
import logging
from datetime import datetime
from typing import List
from core.llm_client import LLMClient
from core.edges import EntityEdge
from core.llm_client import LLMClient
from core.nodes import EntityNode
from core.prompts import prompt_library
import logging
logger = logging.getLogger(__name__)
@ -16,8 +17,8 @@ def prepare_edges_for_invalidation(
new_edges: list[EntityEdge],
nodes: list[EntityNode],
) -> tuple[list[NodeEdgeNodeTriplet], list[NodeEdgeNodeTriplet]]:
existing_edges_pending_invalidation = []
new_edges_with_nodes = []
existing_edges_pending_invalidation = [] # TODO: this is not yet used?
new_edges_with_nodes = [] # TODO: this is not yet used?
existing_edges_pending_invalidation = []
new_edges_with_nodes = []
@ -45,7 +46,7 @@ async def invalidate_edges(
existing_edges_pending_invalidation: List[NodeEdgeNodeTriplet],
new_edges: List[NodeEdgeNodeTriplet],
) -> List[EntityEdge]:
invalidated_edges = []
invalidated_edges = [] # TODO: this is not yet used?
context = prepare_invalidation_context(
existing_edges_pending_invalidation, new_edges

View File

@ -1,9 +1,7 @@
import logging
from neo4j import AsyncDriver
from core.edges import EpisodicEdge, EntityEdge, Edge
from core.nodes import EntityNode, EpisodicNode, Node
from core.edges import EpisodicEdge
from core.nodes import EntityNode, EpisodicNode
logger = logging.getLogger(__name__)

View File

@ -1,12 +1,14 @@
import asyncio
import logging
import os
import sys
from dotenv import load_dotenv
from core import Graphiti
from core.utils.bulk_utils import BulkEpisode
from core.utils.maintenance.graph_data_operations import clear_data
from dotenv import load_dotenv
import os
import asyncio
import logging
import sys
from transcript_parser import parse_podcast_messages
from examples.podcast.transcript_parser import parse_podcast_messages
load_dotenv()

View File

@ -1,8 +1,9 @@
import os
import re
from datetime import datetime, timedelta
import os
from typing import List, Optional
from pydantic import BaseModel, Field
from typing import List
from pydantic import BaseModel
class Speaker(BaseModel):
@ -38,7 +39,7 @@ def parse_timestamp(timestamp: str) -> timedelta:
def parse_conversation_file(
file_path: str, speakers: List[Speaker]
) -> list[ParsedMessage]:
with open(file_path, "r") as file:
with open(file_path) as file:
content = file.read()
messages = content.split("\n\n")

View File

@ -1,12 +1,14 @@
import asyncio
import logging
import os
import sys
from dotenv import load_dotenv
from core import Graphiti
from core.utils.bulk_utils import BulkEpisode
from core.utils.maintenance.graph_data_operations import clear_data
from dotenv import load_dotenv
import os
import asyncio
import logging
import sys
from transcript_parser import parse_podcast_messages
from examples.podcast.transcript_parser import parse_podcast_messages
load_dotenv()

114
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]]
name = "annotated-types"
@ -820,6 +820,7 @@ description = "Nvidia JIT LTO Library"
optional = false
python-versions = ">=3"
files = [
{file = "nvidia_nvjitlink_cu12-12.6.20-py3-none-manylinux2014_aarch64.whl", hash = "sha256:84fb38465a5bc7c70cbc320cfd0963eb302ee25a5e939e9f512bbba55b6072fb"},
{file = "nvidia_nvjitlink_cu12-12.6.20-py3-none-manylinux2014_x86_64.whl", hash = "sha256:562ab97ea2c23164823b2a89cb328d01d45cb99634b8c65fe7cd60d14562bd79"},
{file = "nvidia_nvjitlink_cu12-12.6.20-py3-none-win_amd64.whl", hash = "sha256:ed3c43a17f37b0c922a919203d2d36cbef24d41cc3e6b625182f8b58203644f6"},
]
@ -837,13 +838,13 @@ files = [
[[package]]
name = "openai"
version = "1.41.1"
version = "1.42.0"
description = "The official Python library for the openai API"
optional = false
python-versions = ">=3.7.1"
files = [
{file = "openai-1.41.1-py3-none-any.whl", hash = "sha256:56fb04105263f79559aff3ceea2e1dd16f8c5385e8238cb66cf0e6888fa8bfcf"},
{file = "openai-1.41.1.tar.gz", hash = "sha256:e38e376efd91e0d4db071e2a6517b6b4cac1c2a6fd63efdc5ec6be10c5967c1b"},
{file = "openai-1.42.0-py3-none-any.whl", hash = "sha256:dc91e0307033a4f94931e5d03cc3b29b9717014ad5e73f9f2051b6cb5eda4d80"},
{file = "openai-1.42.0.tar.gz", hash = "sha256:c9d31853b4e0bc2dc8bd08003b462a006035655a701471695d0bfdc08529cde3"},
]
[package.dependencies]
@ -1375,6 +1376,33 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "ruff"
version = "0.6.2"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"},
{file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"},
{file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"},
{file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"},
{file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"},
{file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"},
{file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"},
{file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"},
{file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"},
{file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"},
{file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"},
{file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"},
]
[[package]]
name = "safetensors"
version = "0.4.4"
@ -1554,36 +1582,44 @@ tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (
[[package]]
name = "scipy"
version = "1.14.0"
version = "1.14.1"
description = "Fundamental algorithms for scientific computing in Python"
optional = false
python-versions = ">=3.10"
files = [
{file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"},
{file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"},
{file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"},
{file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"},
{file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"},
{file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"},
{file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"},
{file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"},
{file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"},
{file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"},
{file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"},
{file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"},
{file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"},
{file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"},
{file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"},
{file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"},
{file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"},
{file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"},
{file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"},
{file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"},
{file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"},
{file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"},
{file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"},
{file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"},
{file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"},
{file = "scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389"},
{file = "scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3"},
{file = "scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0"},
{file = "scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3"},
{file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d"},
{file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69"},
{file = "scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad"},
{file = "scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5"},
{file = "scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675"},
{file = "scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2"},
{file = "scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617"},
{file = "scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8"},
{file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37"},
{file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2"},
{file = "scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2"},
{file = "scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94"},
{file = "scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d"},
{file = "scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07"},
{file = "scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5"},
{file = "scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc"},
{file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310"},
{file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066"},
{file = "scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1"},
{file = "scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f"},
{file = "scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79"},
{file = "scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e"},
{file = "scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73"},
{file = "scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e"},
{file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d"},
{file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e"},
{file = "scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06"},
{file = "scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84"},
{file = "scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417"},
]
[package.dependencies]
@ -1591,8 +1627,8 @@ numpy = ">=1.23.5,<2.3"
[package.extras]
dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"]
doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"]
test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<=7.3.7)", "sphinx-design (>=0.4.0)"]
test = ["Cython", "array-api-strict (>=2.0)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
[[package]]
name = "sentence-transformers"
@ -1889,13 +1925,13 @@ telegram = ["requests"]
[[package]]
name = "transformers"
version = "4.44.0"
version = "4.44.2"
description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
optional = false
python-versions = ">=3.8.0"
files = [
{file = "transformers-4.44.0-py3-none-any.whl", hash = "sha256:ea0ff72def71e9f4812d9414d4803b22681b1617aa6f511bd51cfff2b44a6fca"},
{file = "transformers-4.44.0.tar.gz", hash = "sha256:75699495e30b7635ca444d8d372e138c687ab51a875b387e33f1fb759c37f196"},
{file = "transformers-4.44.2-py3-none-any.whl", hash = "sha256:1c02c65e7bfa5e52a634aff3da52138b583fc6f263c1f28d547dc144ba3d412d"},
{file = "transformers-4.44.2.tar.gz", hash = "sha256:36aa17cc92ee154058e426d951684a2dab48751b35b49437896f898931270826"},
]
[package.dependencies]
@ -1984,13 +2020,13 @@ tutorials = ["matplotlib", "pandas", "tabulate"]
[[package]]
name = "types-python-dateutil"
version = "2.9.0.20240316"
version = "2.9.0.20240821"
description = "Typing stubs for python-dateutil"
optional = false
python-versions = ">=3.8"
files = [
{file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"},
{file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"},
{file = "types-python-dateutil-2.9.0.20240821.tar.gz", hash = "sha256:9649d1dcb6fef1046fb18bebe9ea2aa0028b160918518c34589a46045f6ebd98"},
{file = "types_python_dateutil-2.9.0.20240821-py3-none-any.whl", hash = "sha256:f5889fcb4e63ed4aaa379b44f93c32593d50b9a94c9a60a0c854d8cc3511cd57"},
]
[[package]]
@ -2024,4 +2060,4 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "2e970107c418996daa61e9eee243448bd7ef4ba2af28e238c84a94f51f23f02e"
content-hash = "6fe70d655969fb1eed770fee77017f145de7a5bf8964bc60c4ec2946e906cf96"

View File

@ -14,11 +14,16 @@ sentence-transformers = "^3.0.1"
diskcache = "^5.6.3"
arrow = "^1.3.0"
openai = "^1.38.0"
[tool.poetry.dev-dependencies]
pytest = "^8.3.2"
python-dotenv = "^1.0.1"
pytest-asyncio = "^0.23.8"
pytest-xdist = "^3.6.1"
pytest = "^8.3.2"
ruff = "^0.6.2"
[tool.poetry.group.dev.dependencies]
pydantic = "^2.8.2"
[build-system]
requires = ["poetry-core"]

View File

@ -1,11 +1,13 @@
from core import Graphiti
from core.utils.maintenance.graph_data_operations import clear_data
from dotenv import load_dotenv
import os
import asyncio
import logging
import os
import sys
from dotenv import load_dotenv
from core import Graphiti
from core.utils.maintenance.graph_data_operations import clear_data
load_dotenv()
neo4j_uri = os.environ.get("NEO4J_URI") or "bolt://localhost:7687"

View File

@ -1,25 +1,24 @@
import logging
import sys
import os
import sys
import pytest
from core.search.search import SearchConfig
pytestmark = pytest.mark.integration
import asyncio
from dotenv import load_dotenv
from datetime import datetime
from dotenv import load_dotenv
from neo4j import AsyncGraphDatabase
from openai import OpenAI
from core.edges import EpisodicEdge, EntityEdge
from core.edges import EntityEdge, EpisodicEdge
from core.graphiti import Graphiti
from core.llm_client.config import EMBEDDING_DIM
from core.nodes import EpisodicNode, EntityNode
from datetime import datetime
from core.nodes import EntityNode, EpisodicNode
pytestmark = pytest.mark.integration
pytest_plugins = ("pytest_asyncio",)

View File

@ -1,11 +1,13 @@
import pytest
from datetime import datetime, timedelta
import pytest
from core.edges import EntityEdge
from core.nodes import EntityNode
from core.utils.maintenance.temporal_operations import (
prepare_edges_for_invalidation,
prepare_invalidation_context,
)
from core.edges import EntityEdge
from core.nodes import EntityNode
# Helper function to create test data

View File

@ -1,14 +1,15 @@
import pytest
import os
from datetime import datetime, timedelta
import pytest
from dotenv import load_dotenv
from core.edges import EntityEdge
from core.llm_client import LLMConfig, OpenAIClient
from core.nodes import EntityNode
from core.utils.maintenance.temporal_operations import (
invalidate_edges,
)
from core.edges import EntityEdge
from core.nodes import EntityNode
from core.llm_client import OpenAIClient, LLMConfig
from dotenv import load_dotenv
import os
load_dotenv()