graphiti-core 0.3.12__tar.gz → 0.3.14__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.12 → graphiti_core-0.3.14}/PKG-INFO +1 -1
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/edges.py +22 -21
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/helpers.py +3 -0
- graphiti_core-0.3.14/graphiti_core/models/edges/edge_db_queries.py +22 -0
- graphiti_core-0.3.14/graphiti_core/models/nodes/__init__.py +0 -0
- graphiti_core-0.3.14/graphiti_core/models/nodes/node_db_queries.py +17 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/nodes.py +22 -15
- graphiti_core-0.3.14/graphiti_core/search/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/search/search_utils.py +23 -2
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/community_operations.py +19 -5
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/graph_data_operations.py +24 -4
- graphiti_core-0.3.14/graphiti_core/utils/maintenance/utils.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/pyproject.toml +1 -1
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/LICENSE +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/README.md +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/embedder/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/embedder/client.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/embedder/openai.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/embedder/voyage.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/errors.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/graphiti.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/anthropic_client.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/client.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/config.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/errors.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/groq_client.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/openai_client.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/llm_client/utils.py +0 -0
- {graphiti_core-0.3.12/graphiti_core/search → graphiti_core-0.3.14/graphiti_core/models}/__init__.py +0 -0
- /graphiti_core-0.3.12/graphiti_core/utils/maintenance/utils.py → /graphiti_core-0.3.14/graphiti_core/models/edges/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/dedupe_edges.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/dedupe_nodes.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/eval.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/extract_edge_dates.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/extract_edges.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/extract_nodes.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/invalidate_edges.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/lib.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/models.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/prompts/summarize_nodes.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/py.typed +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/search/search.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/search/search_config.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/search/search_config_recipes.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/bulk_utils.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/__init__.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/edge_operations.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/node_operations.py +0 -0
- {graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/temporal_operations.py +0 -0
|
@@ -26,7 +26,12 @@ from pydantic import BaseModel, Field
|
|
|
26
26
|
|
|
27
27
|
from graphiti_core.embedder import EmbedderClient
|
|
28
28
|
from graphiti_core.errors import EdgeNotFoundError, GroupsEdgesNotFoundError
|
|
29
|
-
from graphiti_core.helpers import parse_db_date
|
|
29
|
+
from graphiti_core.helpers import DEFAULT_DATABASE, parse_db_date
|
|
30
|
+
from graphiti_core.models.edges.edge_db_queries import (
|
|
31
|
+
COMMUNITY_EDGE_SAVE,
|
|
32
|
+
ENTITY_EDGE_SAVE,
|
|
33
|
+
EPISODIC_EDGE_SAVE,
|
|
34
|
+
)
|
|
30
35
|
from graphiti_core.nodes import Node
|
|
31
36
|
|
|
32
37
|
logger = logging.getLogger(__name__)
|
|
@@ -49,6 +54,7 @@ class Edge(BaseModel, ABC):
|
|
|
49
54
|
DELETE e
|
|
50
55
|
""",
|
|
51
56
|
uuid=self.uuid,
|
|
57
|
+
_database=DEFAULT_DATABASE,
|
|
52
58
|
)
|
|
53
59
|
|
|
54
60
|
logger.debug(f'Deleted Edge: {self.uuid}')
|
|
@@ -70,17 +76,13 @@ class Edge(BaseModel, ABC):
|
|
|
70
76
|
class EpisodicEdge(Edge):
|
|
71
77
|
async def save(self, driver: AsyncDriver):
|
|
72
78
|
result = await driver.execute_query(
|
|
73
|
-
|
|
74
|
-
MATCH (episode:Episodic {uuid: $episode_uuid})
|
|
75
|
-
MATCH (node:Entity {uuid: $entity_uuid})
|
|
76
|
-
MERGE (episode)-[r:MENTIONS {uuid: $uuid}]->(node)
|
|
77
|
-
SET r = {uuid: $uuid, group_id: $group_id, created_at: $created_at}
|
|
78
|
-
RETURN r.uuid AS uuid""",
|
|
79
|
+
EPISODIC_EDGE_SAVE,
|
|
79
80
|
episode_uuid=self.source_node_uuid,
|
|
80
81
|
entity_uuid=self.target_node_uuid,
|
|
81
82
|
uuid=self.uuid,
|
|
82
83
|
group_id=self.group_id,
|
|
83
84
|
created_at=self.created_at,
|
|
85
|
+
_database=DEFAULT_DATABASE,
|
|
84
86
|
)
|
|
85
87
|
|
|
86
88
|
logger.debug(f'Saved edge to neo4j: {self.uuid}')
|
|
@@ -100,6 +102,7 @@ class EpisodicEdge(Edge):
|
|
|
100
102
|
e.created_at AS created_at
|
|
101
103
|
""",
|
|
102
104
|
uuid=uuid,
|
|
105
|
+
_database=DEFAULT_DATABASE,
|
|
103
106
|
)
|
|
104
107
|
|
|
105
108
|
edges = [get_episodic_edge_from_record(record) for record in records]
|
|
@@ -122,6 +125,7 @@ class EpisodicEdge(Edge):
|
|
|
122
125
|
e.created_at AS created_at
|
|
123
126
|
""",
|
|
124
127
|
uuids=uuids,
|
|
128
|
+
_database=DEFAULT_DATABASE,
|
|
125
129
|
)
|
|
126
130
|
|
|
127
131
|
edges = [get_episodic_edge_from_record(record) for record in records]
|
|
@@ -144,6 +148,7 @@ class EpisodicEdge(Edge):
|
|
|
144
148
|
e.created_at AS created_at
|
|
145
149
|
""",
|
|
146
150
|
group_ids=group_ids,
|
|
151
|
+
_database=DEFAULT_DATABASE,
|
|
147
152
|
)
|
|
148
153
|
|
|
149
154
|
edges = [get_episodic_edge_from_record(record) for record in records]
|
|
@@ -184,14 +189,7 @@ class EntityEdge(Edge):
|
|
|
184
189
|
|
|
185
190
|
async def save(self, driver: AsyncDriver):
|
|
186
191
|
result = await driver.execute_query(
|
|
187
|
-
|
|
188
|
-
MATCH (source:Entity {uuid: $source_uuid})
|
|
189
|
-
MATCH (target:Entity {uuid: $target_uuid})
|
|
190
|
-
MERGE (source)-[r:RELATES_TO {uuid: $uuid}]->(target)
|
|
191
|
-
SET r = {uuid: $uuid, name: $name, group_id: $group_id, fact: $fact, episodes: $episodes,
|
|
192
|
-
created_at: $created_at, expired_at: $expired_at, valid_at: $valid_at, invalid_at: $invalid_at}
|
|
193
|
-
WITH r CALL db.create.setRelationshipVectorProperty(r, "fact_embedding", $fact_embedding)
|
|
194
|
-
RETURN r.uuid AS uuid""",
|
|
192
|
+
ENTITY_EDGE_SAVE,
|
|
195
193
|
source_uuid=self.source_node_uuid,
|
|
196
194
|
target_uuid=self.target_node_uuid,
|
|
197
195
|
uuid=self.uuid,
|
|
@@ -204,6 +202,7 @@ class EntityEdge(Edge):
|
|
|
204
202
|
expired_at=self.expired_at,
|
|
205
203
|
valid_at=self.valid_at,
|
|
206
204
|
invalid_at=self.invalid_at,
|
|
205
|
+
_database=DEFAULT_DATABASE,
|
|
207
206
|
)
|
|
208
207
|
|
|
209
208
|
logger.debug(f'Saved edge to neo4j: {self.uuid}')
|
|
@@ -230,6 +229,7 @@ class EntityEdge(Edge):
|
|
|
230
229
|
e.invalid_at AS invalid_at
|
|
231
230
|
""",
|
|
232
231
|
uuid=uuid,
|
|
232
|
+
_database=DEFAULT_DATABASE,
|
|
233
233
|
)
|
|
234
234
|
|
|
235
235
|
edges = [get_entity_edge_from_record(record) for record in records]
|
|
@@ -259,6 +259,7 @@ class EntityEdge(Edge):
|
|
|
259
259
|
e.invalid_at AS invalid_at
|
|
260
260
|
""",
|
|
261
261
|
uuids=uuids,
|
|
262
|
+
_database=DEFAULT_DATABASE,
|
|
262
263
|
)
|
|
263
264
|
|
|
264
265
|
edges = [get_entity_edge_from_record(record) for record in records]
|
|
@@ -288,6 +289,7 @@ class EntityEdge(Edge):
|
|
|
288
289
|
e.invalid_at AS invalid_at
|
|
289
290
|
""",
|
|
290
291
|
group_ids=group_ids,
|
|
292
|
+
_database=DEFAULT_DATABASE,
|
|
291
293
|
)
|
|
292
294
|
|
|
293
295
|
edges = [get_entity_edge_from_record(record) for record in records]
|
|
@@ -300,17 +302,13 @@ class EntityEdge(Edge):
|
|
|
300
302
|
class CommunityEdge(Edge):
|
|
301
303
|
async def save(self, driver: AsyncDriver):
|
|
302
304
|
result = await driver.execute_query(
|
|
303
|
-
|
|
304
|
-
MATCH (community:Community {uuid: $community_uuid})
|
|
305
|
-
MATCH (node:Entity | Community {uuid: $entity_uuid})
|
|
306
|
-
MERGE (community)-[r:HAS_MEMBER {uuid: $uuid}]->(node)
|
|
307
|
-
SET r = {uuid: $uuid, group_id: $group_id, created_at: $created_at}
|
|
308
|
-
RETURN r.uuid AS uuid""",
|
|
305
|
+
COMMUNITY_EDGE_SAVE,
|
|
309
306
|
community_uuid=self.source_node_uuid,
|
|
310
307
|
entity_uuid=self.target_node_uuid,
|
|
311
308
|
uuid=self.uuid,
|
|
312
309
|
group_id=self.group_id,
|
|
313
310
|
created_at=self.created_at,
|
|
311
|
+
_database=DEFAULT_DATABASE,
|
|
314
312
|
)
|
|
315
313
|
|
|
316
314
|
logger.debug(f'Saved edge to neo4j: {self.uuid}')
|
|
@@ -330,6 +328,7 @@ class CommunityEdge(Edge):
|
|
|
330
328
|
e.created_at AS created_at
|
|
331
329
|
""",
|
|
332
330
|
uuid=uuid,
|
|
331
|
+
_database=DEFAULT_DATABASE,
|
|
333
332
|
)
|
|
334
333
|
|
|
335
334
|
edges = [get_community_edge_from_record(record) for record in records]
|
|
@@ -350,6 +349,7 @@ class CommunityEdge(Edge):
|
|
|
350
349
|
e.created_at AS created_at
|
|
351
350
|
""",
|
|
352
351
|
uuids=uuids,
|
|
352
|
+
_database=DEFAULT_DATABASE,
|
|
353
353
|
)
|
|
354
354
|
|
|
355
355
|
edges = [get_community_edge_from_record(record) for record in records]
|
|
@@ -370,6 +370,7 @@ class CommunityEdge(Edge):
|
|
|
370
370
|
e.created_at AS created_at
|
|
371
371
|
""",
|
|
372
372
|
group_ids=group_ids,
|
|
373
|
+
_database=DEFAULT_DATABASE,
|
|
373
374
|
)
|
|
374
375
|
|
|
375
376
|
edges = [get_community_edge_from_record(record) for record in records]
|
|
@@ -14,11 +14,14 @@ See the License for the specific language governing permissions and
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
+
import os
|
|
17
18
|
from datetime import datetime
|
|
18
19
|
|
|
19
20
|
import numpy as np
|
|
20
21
|
from neo4j import time as neo4j_time
|
|
21
22
|
|
|
23
|
+
DEFAULT_DATABASE = os.getenv('DEFAULT_DATABASE', None)
|
|
24
|
+
|
|
22
25
|
|
|
23
26
|
def parse_db_date(neo_date: neo4j_time.DateTime | None) -> datetime | None:
|
|
24
27
|
return neo_date.to_native() if neo_date else None
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
EPISODIC_EDGE_SAVE = """
|
|
2
|
+
MATCH (episode:Episodic {uuid: $episode_uuid})
|
|
3
|
+
MATCH (node:Entity {uuid: $entity_uuid})
|
|
4
|
+
MERGE (episode)-[r:MENTIONS {uuid: $uuid}]->(node)
|
|
5
|
+
SET r = {uuid: $uuid, group_id: $group_id, created_at: $created_at}
|
|
6
|
+
RETURN r.uuid AS uuid"""
|
|
7
|
+
|
|
8
|
+
ENTITY_EDGE_SAVE = """
|
|
9
|
+
MATCH (source:Entity {uuid: $source_uuid})
|
|
10
|
+
MATCH (target:Entity {uuid: $target_uuid})
|
|
11
|
+
MERGE (source)-[r:RELATES_TO {uuid: $uuid}]->(target)
|
|
12
|
+
SET r = {uuid: $uuid, name: $name, group_id: $group_id, fact: $fact, episodes: $episodes,
|
|
13
|
+
created_at: $created_at, expired_at: $expired_at, valid_at: $valid_at, invalid_at: $invalid_at}
|
|
14
|
+
WITH r CALL db.create.setRelationshipVectorProperty(r, "fact_embedding", $fact_embedding)
|
|
15
|
+
RETURN r.uuid AS uuid"""
|
|
16
|
+
|
|
17
|
+
COMMUNITY_EDGE_SAVE = """
|
|
18
|
+
MATCH (community:Community {uuid: $community_uuid})
|
|
19
|
+
MATCH (node:Entity | Community {uuid: $entity_uuid})
|
|
20
|
+
MERGE (community)-[r:HAS_MEMBER {uuid: $uuid}]->(node)
|
|
21
|
+
SET r = {uuid: $uuid, group_id: $group_id, created_at: $created_at}
|
|
22
|
+
RETURN r.uuid AS uuid"""
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
EPISODIC_NODE_SAVE = """
|
|
2
|
+
MERGE (n:Episodic {uuid: $uuid})
|
|
3
|
+
SET n = {uuid: $uuid, name: $name, group_id: $group_id, source_description: $source_description, source: $source, content: $content,
|
|
4
|
+
entity_edges: $entity_edges, created_at: $created_at, valid_at: $valid_at}
|
|
5
|
+
RETURN n.uuid AS uuid"""
|
|
6
|
+
|
|
7
|
+
ENTITY_NODE_SAVE = """
|
|
8
|
+
MERGE (n:Entity {uuid: $uuid})
|
|
9
|
+
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
10
|
+
WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
|
|
11
|
+
RETURN n.uuid AS uuid"""
|
|
12
|
+
|
|
13
|
+
COMMUNITY_NODE_SAVE = """
|
|
14
|
+
MERGE (n:Community {uuid: $uuid})
|
|
15
|
+
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
16
|
+
WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
|
|
17
|
+
RETURN n.uuid AS uuid"""
|
|
@@ -27,6 +27,12 @@ from pydantic import BaseModel, Field
|
|
|
27
27
|
|
|
28
28
|
from graphiti_core.embedder import EmbedderClient
|
|
29
29
|
from graphiti_core.errors import NodeNotFoundError
|
|
30
|
+
from graphiti_core.helpers import DEFAULT_DATABASE
|
|
31
|
+
from graphiti_core.models.nodes.node_db_queries import (
|
|
32
|
+
COMMUNITY_NODE_SAVE,
|
|
33
|
+
ENTITY_NODE_SAVE,
|
|
34
|
+
EPISODIC_NODE_SAVE,
|
|
35
|
+
)
|
|
30
36
|
|
|
31
37
|
logger = logging.getLogger(__name__)
|
|
32
38
|
|
|
@@ -84,6 +90,7 @@ class Node(BaseModel, ABC):
|
|
|
84
90
|
DETACH DELETE n
|
|
85
91
|
""",
|
|
86
92
|
uuid=self.uuid,
|
|
93
|
+
_database=DEFAULT_DATABASE,
|
|
87
94
|
)
|
|
88
95
|
|
|
89
96
|
logger.debug(f'Deleted Node: {self.uuid}')
|
|
@@ -119,11 +126,7 @@ class EpisodicNode(Node):
|
|
|
119
126
|
|
|
120
127
|
async def save(self, driver: AsyncDriver):
|
|
121
128
|
result = await driver.execute_query(
|
|
122
|
-
|
|
123
|
-
MERGE (n:Episodic {uuid: $uuid})
|
|
124
|
-
SET n = {uuid: $uuid, name: $name, group_id: $group_id, source_description: $source_description, source: $source, content: $content,
|
|
125
|
-
entity_edges: $entity_edges, created_at: $created_at, valid_at: $valid_at}
|
|
126
|
-
RETURN n.uuid AS uuid""",
|
|
129
|
+
EPISODIC_NODE_SAVE,
|
|
127
130
|
uuid=self.uuid,
|
|
128
131
|
name=self.name,
|
|
129
132
|
group_id=self.group_id,
|
|
@@ -133,6 +136,7 @@ class EpisodicNode(Node):
|
|
|
133
136
|
created_at=self.created_at,
|
|
134
137
|
valid_at=self.valid_at,
|
|
135
138
|
source=self.source.value,
|
|
139
|
+
_database=DEFAULT_DATABASE,
|
|
136
140
|
)
|
|
137
141
|
|
|
138
142
|
logger.debug(f'Saved Node to neo4j: {self.uuid}')
|
|
@@ -154,6 +158,7 @@ class EpisodicNode(Node):
|
|
|
154
158
|
e.source AS source
|
|
155
159
|
""",
|
|
156
160
|
uuid=uuid,
|
|
161
|
+
_database=DEFAULT_DATABASE,
|
|
157
162
|
)
|
|
158
163
|
|
|
159
164
|
episodes = [get_episodic_node_from_record(record) for record in records]
|
|
@@ -179,6 +184,7 @@ class EpisodicNode(Node):
|
|
|
179
184
|
e.source AS source
|
|
180
185
|
""",
|
|
181
186
|
uuids=uuids,
|
|
187
|
+
_database=DEFAULT_DATABASE,
|
|
182
188
|
)
|
|
183
189
|
|
|
184
190
|
episodes = [get_episodic_node_from_record(record) for record in records]
|
|
@@ -201,6 +207,7 @@ class EpisodicNode(Node):
|
|
|
201
207
|
e.source AS source
|
|
202
208
|
""",
|
|
203
209
|
group_ids=group_ids,
|
|
210
|
+
_database=DEFAULT_DATABASE,
|
|
204
211
|
)
|
|
205
212
|
|
|
206
213
|
episodes = [get_episodic_node_from_record(record) for record in records]
|
|
@@ -223,17 +230,14 @@ class EntityNode(Node):
|
|
|
223
230
|
|
|
224
231
|
async def save(self, driver: AsyncDriver):
|
|
225
232
|
result = await driver.execute_query(
|
|
226
|
-
|
|
227
|
-
MERGE (n:Entity {uuid: $uuid})
|
|
228
|
-
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
229
|
-
WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
|
|
230
|
-
RETURN n.uuid AS uuid""",
|
|
233
|
+
ENTITY_NODE_SAVE,
|
|
231
234
|
uuid=self.uuid,
|
|
232
235
|
name=self.name,
|
|
233
236
|
group_id=self.group_id,
|
|
234
237
|
summary=self.summary,
|
|
235
238
|
name_embedding=self.name_embedding,
|
|
236
239
|
created_at=self.created_at,
|
|
240
|
+
_database=DEFAULT_DATABASE,
|
|
237
241
|
)
|
|
238
242
|
|
|
239
243
|
logger.debug(f'Saved Node to neo4j: {self.uuid}')
|
|
@@ -254,6 +258,7 @@ class EntityNode(Node):
|
|
|
254
258
|
n.summary AS summary
|
|
255
259
|
""",
|
|
256
260
|
uuid=uuid,
|
|
261
|
+
_database=DEFAULT_DATABASE,
|
|
257
262
|
)
|
|
258
263
|
|
|
259
264
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
@@ -277,6 +282,7 @@ class EntityNode(Node):
|
|
|
277
282
|
n.summary AS summary
|
|
278
283
|
""",
|
|
279
284
|
uuids=uuids,
|
|
285
|
+
_database=DEFAULT_DATABASE,
|
|
280
286
|
)
|
|
281
287
|
|
|
282
288
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
@@ -297,6 +303,7 @@ class EntityNode(Node):
|
|
|
297
303
|
n.summary AS summary
|
|
298
304
|
""",
|
|
299
305
|
group_ids=group_ids,
|
|
306
|
+
_database=DEFAULT_DATABASE,
|
|
300
307
|
)
|
|
301
308
|
|
|
302
309
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
@@ -310,17 +317,14 @@ class CommunityNode(Node):
|
|
|
310
317
|
|
|
311
318
|
async def save(self, driver: AsyncDriver):
|
|
312
319
|
result = await driver.execute_query(
|
|
313
|
-
|
|
314
|
-
MERGE (n:Community {uuid: $uuid})
|
|
315
|
-
SET n = {uuid: $uuid, name: $name, group_id: $group_id, summary: $summary, created_at: $created_at}
|
|
316
|
-
WITH n CALL db.create.setNodeVectorProperty(n, "name_embedding", $name_embedding)
|
|
317
|
-
RETURN n.uuid AS uuid""",
|
|
320
|
+
COMMUNITY_NODE_SAVE,
|
|
318
321
|
uuid=self.uuid,
|
|
319
322
|
name=self.name,
|
|
320
323
|
group_id=self.group_id,
|
|
321
324
|
summary=self.summary,
|
|
322
325
|
name_embedding=self.name_embedding,
|
|
323
326
|
created_at=self.created_at,
|
|
327
|
+
_database=DEFAULT_DATABASE,
|
|
324
328
|
)
|
|
325
329
|
|
|
326
330
|
logger.debug(f'Saved Node to neo4j: {self.uuid}')
|
|
@@ -350,6 +354,7 @@ class CommunityNode(Node):
|
|
|
350
354
|
n.summary AS summary
|
|
351
355
|
""",
|
|
352
356
|
uuid=uuid,
|
|
357
|
+
_database=DEFAULT_DATABASE,
|
|
353
358
|
)
|
|
354
359
|
|
|
355
360
|
nodes = [get_community_node_from_record(record) for record in records]
|
|
@@ -373,6 +378,7 @@ class CommunityNode(Node):
|
|
|
373
378
|
n.summary AS summary
|
|
374
379
|
""",
|
|
375
380
|
uuids=uuids,
|
|
381
|
+
_database=DEFAULT_DATABASE,
|
|
376
382
|
)
|
|
377
383
|
|
|
378
384
|
communities = [get_community_node_from_record(record) for record in records]
|
|
@@ -393,6 +399,7 @@ class CommunityNode(Node):
|
|
|
393
399
|
n.summary AS summary
|
|
394
400
|
""",
|
|
395
401
|
group_ids=group_ids,
|
|
402
|
+
_database=DEFAULT_DATABASE,
|
|
396
403
|
)
|
|
397
404
|
|
|
398
405
|
communities = [get_community_node_from_record(record) for record in records]
|
|
File without changes
|
|
@@ -23,7 +23,7 @@ import numpy as np
|
|
|
23
23
|
from neo4j import AsyncDriver, Query
|
|
24
24
|
|
|
25
25
|
from graphiti_core.edges import EntityEdge, get_entity_edge_from_record
|
|
26
|
-
from graphiti_core.helpers import lucene_sanitize, normalize_l2
|
|
26
|
+
from graphiti_core.helpers import DEFAULT_DATABASE, lucene_sanitize, normalize_l2
|
|
27
27
|
from graphiti_core.nodes import (
|
|
28
28
|
CommunityNode,
|
|
29
29
|
EntityNode,
|
|
@@ -37,6 +37,7 @@ logger = logging.getLogger(__name__)
|
|
|
37
37
|
RELEVANT_SCHEMA_LIMIT = 3
|
|
38
38
|
DEFAULT_MIN_SCORE = 0.6
|
|
39
39
|
DEFAULT_MMR_LAMBDA = 0.5
|
|
40
|
+
MAX_QUERY_LENGTH = 128
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
def fulltext_query(query: str, group_ids: list[str] | None = None):
|
|
@@ -50,7 +51,11 @@ def fulltext_query(query: str, group_ids: list[str] | None = None):
|
|
|
50
51
|
group_ids_filter += ' AND ' if group_ids_filter else ''
|
|
51
52
|
|
|
52
53
|
lucene_query = lucene_sanitize(query)
|
|
53
|
-
|
|
54
|
+
# If the lucene query is too long return no query
|
|
55
|
+
if len(lucene_query.split(' ')) + len(group_ids or '') >= MAX_QUERY_LENGTH:
|
|
56
|
+
return ''
|
|
57
|
+
|
|
58
|
+
full_query = group_ids_filter + '(' + lucene_query + ')'
|
|
54
59
|
|
|
55
60
|
return full_query
|
|
56
61
|
|
|
@@ -86,6 +91,7 @@ async def get_mentioned_nodes(
|
|
|
86
91
|
n.summary AS summary
|
|
87
92
|
""",
|
|
88
93
|
uuids=episode_uuids,
|
|
94
|
+
_database=DEFAULT_DATABASE,
|
|
89
95
|
)
|
|
90
96
|
|
|
91
97
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
@@ -109,6 +115,7 @@ async def get_communities_by_nodes(
|
|
|
109
115
|
c.summary AS summary
|
|
110
116
|
""",
|
|
111
117
|
uuids=node_uuids,
|
|
118
|
+
_database=DEFAULT_DATABASE,
|
|
112
119
|
)
|
|
113
120
|
|
|
114
121
|
communities = [get_community_node_from_record(record) for record in records]
|
|
@@ -126,6 +133,8 @@ async def edge_fulltext_search(
|
|
|
126
133
|
) -> list[EntityEdge]:
|
|
127
134
|
# fulltext search over facts
|
|
128
135
|
fuzzy_query = fulltext_query(query, group_ids)
|
|
136
|
+
if fuzzy_query == '':
|
|
137
|
+
return []
|
|
129
138
|
|
|
130
139
|
cypher_query = Query("""
|
|
131
140
|
CALL db.index.fulltext.queryRelationships("edge_name_and_fact", $query)
|
|
@@ -154,6 +163,7 @@ async def edge_fulltext_search(
|
|
|
154
163
|
target_uuid=target_node_uuid,
|
|
155
164
|
group_ids=group_ids,
|
|
156
165
|
limit=limit,
|
|
166
|
+
_database=DEFAULT_DATABASE,
|
|
157
167
|
)
|
|
158
168
|
|
|
159
169
|
edges = [get_entity_edge_from_record(record) for record in records]
|
|
@@ -204,6 +214,7 @@ async def edge_similarity_search(
|
|
|
204
214
|
group_ids=group_ids,
|
|
205
215
|
limit=limit,
|
|
206
216
|
min_score=min_score,
|
|
217
|
+
_database=DEFAULT_DATABASE,
|
|
207
218
|
)
|
|
208
219
|
|
|
209
220
|
edges = [get_entity_edge_from_record(record) for record in records]
|
|
@@ -219,6 +230,8 @@ async def node_fulltext_search(
|
|
|
219
230
|
) -> list[EntityNode]:
|
|
220
231
|
# BM25 search to get top nodes
|
|
221
232
|
fuzzy_query = fulltext_query(query, group_ids)
|
|
233
|
+
if fuzzy_query == '':
|
|
234
|
+
return []
|
|
222
235
|
|
|
223
236
|
records, _, _ = await driver.execute_query(
|
|
224
237
|
"""
|
|
@@ -237,6 +250,7 @@ async def node_fulltext_search(
|
|
|
237
250
|
query=fuzzy_query,
|
|
238
251
|
group_ids=group_ids,
|
|
239
252
|
limit=limit,
|
|
253
|
+
_database=DEFAULT_DATABASE,
|
|
240
254
|
)
|
|
241
255
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
242
256
|
|
|
@@ -272,6 +286,7 @@ async def node_similarity_search(
|
|
|
272
286
|
group_ids=group_ids,
|
|
273
287
|
limit=limit,
|
|
274
288
|
min_score=min_score,
|
|
289
|
+
_database=DEFAULT_DATABASE,
|
|
275
290
|
)
|
|
276
291
|
nodes = [get_entity_node_from_record(record) for record in records]
|
|
277
292
|
|
|
@@ -286,6 +301,8 @@ async def community_fulltext_search(
|
|
|
286
301
|
) -> list[CommunityNode]:
|
|
287
302
|
# BM25 search to get top communities
|
|
288
303
|
fuzzy_query = fulltext_query(query, group_ids)
|
|
304
|
+
if fuzzy_query == '':
|
|
305
|
+
return []
|
|
289
306
|
|
|
290
307
|
records, _, _ = await driver.execute_query(
|
|
291
308
|
"""
|
|
@@ -304,6 +321,7 @@ async def community_fulltext_search(
|
|
|
304
321
|
query=fuzzy_query,
|
|
305
322
|
group_ids=group_ids,
|
|
306
323
|
limit=limit,
|
|
324
|
+
_database=DEFAULT_DATABASE,
|
|
307
325
|
)
|
|
308
326
|
communities = [get_community_node_from_record(record) for record in records]
|
|
309
327
|
|
|
@@ -339,6 +357,7 @@ async def community_similarity_search(
|
|
|
339
357
|
group_ids=group_ids,
|
|
340
358
|
limit=limit,
|
|
341
359
|
min_score=min_score,
|
|
360
|
+
_database=DEFAULT_DATABASE,
|
|
342
361
|
)
|
|
343
362
|
communities = [get_community_node_from_record(record) for record in records]
|
|
344
363
|
|
|
@@ -530,6 +549,7 @@ async def node_distance_reranker(
|
|
|
530
549
|
query,
|
|
531
550
|
node_uuid=uuid,
|
|
532
551
|
center_uuid=center_node_uuid,
|
|
552
|
+
_database=DEFAULT_DATABASE,
|
|
533
553
|
)
|
|
534
554
|
for uuid in filtered_uuids
|
|
535
555
|
]
|
|
@@ -566,6 +586,7 @@ async def episode_mentions_reranker(driver: AsyncDriver, node_uuids: list[list[s
|
|
|
566
586
|
driver.execute_query(
|
|
567
587
|
query,
|
|
568
588
|
node_uuid=uuid,
|
|
589
|
+
_database=DEFAULT_DATABASE,
|
|
569
590
|
)
|
|
570
591
|
for uuid in sorted_uuids
|
|
571
592
|
]
|
|
@@ -8,8 +8,13 @@ from pydantic import BaseModel
|
|
|
8
8
|
|
|
9
9
|
from graphiti_core.edges import CommunityEdge
|
|
10
10
|
from graphiti_core.embedder import EmbedderClient
|
|
11
|
+
from graphiti_core.helpers import DEFAULT_DATABASE
|
|
11
12
|
from graphiti_core.llm_client import LLMClient
|
|
12
|
-
from graphiti_core.nodes import
|
|
13
|
+
from graphiti_core.nodes import (
|
|
14
|
+
CommunityNode,
|
|
15
|
+
EntityNode,
|
|
16
|
+
get_community_node_from_record,
|
|
17
|
+
)
|
|
13
18
|
from graphiti_core.prompts import prompt_library
|
|
14
19
|
from graphiti_core.utils.maintenance.edge_operations import build_community_edges
|
|
15
20
|
|
|
@@ -29,11 +34,14 @@ async def get_community_clusters(
|
|
|
29
34
|
community_clusters: list[list[EntityNode]] = []
|
|
30
35
|
|
|
31
36
|
if group_ids is None:
|
|
32
|
-
group_id_values, _, _ = await driver.execute_query(
|
|
37
|
+
group_id_values, _, _ = await driver.execute_query(
|
|
38
|
+
"""
|
|
33
39
|
MATCH (n:Entity WHERE n.group_id IS NOT NULL)
|
|
34
40
|
RETURN
|
|
35
41
|
collect(DISTINCT n.group_id) AS group_ids
|
|
36
|
-
"""
|
|
42
|
+
""",
|
|
43
|
+
_database=DEFAULT_DATABASE,
|
|
44
|
+
)
|
|
37
45
|
|
|
38
46
|
group_ids = group_id_values[0]['group_ids']
|
|
39
47
|
|
|
@@ -51,6 +59,7 @@ async def get_community_clusters(
|
|
|
51
59
|
""",
|
|
52
60
|
uuid=node.uuid,
|
|
53
61
|
group_id=group_id,
|
|
62
|
+
_database=DEFAULT_DATABASE,
|
|
54
63
|
)
|
|
55
64
|
|
|
56
65
|
projection[node.uuid] = [
|
|
@@ -209,10 +218,13 @@ async def build_communities(
|
|
|
209
218
|
|
|
210
219
|
|
|
211
220
|
async def remove_communities(driver: AsyncDriver):
|
|
212
|
-
await driver.execute_query(
|
|
221
|
+
await driver.execute_query(
|
|
222
|
+
"""
|
|
213
223
|
MATCH (c:Community)
|
|
214
224
|
DETACH DELETE c
|
|
215
|
-
"""
|
|
225
|
+
""",
|
|
226
|
+
_database=DEFAULT_DATABASE,
|
|
227
|
+
)
|
|
216
228
|
|
|
217
229
|
|
|
218
230
|
async def determine_entity_community(
|
|
@@ -231,6 +243,7 @@ async def determine_entity_community(
|
|
|
231
243
|
c.summary AS summary
|
|
232
244
|
""",
|
|
233
245
|
entity_uuid=entity.uuid,
|
|
246
|
+
_database=DEFAULT_DATABASE,
|
|
234
247
|
)
|
|
235
248
|
|
|
236
249
|
if len(records) > 0:
|
|
@@ -249,6 +262,7 @@ async def determine_entity_community(
|
|
|
249
262
|
c.summary AS summary
|
|
250
263
|
""",
|
|
251
264
|
entity_uuid=entity.uuid,
|
|
265
|
+
_database=DEFAULT_DATABASE,
|
|
252
266
|
)
|
|
253
267
|
|
|
254
268
|
communities: list[CommunityNode] = [
|
|
@@ -21,6 +21,7 @@ from datetime import datetime, timezone
|
|
|
21
21
|
from neo4j import AsyncDriver
|
|
22
22
|
from typing_extensions import LiteralString
|
|
23
23
|
|
|
24
|
+
from graphiti_core.helpers import DEFAULT_DATABASE
|
|
24
25
|
from graphiti_core.nodes import EpisodeType, EpisodicNode
|
|
25
26
|
|
|
26
27
|
EPISODE_WINDOW_LEN = 3
|
|
@@ -30,12 +31,22 @@ logger = logging.getLogger(__name__)
|
|
|
30
31
|
|
|
31
32
|
async def build_indices_and_constraints(driver: AsyncDriver, delete_existing: bool = False):
|
|
32
33
|
if delete_existing:
|
|
33
|
-
records, _, _ = await driver.execute_query(
|
|
34
|
+
records, _, _ = await driver.execute_query(
|
|
35
|
+
"""
|
|
34
36
|
SHOW INDEXES YIELD name
|
|
35
|
-
"""
|
|
37
|
+
""",
|
|
38
|
+
_database=DEFAULT_DATABASE,
|
|
39
|
+
)
|
|
36
40
|
index_names = [record['name'] for record in records]
|
|
37
41
|
await asyncio.gather(
|
|
38
|
-
*[
|
|
42
|
+
*[
|
|
43
|
+
driver.execute_query(
|
|
44
|
+
"""DROP INDEX $name""",
|
|
45
|
+
name=name,
|
|
46
|
+
_database=DEFAULT_DATABASE,
|
|
47
|
+
)
|
|
48
|
+
for name in index_names
|
|
49
|
+
]
|
|
39
50
|
)
|
|
40
51
|
|
|
41
52
|
range_indices: list[LiteralString] = [
|
|
@@ -71,7 +82,15 @@ async def build_indices_and_constraints(driver: AsyncDriver, delete_existing: bo
|
|
|
71
82
|
|
|
72
83
|
index_queries: list[LiteralString] = range_indices + fulltext_indices
|
|
73
84
|
|
|
74
|
-
await asyncio.gather(
|
|
85
|
+
await asyncio.gather(
|
|
86
|
+
*[
|
|
87
|
+
driver.execute_query(
|
|
88
|
+
query,
|
|
89
|
+
_database=DEFAULT_DATABASE,
|
|
90
|
+
)
|
|
91
|
+
for query in index_queries
|
|
92
|
+
]
|
|
93
|
+
)
|
|
75
94
|
|
|
76
95
|
|
|
77
96
|
async def clear_data(driver: AsyncDriver):
|
|
@@ -121,6 +140,7 @@ async def retrieve_episodes(
|
|
|
121
140
|
reference_time=reference_time,
|
|
122
141
|
num_episodes=last_n,
|
|
123
142
|
group_ids=group_ids,
|
|
143
|
+
_database=DEFAULT_DATABASE,
|
|
124
144
|
)
|
|
125
145
|
episodes = [
|
|
126
146
|
EpisodicNode(
|
|
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.12/graphiti_core/search → graphiti_core-0.3.14/graphiti_core/models}/__init__.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
|
{graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/edge_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/node_operations.py
RENAMED
|
File without changes
|
{graphiti_core-0.3.12 → graphiti_core-0.3.14}/graphiti_core/utils/maintenance/temporal_operations.py
RENAMED
|
File without changes
|