graphiti-core 0.3.19__tar.gz → 0.3.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphiti-core might be problematic. Click here for more details.
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/PKG-INFO +15 -4
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/README.md +13 -2
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/graphiti.py +4 -4
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/helpers.py +1 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/models/edges/edge_db_queries.py +20 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/models/nodes/node_db_queries.py +17 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/search/search.py +6 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/search/search_utils.py +41 -24
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/bulk_utils.py +38 -1
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/pyproject.toml +2 -2
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/LICENSE +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/bge_reranker_client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/openai_reranker_client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/edges.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/embedder/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/embedder/client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/embedder/openai.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/embedder/voyage.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/errors.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/anthropic_client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/config.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/errors.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/groq_client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/openai_client.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/llm_client/utils.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/models/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/models/edges/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/models/nodes/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/nodes.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/dedupe_edges.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/dedupe_nodes.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/eval.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/extract_edge_dates.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/extract_edges.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/extract_nodes.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/invalidate_edges.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/lib.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/models.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/prompts/summarize_nodes.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/py.typed +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/search/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/search/search_config.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/search/search_config_recipes.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/__init__.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/community_operations.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/graph_data_operations.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/node_operations.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
- {graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: graphiti-core
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.21
|
|
4
4
|
Summary: A temporal graph building library
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Author: Paul Paliychuk
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Requires-Dist: diskcache (>=5.6.3,<6.0.0)
|
|
15
15
|
Requires-Dist: neo4j (>=5.23.0,<6.0.0)
|
|
16
16
|
Requires-Dist: numpy (>=1.0.0)
|
|
17
|
-
Requires-Dist: openai (>=1.
|
|
17
|
+
Requires-Dist: openai (>=1.53.0,<2.0.0)
|
|
18
18
|
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
|
19
19
|
Requires-Dist: tenacity (<9.0.0)
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
@@ -194,6 +194,17 @@ The `server` directory contains an API service for interacting with the Graphiti
|
|
|
194
194
|
|
|
195
195
|
Please see the [server README](./server/README.md) for more information.
|
|
196
196
|
|
|
197
|
+
## Optional Environment Variables
|
|
198
|
+
|
|
199
|
+
In addition to the Neo4j and OpenAi-compatible credentials, Graphiti also has a few optional environment variables.
|
|
200
|
+
If you are using one of our supported models, such as Anthropic or Voyage models, the necessary environment variables
|
|
201
|
+
must be set.
|
|
202
|
+
|
|
203
|
+
`USE_PARALLEL_RUNTIME` is an optional boolean variable that can be set to true if you wish
|
|
204
|
+
to enable Neo4j's parallel runtime feature for several of our search queries.
|
|
205
|
+
Note that this feature is not supported for Neo4j Community edition or for smaller AuraDB instances,
|
|
206
|
+
as such this feature is off by default.
|
|
207
|
+
|
|
197
208
|
## Documentation
|
|
198
209
|
|
|
199
210
|
- [Guides and API documentation](https://help.getzep.com/graphiti).
|
|
@@ -207,11 +218,11 @@ Graphiti is under active development. We aim to maintain API stability while wor
|
|
|
207
218
|
- [x] Implementing node and edge CRUD operations
|
|
208
219
|
- [ ] Improving performance and scalability
|
|
209
220
|
- [ ] Achieving good performance with different LLM and embedding models
|
|
210
|
-
- [
|
|
221
|
+
- [x] Creating a dedicated embedder interface
|
|
211
222
|
- [ ] Supporting custom graph schemas:
|
|
212
223
|
- Allow developers to provide their own defined node and edge classes when ingesting episodes
|
|
213
224
|
- Enable more flexible knowledge representation tailored to specific use cases
|
|
214
|
-
- [
|
|
225
|
+
- [x] Enhancing retrieval capabilities with more robust and configurable options
|
|
215
226
|
- [ ] Expanding test coverage to ensure reliability and catch edge cases
|
|
216
227
|
|
|
217
228
|
## Contributing
|
|
@@ -173,6 +173,17 @@ The `server` directory contains an API service for interacting with the Graphiti
|
|
|
173
173
|
|
|
174
174
|
Please see the [server README](./server/README.md) for more information.
|
|
175
175
|
|
|
176
|
+
## Optional Environment Variables
|
|
177
|
+
|
|
178
|
+
In addition to the Neo4j and OpenAi-compatible credentials, Graphiti also has a few optional environment variables.
|
|
179
|
+
If you are using one of our supported models, such as Anthropic or Voyage models, the necessary environment variables
|
|
180
|
+
must be set.
|
|
181
|
+
|
|
182
|
+
`USE_PARALLEL_RUNTIME` is an optional boolean variable that can be set to true if you wish
|
|
183
|
+
to enable Neo4j's parallel runtime feature for several of our search queries.
|
|
184
|
+
Note that this feature is not supported for Neo4j Community edition or for smaller AuraDB instances,
|
|
185
|
+
as such this feature is off by default.
|
|
186
|
+
|
|
176
187
|
## Documentation
|
|
177
188
|
|
|
178
189
|
- [Guides and API documentation](https://help.getzep.com/graphiti).
|
|
@@ -186,11 +197,11 @@ Graphiti is under active development. We aim to maintain API stability while wor
|
|
|
186
197
|
- [x] Implementing node and edge CRUD operations
|
|
187
198
|
- [ ] Improving performance and scalability
|
|
188
199
|
- [ ] Achieving good performance with different LLM and embedding models
|
|
189
|
-
- [
|
|
200
|
+
- [x] Creating a dedicated embedder interface
|
|
190
201
|
- [ ] Supporting custom graph schemas:
|
|
191
202
|
- Allow developers to provide their own defined node and edge classes when ingesting episodes
|
|
192
203
|
- Enable more flexible knowledge representation tailored to specific use cases
|
|
193
|
-
- [
|
|
204
|
+
- [x] Enhancing retrieval capabilities with more robust and configurable options
|
|
194
205
|
- [ ] Expanding test coverage to ensure reliability and catch edge cases
|
|
195
206
|
|
|
196
207
|
## Contributing
|
|
@@ -51,6 +51,7 @@ from graphiti_core.utils import (
|
|
|
51
51
|
)
|
|
52
52
|
from graphiti_core.utils.bulk_utils import (
|
|
53
53
|
RawEpisode,
|
|
54
|
+
add_nodes_and_edges_bulk,
|
|
54
55
|
dedupe_edges_bulk,
|
|
55
56
|
dedupe_nodes_bulk,
|
|
56
57
|
extract_edge_dates_bulk,
|
|
@@ -451,10 +452,9 @@ class Graphiti:
|
|
|
451
452
|
if not self.store_raw_episode_content:
|
|
452
453
|
episode.content = ''
|
|
453
454
|
|
|
454
|
-
await
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
await asyncio.gather(*[edge.save(self.driver) for edge in entity_edges])
|
|
455
|
+
await add_nodes_and_edges_bulk(
|
|
456
|
+
self.driver, [episode], episodic_edges, nodes, entity_edges
|
|
457
|
+
)
|
|
458
458
|
|
|
459
459
|
# Update any communities
|
|
460
460
|
if update_communities:
|
|
@@ -24,6 +24,7 @@ from neo4j import time as neo4j_time
|
|
|
24
24
|
load_dotenv()
|
|
25
25
|
|
|
26
26
|
DEFAULT_DATABASE = os.getenv('DEFAULT_DATABASE', None)
|
|
27
|
+
USE_PARALLEL_RUNTIME = bool(os.getenv('USE_PARALLEL_RUNTIME', False))
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def parse_db_date(neo_date: neo4j_time.DateTime | None) -> datetime | None:
|
|
@@ -5,6 +5,15 @@ EPISODIC_EDGE_SAVE = """
|
|
|
5
5
|
SET r = {uuid: $uuid, group_id: $group_id, created_at: $created_at}
|
|
6
6
|
RETURN r.uuid AS uuid"""
|
|
7
7
|
|
|
8
|
+
EPISODIC_EDGE_SAVE_BULK = """
|
|
9
|
+
UNWIND $episodic_edges AS edge
|
|
10
|
+
MATCH (episode:Episodic {uuid: edge.source_node_uuid})
|
|
11
|
+
MATCH (node:Entity {uuid: edge.target_node_uuid})
|
|
12
|
+
MERGE (episode)-[r:MENTIONS {uuid: edge.uuid}]->(node)
|
|
13
|
+
SET r = {uuid: edge.uuid, group_id: edge.group_id, created_at: edge.created_at}
|
|
14
|
+
RETURN r.uuid AS uuid
|
|
15
|
+
"""
|
|
16
|
+
|
|
8
17
|
ENTITY_EDGE_SAVE = """
|
|
9
18
|
MATCH (source:Entity {uuid: $source_uuid})
|
|
10
19
|
MATCH (target:Entity {uuid: $target_uuid})
|
|
@@ -14,6 +23,17 @@ ENTITY_EDGE_SAVE = """
|
|
|
14
23
|
WITH r CALL db.create.setRelationshipVectorProperty(r, "fact_embedding", $fact_embedding)
|
|
15
24
|
RETURN r.uuid AS uuid"""
|
|
16
25
|
|
|
26
|
+
ENTITY_EDGE_SAVE_BULK = """
|
|
27
|
+
UNWIND $entity_edges AS edge
|
|
28
|
+
MATCH (source:Entity {uuid: edge.source_node_uuid})
|
|
29
|
+
MATCH (target:Entity {uuid: edge.target_node_uuid})
|
|
30
|
+
MERGE (source)-[r:RELATES_TO {uuid: edge.uuid}]->(target)
|
|
31
|
+
SET r = {uuid: edge.uuid, name: edge.name, group_id: edge.group_id, fact: edge.fact, episodes: edge.episodes,
|
|
32
|
+
created_at: edge.created_at, expired_at: edge.expired_at, valid_at: edge.valid_at, invalid_at: edge.invalid_at}
|
|
33
|
+
WITH r, edge CALL db.create.setRelationshipVectorProperty(r, "fact_embedding", edge.fact_embedding)
|
|
34
|
+
RETURN r.uuid AS uuid
|
|
35
|
+
"""
|
|
36
|
+
|
|
17
37
|
COMMUNITY_EDGE_SAVE = """
|
|
18
38
|
MATCH (community:Community {uuid: $community_uuid})
|
|
19
39
|
MATCH (node:Entity | Community {uuid: $entity_uuid})
|
|
@@ -4,12 +4,29 @@ EPISODIC_NODE_SAVE = """
|
|
|
4
4
|
entity_edges: $entity_edges, created_at: $created_at, valid_at: $valid_at}
|
|
5
5
|
RETURN n.uuid AS uuid"""
|
|
6
6
|
|
|
7
|
+
EPISODIC_NODE_SAVE_BULK = """
|
|
8
|
+
UNWIND $episodes AS episode
|
|
9
|
+
MERGE (n:Episodic {uuid: episode.uuid})
|
|
10
|
+
SET n = {uuid: episode.uuid, name: episode.name, group_id: episode.group_id, source_description: episode.source_description,
|
|
11
|
+
source: episode.source, content: episode.content,
|
|
12
|
+
entity_edges: episode.entity_edges, created_at: episode.created_at, valid_at: episode.valid_at}
|
|
13
|
+
RETURN n.uuid AS uuid
|
|
14
|
+
"""
|
|
15
|
+
|
|
7
16
|
ENTITY_NODE_SAVE = """
|
|
8
17
|
MERGE (n:Entity {uuid: $uuid})
|
|
9
18
|
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
10
19
|
WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
|
|
11
20
|
RETURN n.uuid AS uuid"""
|
|
12
21
|
|
|
22
|
+
ENTITY_NODE_SAVE_BULK = """
|
|
23
|
+
UNWIND $nodes AS node
|
|
24
|
+
MERGE (n:Entity {uuid: node.uuid})
|
|
25
|
+
SET n = {uuid: node.uuid, name: node.name, group_id: node.group_id, summary: node.summary, created_at: node.created_at}
|
|
26
|
+
WITH n, node CALL db.create.setNodeVectorProperty(n, "name_embedding", node.name_embedding)
|
|
27
|
+
RETURN n.uuid AS uuid
|
|
28
|
+
"""
|
|
29
|
+
|
|
13
30
|
COMMUNITY_NODE_SAVE = """
|
|
14
31
|
MERGE (n:Community {uuid: $uuid})
|
|
15
32
|
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
@@ -66,6 +66,12 @@ async def search(
|
|
|
66
66
|
bfs_origin_node_uuids: list[str] | None = None,
|
|
67
67
|
) -> SearchResults:
|
|
68
68
|
start = time()
|
|
69
|
+
if query.strip() == '':
|
|
70
|
+
return SearchResults(
|
|
71
|
+
edges=[],
|
|
72
|
+
nodes=[],
|
|
73
|
+
communities=[],
|
|
74
|
+
)
|
|
69
75
|
query_vector = await embedder.create(input_data=[query.replace('\n', ' ')])
|
|
70
76
|
|
|
71
77
|
# if group_ids is empty, set it to None
|
|
@@ -21,9 +21,15 @@ from time import time
|
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from neo4j import AsyncDriver, Query
|
|
24
|
+
from typing_extensions import LiteralString
|
|
24
25
|
|
|
25
26
|
from graphiti_core.edges import EntityEdge, get_entity_edge_from_record
|
|
26
|
-
from graphiti_core.helpers import
|
|
27
|
+
from graphiti_core.helpers import (
|
|
28
|
+
DEFAULT_DATABASE,
|
|
29
|
+
USE_PARALLEL_RUNTIME,
|
|
30
|
+
lucene_sanitize,
|
|
31
|
+
normalize_l2,
|
|
32
|
+
)
|
|
27
33
|
from graphiti_core.nodes import (
|
|
28
34
|
CommunityNode,
|
|
29
35
|
EntityNode,
|
|
@@ -38,7 +44,7 @@ RELEVANT_SCHEMA_LIMIT = 3
|
|
|
38
44
|
DEFAULT_MIN_SCORE = 0.6
|
|
39
45
|
DEFAULT_MMR_LAMBDA = 0.5
|
|
40
46
|
MAX_SEARCH_DEPTH = 3
|
|
41
|
-
MAX_QUERY_LENGTH =
|
|
47
|
+
MAX_QUERY_LENGTH = 32
|
|
42
48
|
|
|
43
49
|
|
|
44
50
|
def fulltext_query(query: str, group_ids: list[str] | None = None):
|
|
@@ -187,8 +193,11 @@ async def edge_similarity_search(
|
|
|
187
193
|
min_score: float = DEFAULT_MIN_SCORE,
|
|
188
194
|
) -> list[EntityEdge]:
|
|
189
195
|
# vector similarity search over embedded facts
|
|
190
|
-
|
|
191
|
-
|
|
196
|
+
runtime_query: LiteralString = (
|
|
197
|
+
'CYPHER runtime = parallel parallelRuntimeSupport=all\n' if USE_PARALLEL_RUNTIME else ''
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
query: LiteralString = """
|
|
192
201
|
MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
|
|
193
202
|
WHERE ($group_ids IS NULL OR r.group_id IN $group_ids)
|
|
194
203
|
AND ($source_uuid IS NULL OR n.uuid IN [$source_uuid, $target_uuid])
|
|
@@ -210,10 +219,10 @@ async def edge_similarity_search(
|
|
|
210
219
|
r.invalid_at AS invalid_at
|
|
211
220
|
ORDER BY score DESC
|
|
212
221
|
LIMIT $limit
|
|
213
|
-
"""
|
|
222
|
+
"""
|
|
214
223
|
|
|
215
224
|
records, _, _ = await driver.execute_query(
|
|
216
|
-
query,
|
|
225
|
+
runtime_query + query,
|
|
217
226
|
search_vector=search_vector,
|
|
218
227
|
source_uuid=source_node_uuid,
|
|
219
228
|
target_uuid=target_node_uuid,
|
|
@@ -318,9 +327,13 @@ async def node_similarity_search(
|
|
|
318
327
|
min_score: float = DEFAULT_MIN_SCORE,
|
|
319
328
|
) -> list[EntityNode]:
|
|
320
329
|
# vector similarity search over entity names
|
|
330
|
+
runtime_query: LiteralString = (
|
|
331
|
+
'CYPHER runtime = parallel parallelRuntimeSupport=all\n' if USE_PARALLEL_RUNTIME else ''
|
|
332
|
+
)
|
|
333
|
+
|
|
321
334
|
records, _, _ = await driver.execute_query(
|
|
322
|
-
|
|
323
|
-
|
|
335
|
+
runtime_query
|
|
336
|
+
+ """
|
|
324
337
|
MATCH (n:Entity)
|
|
325
338
|
WHERE $group_ids IS NULL OR n.group_id IN $group_ids
|
|
326
339
|
WITH n, vector.similarity.cosine(n.name_embedding, $search_vector) AS score
|
|
@@ -425,23 +438,27 @@ async def community_similarity_search(
|
|
|
425
438
|
min_score=DEFAULT_MIN_SCORE,
|
|
426
439
|
) -> list[CommunityNode]:
|
|
427
440
|
# vector similarity search over entity names
|
|
441
|
+
runtime_query: LiteralString = (
|
|
442
|
+
'CYPHER runtime = parallel parallelRuntimeSupport=all\n' if USE_PARALLEL_RUNTIME else ''
|
|
443
|
+
)
|
|
444
|
+
|
|
428
445
|
records, _, _ = await driver.execute_query(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
446
|
+
runtime_query
|
|
447
|
+
+ """
|
|
448
|
+
MATCH (comm:Community)
|
|
449
|
+
WHERE ($group_ids IS NULL OR comm.group_id IN $group_ids)
|
|
450
|
+
WITH comm, vector.similarity.cosine(comm.name_embedding, $search_vector) AS score
|
|
451
|
+
WHERE score > $min_score
|
|
452
|
+
RETURN
|
|
453
|
+
comm.uuid As uuid,
|
|
454
|
+
comm.group_id AS group_id,
|
|
455
|
+
comm.name AS name,
|
|
456
|
+
comm.name_embedding AS name_embedding,
|
|
457
|
+
comm.created_at AS created_at,
|
|
458
|
+
comm.summary AS summary
|
|
459
|
+
ORDER BY score DESC
|
|
460
|
+
LIMIT $limit
|
|
461
|
+
""",
|
|
445
462
|
search_vector=search_vector,
|
|
446
463
|
group_ids=group_ids,
|
|
447
464
|
limit=limit,
|
|
@@ -21,12 +21,20 @@ from collections import defaultdict
|
|
|
21
21
|
from datetime import datetime
|
|
22
22
|
from math import ceil
|
|
23
23
|
|
|
24
|
-
from neo4j import AsyncDriver
|
|
24
|
+
from neo4j import AsyncDriver, AsyncManagedTransaction
|
|
25
25
|
from numpy import dot, sqrt
|
|
26
26
|
from pydantic import BaseModel
|
|
27
27
|
|
|
28
28
|
from graphiti_core.edges import Edge, EntityEdge, EpisodicEdge
|
|
29
29
|
from graphiti_core.llm_client import LLMClient
|
|
30
|
+
from graphiti_core.models.edges.edge_db_queries import (
|
|
31
|
+
ENTITY_EDGE_SAVE_BULK,
|
|
32
|
+
EPISODIC_EDGE_SAVE_BULK,
|
|
33
|
+
)
|
|
34
|
+
from graphiti_core.models.nodes.node_db_queries import (
|
|
35
|
+
ENTITY_NODE_SAVE_BULK,
|
|
36
|
+
EPISODIC_NODE_SAVE_BULK,
|
|
37
|
+
)
|
|
30
38
|
from graphiti_core.nodes import EntityNode, EpisodeType, EpisodicNode
|
|
31
39
|
from graphiti_core.search.search_utils import get_relevant_edges, get_relevant_nodes
|
|
32
40
|
from graphiti_core.utils import retrieve_episodes
|
|
@@ -75,6 +83,35 @@ async def retrieve_previous_episodes_bulk(
|
|
|
75
83
|
return episode_tuples
|
|
76
84
|
|
|
77
85
|
|
|
86
|
+
async def add_nodes_and_edges_bulk(
|
|
87
|
+
driver: AsyncDriver,
|
|
88
|
+
episodic_nodes: list[EpisodicNode],
|
|
89
|
+
episodic_edges: list[EpisodicEdge],
|
|
90
|
+
entity_nodes: list[EntityNode],
|
|
91
|
+
entity_edges: list[EntityEdge],
|
|
92
|
+
):
|
|
93
|
+
async with driver.session() as session:
|
|
94
|
+
await session.execute_write(
|
|
95
|
+
add_nodes_and_edges_bulk_tx, episodic_nodes, episodic_edges, entity_nodes, entity_edges
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def add_nodes_and_edges_bulk_tx(
|
|
100
|
+
tx: AsyncManagedTransaction,
|
|
101
|
+
episodic_nodes: list[EpisodicNode],
|
|
102
|
+
episodic_edges: list[EpisodicEdge],
|
|
103
|
+
entity_nodes: list[EntityNode],
|
|
104
|
+
entity_edges: list[EntityEdge],
|
|
105
|
+
):
|
|
106
|
+
episodes = [dict(episode) for episode in episodic_nodes]
|
|
107
|
+
for episode in episodes:
|
|
108
|
+
episode['source'] = str(episode['source'].value)
|
|
109
|
+
await tx.run(EPISODIC_NODE_SAVE_BULK, episodes=episodes)
|
|
110
|
+
await tx.run(ENTITY_NODE_SAVE_BULK, nodes=[dict(entity) for entity in entity_nodes])
|
|
111
|
+
await tx.run(EPISODIC_EDGE_SAVE_BULK, episodic_edges=[dict(edge) for edge in episodic_edges])
|
|
112
|
+
await tx.run(ENTITY_EDGE_SAVE_BULK, entity_edges=[dict(edge) for edge in entity_edges])
|
|
113
|
+
|
|
114
|
+
|
|
78
115
|
async def extract_nodes_and_edges_bulk(
|
|
79
116
|
llm_client: LLMClient, episode_tuples: list[tuple[EpisodicNode, list[EpisodicNode]]]
|
|
80
117
|
) -> tuple[list[EntityNode], list[EntityEdge], list[EpisodicEdge]]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "graphiti-core"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.21"
|
|
4
4
|
description = "A temporal graph building library"
|
|
5
5
|
authors = [
|
|
6
6
|
"Paul Paliychuk <paul@getzep.com>",
|
|
@@ -17,7 +17,7 @@ python = "^3.10"
|
|
|
17
17
|
pydantic = "^2.8.2"
|
|
18
18
|
neo4j = "^5.23.0"
|
|
19
19
|
diskcache = "^5.6.3"
|
|
20
|
-
openai = "^1.
|
|
20
|
+
openai = "^1.53.0"
|
|
21
21
|
tenacity = "<9.0.0"
|
|
22
22
|
numpy = ">=1.0.0"
|
|
23
23
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/bge_reranker_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/cross_encoder/openai_reranker_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/edge_operations.py
RENAMED
|
File without changes
|
|
File without changes
|
{graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/node_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.3.19 → graphiti_core-0.3.21}/graphiti_core/utils/maintenance/temporal_operations.py
RENAMED
|
File without changes
|
|
File without changes
|