graphiti-core 0.12.0rc1__py3-none-any.whl → 0.12.0rc2__py3-none-any.whl

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.

@@ -21,6 +21,8 @@ from typing import Any
21
21
  from pydantic import BaseModel, Field
22
22
  from typing_extensions import LiteralString
23
23
 
24
+ from graphiti_core.helpers import lucene_sanitize
25
+
24
26
 
25
27
  class ComparisonOperator(Enum):
26
28
  equals = '='
@@ -42,6 +44,9 @@ class SearchFilters(BaseModel):
42
44
  node_labels: list[str] | None = Field(
43
45
  default=None, description='List of node labels to filter on'
44
46
  )
47
+ edge_types: list[str] | None = Field(
48
+ default=None, description='List of edge types to filter on'
49
+ )
45
50
  valid_at: list[list[DateFilter]] | None = Field(default=None)
46
51
  invalid_at: list[list[DateFilter]] | None = Field(default=None)
47
52
  created_at: list[list[DateFilter]] | None = Field(default=None)
@@ -55,7 +60,7 @@ def node_search_filter_query_constructor(
55
60
  filter_params: dict[str, Any] = {}
56
61
 
57
62
  if filters.node_labels is not None:
58
- node_labels = '|'.join(filters.node_labels)
63
+ node_labels = '|'.join(list(map(lucene_sanitize, filters.node_labels)))
59
64
  node_label_filter = ' AND n:' + node_labels
60
65
  filter_query += node_label_filter
61
66
 
@@ -68,8 +73,19 @@ def edge_search_filter_query_constructor(
68
73
  filter_query: LiteralString = ''
69
74
  filter_params: dict[str, Any] = {}
70
75
 
76
+ if filters.edge_types is not None:
77
+ edge_types = filters.edge_types
78
+ edge_types_filter = '\nAND r.name in $edge_types'
79
+ filter_query += edge_types_filter
80
+ filter_params['edge_types'] = edge_types
81
+
82
+ if filters.node_labels is not None:
83
+ node_labels = '|'.join(list(map(lucene_sanitize, filters.node_labels)))
84
+ node_label_filter = '\nAND n:' + node_labels + ' AND m:' + node_labels
85
+ filter_query += node_label_filter
86
+
71
87
  if filters.valid_at is not None:
72
- valid_at_filter = ' AND ('
88
+ valid_at_filter = '\nAND ('
73
89
  for i, or_list in enumerate(filters.valid_at):
74
90
  for j, date_filter in enumerate(or_list):
75
91
  filter_params['valid_at_' + str(j)] = date_filter.date
@@ -159,7 +159,7 @@ async def edge_fulltext_search(
159
159
  """
160
160
  CALL db.index.fulltext.queryRelationships("edge_name_and_fact", $query, {limit: $limit})
161
161
  YIELD relationship AS rel, score
162
- MATCH (:Entity)-[r:RELATES_TO]->(:Entity)
162
+ MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
163
163
  WHERE r.group_id IN $group_ids"""
164
164
  + filter_query
165
165
  + """\nWITH r, score, startNode(r) AS n, endNode(r) AS m
@@ -211,9 +211,9 @@ async def edge_similarity_search(
211
211
  filter_query, filter_params = edge_search_filter_query_constructor(search_filter)
212
212
  query_params.update(filter_params)
213
213
 
214
- group_filter_query: LiteralString = ''
214
+ group_filter_query: LiteralString = 'WHERE r.group_id IS NOT NULL'
215
215
  if group_ids is not None:
216
- group_filter_query += 'WHERE r.group_id IN $group_ids'
216
+ group_filter_query += '\nAND r.group_id IN $group_ids'
217
217
  query_params['group_ids'] = group_ids
218
218
  query_params['source_node_uuid'] = source_node_uuid
219
219
  query_params['target_node_uuid'] = target_node_uuid
@@ -227,8 +227,8 @@ async def edge_similarity_search(
227
227
  query: LiteralString = (
228
228
  RUNTIME_QUERY
229
229
  + """
230
- MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
231
- """
230
+ MATCH (n:Entity)-[r:RELATES_TO]->(m:Entity)
231
+ """
232
232
  + group_filter_query
233
233
  + filter_query
234
234
  + """\nWITH DISTINCT r, vector.similarity.cosine(r.fact_embedding, $search_vector) AS score
@@ -287,7 +287,7 @@ async def edge_bfs_search(
287
287
  UNWIND $bfs_origin_node_uuids AS origin_uuid
288
288
  MATCH path = (origin:Entity|Episodic {uuid: origin_uuid})-[:RELATES_TO|MENTIONS]->{1,3}(n:Entity)
289
289
  UNWIND relationships(path) AS rel
290
- MATCH ()-[r:RELATES_TO]-()
290
+ MATCH (n:Entity)-[r:RELATES_TO]-(m:Entity)
291
291
  WHERE r.uuid = rel.uuid
292
292
  """
293
293
  + filter_query
@@ -340,10 +340,10 @@ async def node_fulltext_search(
340
340
 
341
341
  query = (
342
342
  """
343
- CALL db.index.fulltext.queryNodes("node_name_and_summary", $query, {limit: $limit})
344
- YIELD node AS n, score
345
- WHERE n:Entity
346
- """
343
+ CALL db.index.fulltext.queryNodes("node_name_and_summary", $query, {limit: $limit})
344
+ YIELD node AS n, score
345
+ WHERE n:Entity
346
+ """
347
347
  + filter_query
348
348
  + ENTITY_NODE_RETURN
349
349
  + """
@@ -376,9 +376,9 @@ async def node_similarity_search(
376
376
  # vector similarity search over entity names
377
377
  query_params: dict[str, Any] = {}
378
378
 
379
- group_filter_query: LiteralString = ''
379
+ group_filter_query: LiteralString = 'WHERE n.group_id IS NOT NULL'
380
380
  if group_ids is not None:
381
- group_filter_query += 'WHERE n.group_id IN $group_ids'
381
+ group_filter_query += ' AND n.group_id IN $group_ids'
382
382
  query_params['group_ids'] = group_ids
383
383
 
384
384
  filter_query, filter_params = node_search_filter_query_constructor(search_filter)
@@ -160,6 +160,14 @@ async def extract_edges(
160
160
  invalid_at = edge_data.get('invalid_at', None)
161
161
  valid_at_datetime = None
162
162
  invalid_at_datetime = None
163
+ source_node_uuid = node_uuids_by_name_map.get(edge_data.get('source_entity_name', ''), '')
164
+ target_node_uuid = node_uuids_by_name_map.get(edge_data.get('target_entity_name', ''), '')
165
+
166
+ if source_node_uuid == '' or target_node_uuid == '':
167
+ logger.warning(
168
+ f'WARNING: source or target node not filled {edge_data.get("edge_name")}. source_node_uuid: {source_node_uuid} and target_node_uuid: {target_node_uuid} '
169
+ )
170
+ continue
163
171
 
164
172
  if valid_at:
165
173
  try:
@@ -177,12 +185,8 @@ async def extract_edges(
177
185
  except ValueError as e:
178
186
  logger.warning(f'WARNING: Error parsing invalid_at date: {e}. Input: {invalid_at}')
179
187
  edge = EntityEdge(
180
- source_node_uuid=node_uuids_by_name_map.get(
181
- edge_data.get('source_entity_name', ''), ''
182
- ),
183
- target_node_uuid=node_uuids_by_name_map.get(
184
- edge_data.get('target_entity_name', ''), ''
185
- ),
188
+ source_node_uuid=source_node_uuid,
189
+ target_node_uuid=target_node_uuid,
186
190
  name=edge_data.get('relation_type', ''),
187
191
  group_id=group_id,
188
192
  fact=edge_data.get('fact', ''),
@@ -276,8 +280,8 @@ async def resolve_extracted_edges(
276
280
  # Determine which edge types are relevant for each edge
277
281
  edge_types_lst: list[dict[str, BaseModel]] = []
278
282
  for extracted_edge in extracted_edges:
279
- source_node_labels = uuid_entity_map[extracted_edge.source_node_uuid].labels
280
- target_node_labels = uuid_entity_map[extracted_edge.target_node_uuid].labels
283
+ source_node_labels = uuid_entity_map[extracted_edge.source_node_uuid].labels + ['Entity']
284
+ target_node_labels = uuid_entity_map[extracted_edge.target_node_uuid].labels + ['Entity']
281
285
  label_tuples = [
282
286
  (source_label, target_label)
283
287
  for source_label in source_node_labels
@@ -439,7 +443,7 @@ async def resolve_extracted_edge(
439
443
  resolved_edge.name = fact_type
440
444
 
441
445
  edge_attributes_context = {
442
- 'message': episode.content,
446
+ 'episode_content': episode.content,
443
447
  'reference_time': episode.valid_at,
444
448
  'fact': resolved_edge.fact,
445
449
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: graphiti-core
3
- Version: 0.12.0rc1
3
+ Version: 0.12.0rc2
4
4
  Summary: A temporal graph building library
5
5
  License: Apache-2.0
6
6
  Author: Paul Paliychuk
@@ -46,21 +46,21 @@ graphiti_core/search/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
46
46
  graphiti_core/search/search.py,sha256=XCEYz4-I341eWiZ-czeFlH5hdbHTTLymhHiD153p6DQ,15122
47
47
  graphiti_core/search/search_config.py,sha256=VvKg6AB_RPhoe56DBBXHRBXHThAVJ_OLFCyq_yKof-A,3765
48
48
  graphiti_core/search/search_config_recipes.py,sha256=4GquRphHhJlpXQhAZOySYnCzBWYoTwxlJj44eTOavZQ,7443
49
- graphiti_core/search/search_filters.py,sha256=JkP7NbM4Dor27dne5vAuxbJic12dIJDtWJxNqmVuRec,5884
49
+ graphiti_core/search/search_filters.py,sha256=AT074LfIw3nc-jKtDbHCopkUIk5eY1_HRl6EoHSQsUc,6551
50
50
  graphiti_core/search/search_helpers.py,sha256=G5Ceaq5Pfgx0Weelqgeylp_pUHwiBnINaUYsDbURJbE,2636
51
- graphiti_core/search/search_utils.py,sha256=Q36whL7VTlVRuFkktqjbIlLqVYf7myE6iHo4i0bW73E,34634
51
+ graphiti_core/search/search_utils.py,sha256=AimBkRgvSFHqAkt1vraTVj_bVAp3JKrR6JUMpoZa8RI,34469
52
52
  graphiti_core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  graphiti_core/utils/bulk_utils.py,sha256=WFCfo_OrFD2bpm13Vkex4A1YLVHX4pjCm5acZ1CwzEI,15848
54
54
  graphiti_core/utils/datetime_utils.py,sha256=Ti-2tnrDFRzBsbfblzsHybsM3jaDLP4-VT2t0VhpIzU,1357
55
55
  graphiti_core/utils/maintenance/__init__.py,sha256=vW4H1KyapTl-OOz578uZABYcpND4wPx3Vt6aAPaXh78,301
56
56
  graphiti_core/utils/maintenance/community_operations.py,sha256=TF-4eHuvMe_jMqvWg3swxK80zLLtOR0t1pmUUQlNulM,10067
57
- graphiti_core/utils/maintenance/edge_operations.py,sha256=KeHcNJ2YXApC-cuoR1zBdXPtinOdv0DfvQcBicVnuBQ,18865
57
+ graphiti_core/utils/maintenance/edge_operations.py,sha256=9_vC3piLUlGM-C30Z4DsN6UWQoxbabsSlJYD7z1zsr4,19222
58
58
  graphiti_core/utils/maintenance/graph_data_operations.py,sha256=BIJKc8tbvU4IjWxLgeotw57b1eE3Iw8YtV74j6eo4RQ,7493
59
59
  graphiti_core/utils/maintenance/node_operations.py,sha256=xuXKY0aoe_Idl9Edtb8FxSqoCa45M043nCMraJuAcW8,16606
60
60
  graphiti_core/utils/maintenance/temporal_operations.py,sha256=mJkw9xLB4W2BsLfC5POr0r-PHWL9SIfNj_l_xu0B5ug,3410
61
61
  graphiti_core/utils/maintenance/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  graphiti_core/utils/ontology_utils/entity_types_utils.py,sha256=QJX5cG0GSSNF_Mm_yrldr69wjVAbN_MxLhOSznz85Hk,1279
63
- graphiti_core-0.12.0rc1.dist-info/LICENSE,sha256=KCUwCyDXuVEgmDWkozHyniRyWjnWUWjkuDHfU6o3JlA,11325
64
- graphiti_core-0.12.0rc1.dist-info/METADATA,sha256=NWn1DI3wq2YnAPzTi7chWv1c22UhaEKaSzmt_ky9B9s,15301
65
- graphiti_core-0.12.0rc1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
66
- graphiti_core-0.12.0rc1.dist-info/RECORD,,
63
+ graphiti_core-0.12.0rc2.dist-info/LICENSE,sha256=KCUwCyDXuVEgmDWkozHyniRyWjnWUWjkuDHfU6o3JlA,11325
64
+ graphiti_core-0.12.0rc2.dist-info/METADATA,sha256=-fYdpjbrMX_KEX-KjyoGONa042ydQ8mlH0henpu9Z9U,15301
65
+ graphiti_core-0.12.0rc2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
66
+ graphiti_core-0.12.0rc2.dist-info/RECORD,,