graphiti-core 0.17.4__py3-none-any.whl → 0.25.3__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.
Files changed (59) hide show
  1. graphiti_core/cross_encoder/gemini_reranker_client.py +1 -1
  2. graphiti_core/cross_encoder/openai_reranker_client.py +1 -1
  3. graphiti_core/decorators.py +110 -0
  4. graphiti_core/driver/driver.py +62 -2
  5. graphiti_core/driver/falkordb_driver.py +215 -23
  6. graphiti_core/driver/graph_operations/graph_operations.py +191 -0
  7. graphiti_core/driver/kuzu_driver.py +182 -0
  8. graphiti_core/driver/neo4j_driver.py +70 -8
  9. graphiti_core/driver/neptune_driver.py +305 -0
  10. graphiti_core/driver/search_interface/search_interface.py +89 -0
  11. graphiti_core/edges.py +264 -132
  12. graphiti_core/embedder/azure_openai.py +10 -3
  13. graphiti_core/embedder/client.py +2 -1
  14. graphiti_core/graph_queries.py +114 -101
  15. graphiti_core/graphiti.py +635 -260
  16. graphiti_core/graphiti_types.py +2 -0
  17. graphiti_core/helpers.py +37 -15
  18. graphiti_core/llm_client/anthropic_client.py +142 -52
  19. graphiti_core/llm_client/azure_openai_client.py +57 -19
  20. graphiti_core/llm_client/client.py +83 -21
  21. graphiti_core/llm_client/config.py +1 -1
  22. graphiti_core/llm_client/gemini_client.py +75 -57
  23. graphiti_core/llm_client/openai_base_client.py +92 -48
  24. graphiti_core/llm_client/openai_client.py +39 -9
  25. graphiti_core/llm_client/openai_generic_client.py +91 -56
  26. graphiti_core/models/edges/edge_db_queries.py +259 -35
  27. graphiti_core/models/nodes/node_db_queries.py +311 -32
  28. graphiti_core/nodes.py +388 -164
  29. graphiti_core/prompts/dedupe_edges.py +42 -31
  30. graphiti_core/prompts/dedupe_nodes.py +56 -39
  31. graphiti_core/prompts/eval.py +4 -4
  32. graphiti_core/prompts/extract_edges.py +24 -15
  33. graphiti_core/prompts/extract_nodes.py +76 -35
  34. graphiti_core/prompts/prompt_helpers.py +39 -0
  35. graphiti_core/prompts/snippets.py +29 -0
  36. graphiti_core/prompts/summarize_nodes.py +23 -25
  37. graphiti_core/search/search.py +154 -74
  38. graphiti_core/search/search_config.py +39 -4
  39. graphiti_core/search/search_filters.py +110 -31
  40. graphiti_core/search/search_helpers.py +5 -6
  41. graphiti_core/search/search_utils.py +1360 -473
  42. graphiti_core/tracer.py +193 -0
  43. graphiti_core/utils/bulk_utils.py +216 -90
  44. graphiti_core/utils/content_chunking.py +702 -0
  45. graphiti_core/utils/datetime_utils.py +13 -0
  46. graphiti_core/utils/maintenance/community_operations.py +62 -38
  47. graphiti_core/utils/maintenance/dedup_helpers.py +262 -0
  48. graphiti_core/utils/maintenance/edge_operations.py +306 -156
  49. graphiti_core/utils/maintenance/graph_data_operations.py +44 -74
  50. graphiti_core/utils/maintenance/node_operations.py +466 -206
  51. graphiti_core/utils/maintenance/temporal_operations.py +11 -3
  52. graphiti_core/utils/ontology_utils/entity_types_utils.py +1 -1
  53. graphiti_core/utils/text_utils.py +53 -0
  54. {graphiti_core-0.17.4.dist-info → graphiti_core-0.25.3.dist-info}/METADATA +221 -87
  55. graphiti_core-0.25.3.dist-info/RECORD +87 -0
  56. {graphiti_core-0.17.4.dist-info → graphiti_core-0.25.3.dist-info}/WHEEL +1 -1
  57. graphiti_core-0.17.4.dist-info/RECORD +0 -77
  58. /graphiti_core/{utils/maintenance/utils.py → migrations/__init__.py} +0 -0
  59. {graphiti_core-0.17.4.dist-info → graphiti_core-0.25.3.dist-info}/licenses/LICENSE +0 -0
@@ -15,53 +15,22 @@ limitations under the License.
15
15
  """
16
16
 
17
17
  import logging
18
- from datetime import datetime, timezone
18
+ from datetime import datetime
19
19
 
20
20
  from typing_extensions import LiteralString
21
21
 
22
- from graphiti_core.driver.driver import GraphDriver
23
- from graphiti_core.graph_queries import get_fulltext_indices, get_range_indices
24
- from graphiti_core.helpers import parse_db_date, semaphore_gather
25
- from graphiti_core.nodes import EpisodeType, EpisodicNode
22
+ from graphiti_core.driver.driver import GraphDriver, GraphProvider
23
+ from graphiti_core.models.nodes.node_db_queries import (
24
+ EPISODIC_NODE_RETURN,
25
+ EPISODIC_NODE_RETURN_NEPTUNE,
26
+ )
27
+ from graphiti_core.nodes import EpisodeType, EpisodicNode, get_episodic_node_from_record
26
28
 
27
29
  EPISODE_WINDOW_LEN = 3
28
30
 
29
31
  logger = logging.getLogger(__name__)
30
32
 
31
33
 
32
- async def build_indices_and_constraints(driver: GraphDriver, delete_existing: bool = False):
33
- if delete_existing:
34
- records, _, _ = await driver.execute_query(
35
- """
36
- SHOW INDEXES YIELD name
37
- """,
38
- )
39
- index_names = [record['name'] for record in records]
40
- await semaphore_gather(
41
- *[
42
- driver.execute_query(
43
- """DROP INDEX $name""",
44
- name=name,
45
- )
46
- for name in index_names
47
- ]
48
- )
49
- range_indices: list[LiteralString] = get_range_indices(driver.provider)
50
-
51
- fulltext_indices: list[LiteralString] = get_fulltext_indices(driver.provider)
52
-
53
- index_queries: list[LiteralString] = range_indices + fulltext_indices
54
-
55
- await semaphore_gather(
56
- *[
57
- driver.execute_query(
58
- query,
59
- )
60
- for query in index_queries
61
- ]
62
- )
63
-
64
-
65
34
  async def clear_data(driver: GraphDriver, group_ids: list[str] | None = None):
66
35
  async with driver.session() as session:
67
36
 
@@ -69,10 +38,19 @@ async def clear_data(driver: GraphDriver, group_ids: list[str] | None = None):
69
38
  await tx.run('MATCH (n) DETACH DELETE n')
70
39
 
71
40
  async def delete_group_ids(tx):
72
- await tx.run(
73
- 'MATCH (n:Entity|Episodic|Community) WHERE n.group_id IN $group_ids DETACH DELETE n',
74
- group_ids=group_ids,
75
- )
41
+ labels = ['Entity', 'Episodic', 'Community']
42
+ if driver.provider == GraphProvider.KUZU:
43
+ labels.append('RelatesToNode_')
44
+
45
+ for label in labels:
46
+ await tx.run(
47
+ f"""
48
+ MATCH (n:{label})
49
+ WHERE n.group_id IN $group_ids
50
+ DETACH DELETE n
51
+ """,
52
+ group_ids=group_ids,
53
+ )
76
54
 
77
55
  if group_ids is None:
78
56
  await session.execute_write(delete_all)
@@ -101,26 +79,32 @@ async def retrieve_episodes(
101
79
  Returns:
102
80
  list[EpisodicNode]: A list of EpisodicNode objects representing the retrieved episodes.
103
81
  """
104
- group_id_filter: LiteralString = (
105
- '\nAND e.group_id IN $group_ids' if group_ids and len(group_ids) > 0 else ''
106
- )
107
- source_filter: LiteralString = '\nAND e.source = $source' if source is not None else ''
82
+
83
+ query_params: dict = {}
84
+ query_filter = ''
85
+ if group_ids and len(group_ids) > 0:
86
+ query_filter += '\nAND e.group_id IN $group_ids'
87
+ query_params['group_ids'] = group_ids
88
+
89
+ if source is not None:
90
+ query_filter += '\nAND e.source = $source'
91
+ query_params['source'] = source.name
108
92
 
109
93
  query: LiteralString = (
110
94
  """
111
- MATCH (e:Episodic) WHERE e.valid_at <= $reference_time
112
- """
113
- + group_id_filter
114
- + source_filter
95
+ MATCH (e:Episodic)
96
+ WHERE e.valid_at <= $reference_time
97
+ """
98
+ + query_filter
99
+ + """
100
+ RETURN
101
+ """
102
+ + (
103
+ EPISODIC_NODE_RETURN_NEPTUNE
104
+ if driver.provider == GraphProvider.NEPTUNE
105
+ else EPISODIC_NODE_RETURN
106
+ )
115
107
  + """
116
- RETURN e.content AS content,
117
- e.created_at AS created_at,
118
- e.valid_at AS valid_at,
119
- e.uuid AS uuid,
120
- e.group_id AS group_id,
121
- e.name AS name,
122
- e.source_description AS source_description,
123
- e.source AS source
124
108
  ORDER BY e.valid_at DESC
125
109
  LIMIT $num_episodes
126
110
  """
@@ -128,23 +112,9 @@ async def retrieve_episodes(
128
112
  result, _, _ = await driver.execute_query(
129
113
  query,
130
114
  reference_time=reference_time,
131
- source=source.name if source is not None else None,
132
115
  num_episodes=last_n,
133
- group_ids=group_ids,
116
+ **query_params,
134
117
  )
135
118
 
136
- episodes = [
137
- EpisodicNode(
138
- content=record['content'],
139
- created_at=parse_db_date(record['created_at'])
140
- or datetime.min.replace(tzinfo=timezone.utc),
141
- valid_at=parse_db_date(record['valid_at']) or datetime.min.replace(tzinfo=timezone.utc),
142
- uuid=record['uuid'],
143
- group_id=record['group_id'],
144
- source=EpisodeType.from_str(record['source']),
145
- name=record['name'],
146
- source_description=record['source_description'],
147
- )
148
- for record in result
149
- ]
119
+ episodes = [get_episodic_node_from_record(record) for record in result]
150
120
  return list(reversed(episodes)) # Return in chronological order